show HDD warnings based on sectors
This commit is contained in:
+128
-1
@@ -23,6 +23,9 @@ void SMART::readSMARTData(Drive *drive)
|
||||
uint32_t powerOnHours = 0U;
|
||||
uint32_t powerCycles = 0U;
|
||||
uint32_t temperature = 0U;
|
||||
uint32_t reallocatedSectors = 0U;
|
||||
uint32_t pendingSectors = 0U;
|
||||
uint32_t uncorrectableSectors = 0U;
|
||||
|
||||
modelFamily.clear();
|
||||
modelName.clear();
|
||||
@@ -57,6 +60,9 @@ void SMART::readSMARTData(Drive *drive)
|
||||
SMART::parsePowerOnHours(sLine, powerOnHours);
|
||||
SMART::parsePowerCycles(sLine, powerCycles);
|
||||
SMART::parseTemperature(sLine, temperature);
|
||||
SMART::parseReallocatedSectors(sLine, reallocatedSectors);
|
||||
SMART::parsePendingSectors(sLine, pendingSectors);
|
||||
SMART::parseUncorrectableSectors(sLine, uncorrectableSectors);
|
||||
}
|
||||
|
||||
free(cLine);
|
||||
@@ -70,7 +76,7 @@ void SMART::readSMARTData(Drive *drive)
|
||||
}
|
||||
}
|
||||
|
||||
drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycles, temperature); // write data in drive
|
||||
drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycles, temperature, reallocatedSectors, pendingSectors, uncorrectableSectors); // write data in drive
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,3 +315,124 @@ bool SMART::parseTemperature(string sLine, uint32_t &temperature)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief parse Reallocated Sectors Count (SMART ID 0x05)
|
||||
* \param string output line of smartctl
|
||||
* \param uint32_t parsed reallocated sectors count
|
||||
* \return bool if parsing was possible
|
||||
*/
|
||||
bool SMART::parseReallocatedSectors(string sLine, uint32_t &reallocatedSectors)
|
||||
{
|
||||
string search("\"id\": 5,");
|
||||
size_t found = sLine.find(search);
|
||||
if (found != string::npos)
|
||||
{
|
||||
// Found attribute ID 5 (Reallocated_Sector_Ct)
|
||||
// Now we need to find the raw value in the next lines
|
||||
// smartctl JSON format: "raw": { "value": <number>, ... }
|
||||
return true; // Mark that we found the attribute
|
||||
}
|
||||
|
||||
// Look for the raw value if we're in the right attribute
|
||||
search = "\"value\":";
|
||||
found = sLine.find(search);
|
||||
if (found != string::npos && sLine.find("\"raw\":") != string::npos)
|
||||
{
|
||||
// Extract value after "value":
|
||||
sLine.erase(0U, sLine.find("\"value\":") + 8U);
|
||||
// Remove trailing characters
|
||||
size_t comma = sLine.find(",");
|
||||
if (comma != string::npos)
|
||||
{
|
||||
sLine = sLine.substr(0, comma);
|
||||
}
|
||||
// Remove whitespace
|
||||
sLine.erase(remove(sLine.begin(), sLine.end(), ' '), sLine.end());
|
||||
|
||||
if (!sLine.empty() && sLine.find_first_not_of("0123456789") == string::npos)
|
||||
{
|
||||
reallocatedSectors = stoul(sLine);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief parse Current Pending Sector Count (SMART ID 0xC5)
|
||||
* \param string output line of smartctl
|
||||
* \param uint32_t parsed pending sectors count
|
||||
* \return bool if parsing was possible
|
||||
*/
|
||||
bool SMART::parsePendingSectors(string sLine, uint32_t &pendingSectors)
|
||||
{
|
||||
string search("\"id\": 197,"); // 0xC5 = 197 decimal
|
||||
size_t found = sLine.find(search);
|
||||
if (found != string::npos)
|
||||
{
|
||||
return true; // Mark that we found the attribute
|
||||
}
|
||||
|
||||
// Look for the raw value
|
||||
search = "\"value\":";
|
||||
found = sLine.find(search);
|
||||
if (found != string::npos && sLine.find("\"raw\":") != string::npos)
|
||||
{
|
||||
sLine.erase(0U, sLine.find("\"value\":") + 8U);
|
||||
size_t comma = sLine.find(",");
|
||||
if (comma != string::npos)
|
||||
{
|
||||
sLine = sLine.substr(0, comma);
|
||||
}
|
||||
sLine.erase(remove(sLine.begin(), sLine.end(), ' '), sLine.end());
|
||||
|
||||
if (!sLine.empty() && sLine.find_first_not_of("0123456789") == string::npos)
|
||||
{
|
||||
pendingSectors = stoul(sLine);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief parse Offline Uncorrectable Sectors (SMART ID 0xC6)
|
||||
* \param string output line of smartctl
|
||||
* \param uint32_t parsed uncorrectable sectors count
|
||||
* \return bool if parsing was possible
|
||||
*/
|
||||
bool SMART::parseUncorrectableSectors(string sLine, uint32_t &uncorrectableSectors)
|
||||
{
|
||||
string search("\"id\": 198,"); // 0xC6 = 198 decimal
|
||||
size_t found = sLine.find(search);
|
||||
if (found != string::npos)
|
||||
{
|
||||
return true; // Mark that we found the attribute
|
||||
}
|
||||
|
||||
// Look for the raw value
|
||||
search = "\"value\":";
|
||||
found = sLine.find(search);
|
||||
if (found != string::npos && sLine.find("\"raw\":") != string::npos)
|
||||
{
|
||||
sLine.erase(0U, sLine.find("\"value\":") + 8U);
|
||||
size_t comma = sLine.find(",");
|
||||
if (comma != string::npos)
|
||||
{
|
||||
sLine = sLine.substr(0, comma);
|
||||
}
|
||||
sLine.erase(remove(sLine.begin(), sLine.end(), ' '), sLine.end());
|
||||
|
||||
if (!sLine.empty() && sLine.find_first_not_of("0123456789") == string::npos)
|
||||
{
|
||||
uncorrectableSectors = stoul(sLine);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user