Index: sources/storage/TreatmentLog.cpp =================================================================== diff -u -r16bd55822fa77e5bea6fdfa7b54abf123c1da8bb -r6c6f1f5d466badd9b4fd67be7c907234c342b2a2 --- sources/storage/TreatmentLog.cpp (.../TreatmentLog.cpp) (revision 16bd55822fa77e5bea6fdfa7b54abf123c1da8bb) +++ sources/storage/TreatmentLog.cpp (.../TreatmentLog.cpp) (revision 6c6f1f5d466badd9b4fd67be7c907234c342b2a2) @@ -1,13 +1,13 @@ /*! * - * Copyright (c) 2021-2022 Diality Inc. - All Rights Reserved. + * Copyright (c) 2021-2023 Diality Inc. - All Rights Reserved. * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * \file TreatmentLog.cpp * \author (last) Behrouz NematiPour - * \date (last) 27-Jun-2022 + * \date (last) 07-Apr-2023 * \author (original) Behrouz NematiPour * \date (original) 04-May-2021 * @@ -34,6 +34,7 @@ #define ADDTITLE(vTITLE) logContent += QString("[%1]\n").arg(vTITLE) #define ADDALINE(vTEXT ) logContent += QString("%1\n" ).arg(vTEXT ) #define ADDTOLOG(vINDEX) index = vINDEX; logContent += title(index) + sep + value(index) + sep + unit(index) + "\n"; + /*! * \brief TreatmentLog::TreatmentLog * The constructor to initial the Treatment Log @@ -58,12 +59,24 @@ connect(&_saveWatcher , SIGNAL(finished()), this , SLOT(onSave ())); + connect(&_CloudSyncController , SIGNAL(didCloudSyncStatus(bool)), + this , SLOT( onCloudSyncStatus(bool))); + connect(&_CloudSyncController , SIGNAL(didTxCodeReceive(const QString &)), this , SLOT( onTxCodeReceive(const QString &))); } /*! + * \brief TreatmentLog::timerEvent + * \details The overloaded method of the main class to capture the QObject timer. + */ +void TreatmentLog::timerEvent(QTimerEvent *) +{ + testPendingTxReports(); +} + +/*! * \brief TreatmentLog::initModel * Initializing the model for the constant values. * \param vData - the response model data. @@ -87,11 +100,11 @@ // - the category shall become as part of the group // - the structure of the settings should become horizontal which vertical now. QString mCategory = Storage::Settings_Category_ConfigurationsDataList; - QString mAcidConcentrateType = _Settings.key(mCategory, "Acid Concentrate" , vData.mAcidConcentrateType ); - QString mBicarbonateConcentrateType = _Settings.key(mCategory, "Bicarbonate Concentrate" , vData.mBicarbonateConcentrateType ); - QString mDialyzerType = _Settings.key(mCategory, "Dialyzer Type" , vData.mDialyzerType ); - QString mHeparinType = _Settings.key(mCategory, "Heparin Type" , vData.mHeparinType ); - QString mWaterSampleTestResult = _Settings.key(mCategory, "Water Sample Result" , vData.mWaterSampleTestResult ); + QString mAcidConcentrateType = _Settings.key(mCategory, "Acid Concentrate Options" , vData.mAcidConcentrateType ); + QString mBicarbonateConcentrateType = _Settings.key(mCategory, "Bicarbonate Concentrate Options" , vData.mBicarbonateConcentrateType ); + QString mDialyzerType = _Settings.key(mCategory, "Dialyzer Type Options" , vData.mDialyzerType ); + QString mHeparinType = _Settings.key(mCategory, "Heparin Type Options" , vData.mHeparinType ); + QString mWaterSampleTestResult = _Settings.key(mCategory, "Water Sample Result" , vData.mWaterSampleTestResult ); // init/fill/clear the _values @@ -167,13 +180,18 @@ if (vLogType == Logger::eLogTrtmt) { if ( vLogPath.trimmed().isEmpty() ) { _treatmentLogPath = QString("%1%2") - .arg(Storage::SDCard_Base_Path_Name) + .arg(Storage::Settings_Path_Name) .arg(Storage::Log_Folder_Treatment ); } else { _treatmentLogPath = vLogPath; } - LOG_DEBUG(QString("Treatment log folder has been set to %1").arg(_treatmentLogPath)); + _treatmentLogPath_Pending = QString("%1%2") + .arg(Storage::Settings_Path_Name) + .arg(Storage::Log_Folder_Pending ); + + LOG_DEBUG(QString("Treatment log folder has been set to %1" ).arg(_treatmentLogPath )); + LOG_DEBUG(QString("Treatment log pending folder has been set to %1" ).arg(_treatmentLogPath_Pending )); } } @@ -218,7 +236,7 @@ QString end = "%1" ; uint index = 0 ; - ADDTITLE("Title"); + // ADDTITLE("Title"); // will be added with Tx Code when gets out of pending, by receiving the Tx Code from CloudSync ADDTOLOG( ePatientID ); ADDTITLE("Treatment Parameters" ); @@ -304,18 +322,21 @@ _lastTxInfo.mDeviceID = _deviceID; _lastTxInfo.mPatientID = _values[ePatientID]; _lastTxInfo.mFileName = QString("%1%2_%3.log") - .arg(_treatmentLogPath) + .arg(_treatmentLogPath_Pending) .arg(_lastTxInfo.mDateTime) .arg(_lastTxInfo.mDeviceID); - ok = Storage::FileHandler::makeFolder(_treatmentLogPath); - if ( ! ok ) { LOG_DEBUG(QString("Cannot create folder %1").arg(_treatmentLogPath)); return ok; } + ok = Storage::FileHandler::makeFolder(_treatmentLogPath_Pending); + if ( ! ok ) { LOG_DEBUG(QString("Cannot create folder %1").arg(_treatmentLogPath_Pending)); return ok; } ok = Storage::FileHandler::write(_lastTxInfo.mFileName, logContent, false); if ( ! ok ) { LOG_DEBUG(QString("Cannot write to file %1").arg(_lastTxInfo.mFileName)); return ok; } _treatmentLogAvrgeData.clear(); _treatmentLogAlarmData.clear(); _treatmentLogEventData.clear(); _lastTxInfo.mStatus = ok; + + sendPending(); // reset the timer to find the latest saved pending and ask for Tx Code. + return ok; } @@ -327,10 +348,6 @@ { LOG_DEBUG(QString("Save Treatment Log Ended: %1").arg(_saveWatcher.result())); isIdle(true); - if ( _lastTxInfo.mStatus ) - emit didTreatmentLogSave( _lastTxInfo.mDeviceID , - _lastTxInfo.mPatientID , - _lastTxInfo.mFileName ); } // ----- Export @@ -401,6 +418,24 @@ } /*! + * \brief TreatmentLog::onCloudSyncStatus + * \details This is the handler to the slot CloudSyncController::didCloudSyncStatus, + * which will be emitted when the Cloud is running and the device is registered, with vReady as true. + * Therefore pending Treatment logs can be sent. + * or with ready as false if CloudSync stops or for any error can't communicate to send the logs. + */ +void TreatmentLog::onCloudSyncStatus(bool vReady) +{ + static int id; + if ( vReady ) { + id = startTimer(_interval); + } + else { + killTimer(id); + } +} + +/*! * \brief TreatmentLog::onTxCodeReceive * \details this slot will update the treatment code sent by CS. * \param vTxCode - The treatment code sent by CS. @@ -409,5 +444,92 @@ void TreatmentLog::onTxCodeReceive(const QString &vTxCode) { _txCode = vTxCode; - emit didTxCodeReceive(_txCode); + // This has to be checked before the addTxCode, + // because that function will change the _lastTxInfo.mFilename after it is moved from pending. + bool isLastTxInfo = ! _lastTxInfo.mFileName.isEmpty() && _pendingTx == _lastTxInfo.mFileName; + + // getting the Tx out of pending and add the received Tx in the file + addTxCode(); + + if ( isLastTxInfo ) { + // avoid updating the screen with another pending Tx in queue + emit didTxCodeReceive(_txCode); + } } + +/*! + * \brief TreatmentLog::addTxCode + * \details Adds the [Title] and Tx Code to the file and moves it from pending. + * \return true on success, false on any case of read, write, remove. + */ +bool TreatmentLog::addTxCode() +{ + bool ok = true; + QString src = _pendingTx; + QString dst = _treatmentLogPath + QFileInfo(src).fileName(); + QString logContent; + ADDTITLE("Title"); + ADDALINE(QString("Tx Code,%1,").arg(_txCode)); + + ok = FileHandler::read (src, logContent, true ); // reads the file and appends the content to logContent + if ( ! ok ) { + LOG_DEBUG(QString("Couldn't read pending treatment log file '%1'").arg(src)); + return ok; + } + + ok = FileHandler::write (dst, logContent ); + if ( ! ok ) { + LOG_DEBUG(QString("Couldn't settle pending treatment log file '%1'").arg(src)); + return ok; + } + + QFile::remove(src); + if ( ! ok ) { + LOG_DEBUG(QString("Couldn't remove pending treatment log file '%1'").arg(src)); + return ok; + } + _lastTxInfo.mFileName = dst; // Update the last Tx file to the new location [ export ] + sendPending(); // start looking for the next pending, instead of waiting to timeout + return ok; +} + +/*! + * \brief TreatmentLog::sendPending + * \details Resets the pending counter to immediately/ASAP as for the pending and won't waits for the timeout. + */ +void TreatmentLog::sendPending() +{ + _pendingCounter = 0; +} + +/*! + * \brief TreatmentLog::testPendingTxReports + * \details this function count downs for the _pendingInterval + * when the _pendingCounter reaches 0 will search for the files + * in the _TreatmentLog.logPathPending() + * and if there is any will get the recent file in the list + * and asks for the TxCode by emitting the didTxPending signal + */ +void TreatmentLog::testPendingTxReports() +{ + if ( _pendingCounter ) { + _pendingCounter -- ; + return; + } + else { + _pendingCounter = _pendingInterval; // every minute + } + + QFileInfoList pendingFiles; + pendingFiles = Storage::FileHandler::find(_TreatmentLog.logPathPending(), {"*.log"}); + // look into the list. + // if there are pending files, + // send a request only for the top on the list + // * When gets the Tx Code, moves from pending then next one comes to top + // the process repeats until there is no file in pending + if ( pendingFiles.count() ) { + // the most recent/first Tx file, to first ask for the current treatment which has just saved as pending on screen + _pendingTx = pendingFiles.first().absoluteFilePath(); + emit didTxPending( _pendingTx ); + } +}