13 Commits

12 changed files with 115 additions and 46 deletions

View File

@ -24,7 +24,7 @@ Instructions how to create a standalone machine that boots directly to reHDD. Th
* Upload reHDD log every 12h if wanted * Upload reHDD log every 12h if wanted
### Software requirements ### Software requirements
* `apt-get install hwinfo smartmontools curl` * `apt-get install hwinfo smartmontools curl htop sudo`
### Installation ### Installation

View File

@ -37,18 +37,23 @@ public:
private: private:
string sPath; string sPath;
string sModelFamily;
string sModelName;
string sSerial;
uint64_t u64Capacity = 0U; //in byte
uint32_t u32ErrorCount = 0U;
uint32_t u32PowerOnHours = 0U; //in hours
uint32_t u32PowerCycles = 0U;
time_t u32Timestamp = 0U; //unix timestamp for detecting a frozen drive time_t u32Timestamp = 0U; //unix timestamp for detecting a frozen drive
double d32TaskPercentage = 0U; //in percent for Shred (1 to 100) double d32TaskPercentage = 0U; //in percent for Shred (1 to 100)
time_t u32TimestampTaskStart = 0U; //unix timestamp for duration of an action time_t u32TimestampTaskStart = 0U; //unix timestamp for duration of an action
time_t u32TaskDuration = 0U; //time needed to complete the task time_t u32TaskDuration = 0U; //time needed to complete the task
struct
{
string sModelFamily;
string sModelName;
string sSerial;
uint64_t u64Capacity = 0U; //in byte
uint32_t u32ErrorCount = 0U;
uint32_t u32PowerOnHours = 0U; //in hours
uint32_t u32PowerCycles = 0U;
uint32_t u32Temperature = 0U; //in Fahrenheit, just kidding: degree Celsius
} sSmartData;
private: private:
void setTimestamp(); void setTimestamp();
@ -68,6 +73,7 @@ public:
uint32_t getErrorCount(void); uint32_t getErrorCount(void);
uint32_t getPowerOnHours(void); //in hours uint32_t getPowerOnHours(void); //in hours
uint32_t getPowerCycles(void); uint32_t getPowerCycles(void);
uint32_t getTemperature(void); //in Fahrenheit, just kidding: degree Celsius
void checkFrozenDrive(void); void checkFrozenDrive(void);
void setDriveSMARTData( string modelFamily, void setDriveSMARTData( string modelFamily,
@ -76,12 +82,14 @@ public:
uint64_t capacity, uint64_t capacity,
uint32_t errorCount, uint32_t errorCount,
uint32_t powerOnHours, uint32_t powerOnHours,
uint32_t powerCycles); uint32_t powerCycles,
uint32_t temperature);
string sCapacityToText(); string sCapacityToText();
string sErrorCountToText(); string sErrorCountToText();
string sPowerOnHoursToText(); string sPowerOnHoursToText();
string sPowerCyclesToText(); string sPowerCyclesToText();
string sTemperatureToText();
void setTaskPercentage(double d32TaskPercentage); void setTaskPercentage(double d32TaskPercentage);
double getTaskPercentage(void); double getTaskPercentage(void);

View File

@ -8,13 +8,14 @@
#ifndef REHDD_H_ #ifndef REHDD_H_
#define REHDD_H_ #define REHDD_H_
#define REHDD_VERSION "bV0.2.2" #define REHDD_VERSION "bV0.3.0"
// Drive handling Settings // Drive handling Settings
#define WORSE_HOURS 19200 //mark drive if at this limit or beyond #define WORSE_HOURS 19200 //mark drive if at this limit or beyond
#define WORSE_POWERUP 10000 //mark drive if at this limit or beyond #define WORSE_POWERUP 10000 //mark drive if at this limit or beyond
#define WORSE_TEMPERATURE 55 //mark drive if at this limit or beyond
#define SHRED_ITERATIONS 3U #define SHRED_ITERATIONS 3U
#define FROZEN_TIMEOUT 10 //After this timeout (minutes) the drive will be marked as frozen #define FROZEN_TIMEOUT 20 //After this timeout (minutes) the drive will be marked as frozen, if no progress
#define METRIC_THRESHOLD 3L*1000L*1000L*1000L //calc shred speed with this minimum of time delta #define METRIC_THRESHOLD 3L*1000L*1000L*1000L //calc shred speed with this minimum of time delta
// Logger Settings // Logger Settings

View File

@ -23,6 +23,7 @@
//#define DEMO_DRIVE_SIZE 1024*1024*256L // 256MB //#define DEMO_DRIVE_SIZE 1024*1024*256L // 256MB
//#define DEMO_DRIVE_SIZE 1024*1024*1024L // 1GB //#define DEMO_DRIVE_SIZE 1024*1024*1024L // 1GB
//#define DEMO_DRIVE_SIZE 5*1024*1024*1024L // 5GB
//#define DEMO_DRIVE_SIZE 1024*1024*1024*10L // 10GB //#define DEMO_DRIVE_SIZE 1024*1024*1024*10L // 10GB
typedef int fileDescriptor; typedef int fileDescriptor;

View File

@ -27,6 +27,7 @@ private:
static void parseErrorCount(string sLine); static void parseErrorCount(string sLine);
static void parsePowerOnHours(string sLine); static void parsePowerOnHours(string sLine);
static void parsePowerCycle(string sLine); static void parsePowerCycle(string sLine);
static void parseTemperature(string sLine);
static string modelFamily; static string modelFamily;
static string modelName; static string modelName;
@ -35,6 +36,7 @@ private:
static uint32_t errorCount; static uint32_t errorCount;
static uint32_t powerOnHours; static uint32_t powerOnHours;
static uint32_t powerCycle; static uint32_t powerCycle;
static uint32_t temperature;
}; };
#endif // SMART_H_ #endif // SMART_H_

View File

@ -56,12 +56,12 @@ private:
static WINDOW *createOverViewWindow( int iXSize, int iYSize); static WINDOW *createOverViewWindow( int iXSize, int iYSize);
static WINDOW *createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive drive); static WINDOW *createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive drive);
static WINDOW *overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart); static WINDOW *overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart);
static WINDOW *createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, string sTime, string sSpeed, bool bSelected); static WINDOW *createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, int iListIndex, string sModelFamily, string sSerial, string sCapacity, string sState, string sTime, string sSpeed, string sTemp, bool bSelected);
static WINDOW *createSystemStats(int iXSize, int iYSize, int iXStart, int iYStart); static WINDOW *createSystemStats(int iXSize, int iYSize, int iXStart, int iYStart);
static WINDOW *createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate); static WINDOW *createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate);
static WINDOW *createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string selectedTask, string optionA, string optionB); static WINDOW *createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string selectedTask, string optionA, string optionB);
static WINDOW* createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, string sProgress); static WINDOW* createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, string sProgress);
static WINDOW* createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, uint32_t u32PowerOnHours, uint32_t u32PowerCycles, uint32_t u32ErrorCount); static WINDOW* createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, uint32_t u32PowerOnHours, uint32_t u32PowerCycles, uint32_t u32ErrorCount, uint32_t u32Temperature);
static WINDOW* createZeroChecksumWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, uint32_t u32Checksum); static WINDOW* createZeroChecksumWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, uint32_t u32Checksum);
void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY); void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY);

View File

@ -4,7 +4,7 @@ Description=dmesg on tty2
[Service] [Service]
WorkingDirectory=/usr/bin/ WorkingDirectory=/usr/bin/
ExecStart= ExecStart=
ExecStart=-/usr/bin/dmesg -wH ExecStart=-/usr/bin/dmesg -wHT
StandardInput=tty StandardInput=tty
StandardOutput=tty StandardOutput=tty
Restart=always Restart=always

View File

@ -14,36 +14,41 @@ string Drive::getPath(void)
string Drive::getModelFamily(void) string Drive::getModelFamily(void)
{ {
return sModelFamily; return sSmartData.sModelFamily;
} }
string Drive::getModelName(void) string Drive::getModelName(void)
{ {
return sModelName; return sSmartData.sModelName;
} }
string Drive::getSerial(void) string Drive::getSerial(void)
{ {
return sSerial; return sSmartData.sSerial;
} }
uint64_t Drive::getCapacity(void) uint64_t Drive::getCapacity(void)
{ {
return u64Capacity; return sSmartData.u64Capacity;
} }
uint32_t Drive::getErrorCount(void) uint32_t Drive::getErrorCount(void)
{ {
return u32ErrorCount; return sSmartData.u32ErrorCount;
} }
uint32_t Drive::getPowerOnHours(void) uint32_t Drive::getPowerOnHours(void)
{ {
return u32PowerOnHours; return sSmartData.u32PowerOnHours;
} }
uint32_t Drive::getPowerCycles(void) uint32_t Drive::getPowerCycles(void)
{ {
return u32PowerCycles; return sSmartData.u32PowerCycles;
}
uint32_t Drive::getTemperature(void)
{
return sSmartData.u32Temperature;
} }
string Drive::sCapacityToText() string Drive::sCapacityToText()
@ -91,6 +96,11 @@ string Drive::sPowerCyclesToText()
return to_string(getPowerCycles()); return to_string(getPowerCycles());
} }
string Drive::sTemperatureToText()
{
return to_string(getTemperature())+" C";;
}
void Drive::setTaskPercentage(double d32TaskPercentage) void Drive::setTaskPercentage(double d32TaskPercentage)
{ {
if(d32TaskPercentage <= 100) if(d32TaskPercentage <= 100)
@ -114,6 +124,7 @@ double Drive::getTaskPercentage(void)
* \param uint32_t errorCount * \param uint32_t errorCount
* \param uint32_t powerOnHours * \param uint32_t powerOnHours
* \param uint32_t powerCycle * \param uint32_t powerCycle
* \param uint32_t temperature
* \return void * \return void
*/ */
void Drive::setDriveSMARTData( string modelFamily, void Drive::setDriveSMARTData( string modelFamily,
@ -122,16 +133,17 @@ void Drive::setDriveSMARTData( string modelFamily,
uint64_t capacity, uint64_t capacity,
uint32_t errorCount, uint32_t errorCount,
uint32_t powerOnHours, uint32_t powerOnHours,
uint32_t powerCycle) uint32_t powerCycle,
uint32_t temperature)
{ {
this->sModelFamily = modelFamily; this->sSmartData.sModelFamily = modelFamily;
sModelName = modelName; this->sSmartData.sModelName = modelName;
sSerial = serial; this->sSmartData.sSerial = serial;
u64Capacity = capacity; this->sSmartData.u64Capacity = capacity;
u32ErrorCount = errorCount; this->sSmartData.u32ErrorCount = errorCount;
u32PowerOnHours = powerOnHours; this->sSmartData.u32PowerOnHours = powerOnHours;
u32PowerCycles = powerCycle; this->sSmartData.u32PowerCycles = powerCycle;
this->sSmartData.u32Temperature = temperature;
} }
void Drive::setTimestamp() void Drive::setTimestamp()
@ -167,7 +179,7 @@ void Drive::checkFrozenDrive(void)
time_t u32localtime; time_t u32localtime;
time(&u32localtime); time(&u32localtime);
if((u32localtime - this->u32Timestamp) >= (FROZEN_TIMEOUT*60) && (this->u32Timestamp > 0)) if((u32localtime - this->u32Timestamp) >= (FROZEN_TIMEOUT*60) && (this->u32Timestamp > 0) && (this->getTaskPercentage() < 100.0))
{ {
Logger::logThis()->warning("Drive Frozen: " + this->getModelName() + " " + this->getSerial()); Logger::logThis()->warning("Drive Frozen: " + this->getModelName() + " " + this->getSerial());
this->bWasDeleteted = false; this->bWasDeleteted = false;

View File

@ -264,6 +264,8 @@ void reHDD::filterNewDrives(list <Drive>* plistOldDrives, list <Drive>* plistNew
if((itOld->getSerial() == itNew->getSerial()) || (itOld->getPath() == itNew->getPath())) if((itOld->getSerial() == itNew->getSerial()) || (itOld->getPath() == itNew->getPath()))
{ {
itOld->bIsOffline = false; //drive is still attached itOld->bIsOffline = false; //drive is still attached
//copy new smart data to existing drive
itOld->setDriveSMARTData(itNew->getModelFamily(), itNew->getModelName(), itNew->getSerial(), itNew->getCapacity(), itNew->getErrorCount(), itNew->getPowerOnHours(), itNew->getPowerCycles(), itNew->getTemperature());
#ifdef LOG_LEVEL_HIGH #ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Delete new drive, because allready attached: " + itNew->getModelName()); Logger::logThis()->info("Delete new drive, because allready attached: " + itNew->getModelName());
#endif #endif

View File

@ -270,10 +270,11 @@ unsigned int Shred::uiCalcChecksum(fileDescriptor file,Drive* drive, int* ipSign
ulDriveByteCounter += iReadBytes; ulDriveByteCounter += iReadBytes;
ulDriveByteOverallCount += iReadBytes; ulDriveByteOverallCount += iReadBytes;
d32Percent = this->calcProgress(); d32Percent = this->calcProgress();
drive->sShredSpeed.ulSpeedMetricBytesWritten += iReadBytes;
#ifdef LOG_LEVEL_HIGH #ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Shred-Task (Checksum): ByteCount: " + to_string(ulDriveByteCounter) + " - progress: " + to_string(d32Percent) + " - Drive: " + drive->getSerial()); Logger::logThis()->info("Shred-Task (Checksum): ByteCount: " + to_string(ulDriveByteCounter) + " - progress: " + to_string(d32Percent) + " - Drive: " + drive->getSerial());
#endif #endif
if((d32Percent-d32TmpPercent) >= 0.9) if((d32Percent-d32TmpPercent) >= 0.01)
{ {
drive->setTaskPercentage(d32TmpPercent); drive->setTaskPercentage(d32TmpPercent);
d32TmpPercent = d32Percent; d32TmpPercent = d32Percent;

View File

@ -14,6 +14,7 @@ uint64_t SMART::capacity = 0U;
uint32_t SMART::errorCount = 0U; uint32_t SMART::errorCount = 0U;
uint32_t SMART::powerOnHours = 0U; uint32_t SMART::powerOnHours = 0U;
uint32_t SMART::powerCycle = 0U; uint32_t SMART::powerCycle = 0U;
uint32_t SMART::temperature = 0U;
/** /**
* \brief get and set S.M.A.R.T. values in Drive * \brief get and set S.M.A.R.T. values in Drive
@ -29,6 +30,7 @@ void SMART::readSMARTData(Drive* drive)
errorCount = 0U; errorCount = 0U;
powerOnHours = 0U; powerOnHours = 0U;
powerCycle = 0U; powerCycle = 0U;
temperature = 0U;
size_t len = 0; //lenght of found line size_t len = 0; //lenght of found line
char* cLine = NULL; //found line char* cLine = NULL; //found line
@ -50,9 +52,10 @@ void SMART::readSMARTData(Drive* drive)
SMART::parseErrorCount(sLine); SMART::parseErrorCount(sLine);
SMART::parsePowerOnHours(sLine); SMART::parsePowerOnHours(sLine);
SMART::parsePowerCycle(sLine); SMART::parsePowerCycle(sLine);
SMART::parseTemperature(sLine);
} }
pclose(outputfileSmart); pclose(outputfileSmart);
drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycle); //wirte data in drive drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycle, temperature); //wirte data in drive
} }
/** /**
@ -176,3 +179,26 @@ void SMART::parsePowerCycle(string sLine)
} }
} }
/**
* \brief parse temperature
* \param string output line of smartctl
* \return void
*/
void SMART::parseTemperature(string sLine)
{
string search("\"current\": ");
size_t found = sLine.find(search);
if (found!=string::npos)
{
sLine.erase(0, sLine.find(": ") + 2);
sLine.erase(sLine.length()-1, 2);
if(sLine == "{")
{
temperature = 0U; // this drive doesn't support temperatur
}
else
{
temperature = stol(sLine);
}
}
}

View File

@ -74,11 +74,12 @@ void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
for (it = plistDrives->begin(); it != plistDrives->end(); ++it) for (it = plistDrives->begin(); it != plistDrives->end(); ++it)
{ {
string sModelFamily = it->getModelFamily(); string sModelFamily = it->getModelFamily();
string sModelName = it->getModelName(); string sSerial = "SN: " + it->getSerial();
string sCapacity = it->sCapacityToText(); string sCapacity = it->sCapacityToText();
string sState = " "; string sState = " ";
string sSpeed = " "; string sSpeed = " ";
string sTime = " "; string sTime = " ";
string sTemp = it->sTemperatureToText();
bool bSelectedEntry = false; bool bSelectedEntry = false;
@ -87,10 +88,10 @@ void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
bSelectedEntry = true; //mark this drive in entries list bSelectedEntry = true; //mark this drive in entries list
displaySelectedDrive(*it, u16StdscrX, u16StdscrY); displaySelectedDrive(*it, u16StdscrX, u16StdscrY);
if((it->getPowerOnHours() >= WORSE_HOURS) || (it->getPowerCycles() >= WORSE_POWERUP) || (it->getErrorCount() > 0)) if((it->getPowerOnHours() >= WORSE_HOURS) || (it->getPowerCycles() >= WORSE_POWERUP) || (it->getErrorCount() > 0) || (it->getTemperature() >= WORSE_TEMPERATURE))
{ {
// smart values are bad --> show warning // smart values are bad --> show warning
smartWarning=createSmartWarning(50, 10, ((u16StdscrX)-(int)(u16StdscrX/2)+35),(int)(u16StdscrY/2)-5, it->getPath(), it->getPowerOnHours(), it->getPowerCycles(), it->getErrorCount()); smartWarning=createSmartWarning(50, 10, ((u16StdscrX)-(int)(u16StdscrX/2)+35),(int)(u16StdscrY/2)-5, it->getPath(), it->getPowerOnHours(), it->getPowerCycles(), it->getErrorCount(), it->getTemperature());
wrefresh(smartWarning); wrefresh(smartWarning);
} }
} }
@ -151,7 +152,7 @@ void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
break; break;
} }
WINDOW * tmp = createEntryWindow( ((int)(u16StdscrX/3) - 2), 5, 3, (5* (u8Index) )+3, sModelFamily, sModelName, sCapacity, sState, sTime, sSpeed, bSelectedEntry); WINDOW * tmp = createEntryWindow( ((int)(u16StdscrX/3) - 2), 5, 3, (5* (u8Index) )+3, (distance(plistDrives->begin(), it)+1), sModelFamily, sSerial, sCapacity, sState, sTime, sSpeed, sTemp, bSelectedEntry);
wrefresh(tmp); wrefresh(tmp);
u8Index++; u8Index++;
}//end loop though drives }//end loop though drives
@ -308,7 +309,7 @@ WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart)
return newWindow; return newWindow;
} }
WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, string sTime, string sSpeed, bool bSelected) WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, int iListIndex, string sModelFamily, string sSerial, string sCapacity, string sState, string sTime, string sSpeed, string sTemp, bool bSelected)
{ {
WINDOW *newWindow; WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, iXStart); newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
@ -328,9 +329,12 @@ WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart,
box(newWindow, ACS_VLINE, ACS_HLINE); box(newWindow, ACS_VLINE, ACS_HLINE);
mvwaddstr(newWindow,1, 1, sModelFamily.c_str()); mvwaddstr(newWindow,1, 1, to_string(iListIndex).c_str());
mvwaddstr(newWindow,2, 1, sModelName.c_str());
mvwaddstr(newWindow,3, 1, sCapacity.c_str()); mvwaddstr(newWindow,1, 5, sModelFamily.c_str());
mvwaddstr(newWindow,2, 5, sSerial.c_str());
mvwaddstr(newWindow,3, 5, sCapacity.c_str());
mvwaddstr(newWindow,3, 5+sCapacity.length()+3, sTemp.c_str());
mvwaddstr(newWindow,1, iXSize-sSpeed.length()-5, sSpeed.c_str()); mvwaddstr(newWindow,1, iXSize-sSpeed.length()-5, sSpeed.c_str());
mvwaddstr(newWindow,2, iXSize-sState.length()-5, sState.c_str()); mvwaddstr(newWindow,2, iXSize-sState.length()-5, sState.c_str());
@ -357,10 +361,14 @@ WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iXStart, int iYStart)
strftime(buffer,sizeof(buffer),"Date: %d-%m-%Y Time: %H:%M",timeinfo); strftime(buffer,sizeof(buffer),"Date: %d-%m-%Y Time: %H:%M",timeinfo);
string time(buffer); string time(buffer);
string sLine01 = "reHDD - hard drive refurbishing tool"; string sLine01 = "reHDD - hard drive refurbishing tool";
string sLine02 = "Version: " + string(REHDD_VERSION); string sLine02 = "Version: " + string(REHDD_VERSION);
string sLine03 = "Available under GPL 3.0"; string sLine03 = "Build time: ";
string sLine04 = "https://git.mosad.xyz/localhorst/reHDD"; sLine03.append(__DATE__);
sLine03.append(" ");
sLine03.append(__TIME__);
string sLine04 = "Available under GPL 3.0";
string sLine05 = "https://git.mosad.xyz/localhorst/reHDD";
uint16_t u16Line = 2; uint16_t u16Line = 2;
@ -368,6 +376,7 @@ WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iXStart, int iYStart)
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine02.c_str()); mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine02.c_str());
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine03.c_str()); mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine03.c_str());
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine04.c_str()); mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine04.c_str());
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine05.c_str());
u16Line++; u16Line++;
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), time.c_str()); mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), time.c_str());
@ -578,7 +587,7 @@ void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
} }
} }
WINDOW* TUI::createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, uint32_t u32PowerOnHours, uint32_t u32PowerCycles, uint32_t u32ErrorCount) WINDOW* TUI::createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, uint32_t u32PowerOnHours, uint32_t u32PowerCycles, uint32_t u32ErrorCount, uint32_t u32Temperature)
{ {
WINDOW *newWindow; WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, iXStart); newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
@ -613,6 +622,13 @@ WINDOW* TUI::createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart
{ {
string sLineTmp = "S.M.A.R.T. erros detected: " + to_string(u32ErrorCount); string sLineTmp = "S.M.A.R.T. erros detected: " + to_string(u32ErrorCount);
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLineTmp.c_str()); mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLineTmp.c_str());
u16Line++;
}
if(u32Temperature >= WORSE_TEMPERATURE)
{
string sLineTmp = "Drive too hot: " + to_string(u32Temperature)+" C";
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLineTmp.c_str());
} }
return newWindow; return newWindow;
} }