Index: AlarmMapping.csv =================================================================== diff -u -r13a271ff9262b297f76fa2f97110ff5e0f3f1e1b -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- AlarmMapping.csv (.../AlarmMapping.csv) (revision 13a271ff9262b297f76fa2f97110ff5e0f3f1e1b) +++ AlarmMapping.csv (.../AlarmMapping.csv) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -41,7 +41,7 @@ 40,"Dialysis outlet pump failed motor off check.\nMeasured speed while commanded off." 41,"Dialysis outlet pump failed motor direction check.\nMeasured vs commanded." 42,"Dialysis outlet pump failed rotor speed check.\nMismatch with rotor and motor speeds." - 43,"Alarm ID available for use." + 43,"HD blood leak self test fault." 44,"User interface communication timeout." 45,"HD too many bad communications CRC." 46,"System message that required acknowledgment was not acknowledged." @@ -72,7 +72,7 @@ 71,"HD venous pressure self-test failure alarm." 72,"HD blood flow meter status check self-test failure alarm." 73,"HD dialysate flow meter status check self-test failure alarm." - 74,"HD blood leak detector self-test failure alarm." + 74,"HD blood leak detector self-test transmit timeout." 75,"HD syringe pump self-test failure alarm." 76,"HD monitored voltage is out of range." 77,"DG monitored voltage is out of range." @@ -110,8 +110,8 @@ 109,"HD syringe pump volume check error." 110,"HD syringe pump speed check error." 111,"HD syringe pump not stopped in off state error." - 112,"HD blood leak zero command timeout." - 113,"Unused." + 112,"HD blood leak zero command transmit timeout." + 113,"HD blood leak zero command fault." 114,"HD venous air bubble detector self-test failure." 115,"DG temperature sensor out of range." 116,"DG temperature sensor ADC out of range." @@ -286,7 +286,7 @@ 285,"HD treatment recirculate timeout warning." 286,"HD treatment rinseback complete timeout warning." 287,"HD processor clock speed checks against FPGA clock failure." - 288,"Alarm ID available for use." + 288,"HD load cells primary/back up drift out of range." 289,"DG dialysate or concentrate caps not closed." 290,"DG flow too low while heater is on." 291,"Total number of alarms." Index: alarmMapping.sh =================================================================== diff -u -r2d0bacfbe1b70055247eb40743405a5f9acb15e3 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- alarmMapping.sh (.../alarmMapping.sh) (revision 2d0bacfbe1b70055247eb40743405a5f9acb15e3) +++ alarmMapping.sh (.../alarmMapping.sh) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -9,12 +9,12 @@ # @file alarmMapping.sh # # @author (last) Behrouz NematiPour -# @date (last) 28-Mar-2022 +# @date (last) 22-Jun-022 # @author (original) Behrouz NematiPour # @date (original) 11-May-2021 # ############################################################################ - +ALARM_MAPPING=../scripts/build/alarmMapping BRANCH="staging" if ( test -n "$1" ); then BRANCH="$1" @@ -28,7 +28,7 @@ fi cd .. -if ! ( test -x ../scripts/build/alarmMapping ); then +if ! ( test -x $ALARM_MAPPING ); then echo "Alarm Mapping tool doesn't exist. Continues by assuming the Alarm Table is updated." # if return anything other than 0 build stops running next steps. # it is ok for the dev_test to not to have the script folder and @@ -38,10 +38,10 @@ # update the alarm messaging echo "update the alarm message mapping" -../scripts/build/alarmMapping \ - common/ \ - sources/model/hd/alarm/ \ - 2> alarmMapping.err \ +$ALARM_MAPPING \ + common/ \ + sources/model/hd/alarm/ \ + 2> alarmMapping.err \ | tee alarmMapping.log echo "move the Alarm code mapping to current location(./)" Index: denali.pro.user =================================================================== diff -u -r13a271ff9262b297f76fa2f97110ff5e0f3f1e1b -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- denali.pro.user (.../denali.pro.user) (revision 13a271ff9262b297f76fa2f97110ff5e0f3f1e1b) +++ denali.pro.user (.../denali.pro.user) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -1,6 +1,6 @@ - + EnvironmentId @@ -132,7 +132,7 @@ false - false + true true @@ -1249,6 +1249,15 @@ true + staging + /home/denali/Projects/application/alarmMapping.sh + %{sourceDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + + true qmake QtProjectManager.QMakeBuildStep @@ -1258,7 +1267,7 @@ false false - + true Make @@ -1269,7 +1278,7 @@ false - + true -b --tag denali >> denali @@ -1279,7 +1288,7 @@ ProjectExplorer.ProcessStep - 3 + 4 Build Build ProjectExplorer.BuildSteps.Build Index: denali.qrc =================================================================== diff -u -reaf21ffe52c818b4c8abdb2084582ada9dc78ceb -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- denali.qrc (.../denali.qrc) (revision eaf21ffe52c818b4c8abdb2084582ada9dc78ceb) +++ denali.qrc (.../denali.qrc) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -15,6 +15,7 @@ sources/gui/qml/pages/settings/SettingsDG.qml sources/gui/qml/pages/settings/SettingsVolumeBrightness.qml sources/gui/qml/pages/settings/SettingsBluetoothCuff.qml + sources/gui/qml/pages/settings/SettingsExportLogs.qml sources/gui/qml/dialogs/PowerOff.qml @@ -136,40 +137,41 @@ sources/gui/qml/AlarmItem.qml sources/gui/qml/PowerItem.qml sources/gui/qml/KeyboardItem.qml - sources/gui/qml/SDItem.qml + sources/gui/qml/SDCProgressItem.qml + sources/gui/qml/USBProgressItem.qml - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/backspace.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/check.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/enter.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/globe.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/handwriting.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/hidekeyboard.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/search.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/selectionhandle.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/shift-normal.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/shift-active.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/shift-capslock.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/textmode.svg - sources/gui/qml/plugins/virtualkeyboard/styles/denali/style.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/dialpad.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/digits.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/handwriting.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/main.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/numbers.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/symbols.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/dialpad.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/digits.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/handwriting.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/main.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/numbers.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/symbols.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/dialpad.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/digits.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/handwriting.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/main.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/numbers.qml - sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/symbols.qml + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/backspace.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/check.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/enter.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/globe.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/handwriting.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/hidekeyboard.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/search.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/selectionhandle.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/shift-normal.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/shift-active.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/shift-capslock.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/images/textmode.svg + sources/gui/qml/plugins/virtualkeyboard/styles/denali/style.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/dialpad.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/digits.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/handwriting.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/main.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/numbers.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_GB/symbols.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/dialpad.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/digits.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/handwriting.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/main.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/numbers.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/en_US/symbols.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/dialpad.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/digits.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/handwriting.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/main.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/numbers.qml + sources/gui/qml/plugins/virtualkeyboard/layouts/fallback/symbols.qml Index: scripts/run.sh =================================================================== diff -u -r768259b3c00ee3fbc5ba04475763b43cfac76bfe -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- scripts/run.sh (.../run.sh) (revision 768259b3c00ee3fbc5ba04475763b43cfac76bfe) +++ scripts/run.sh (.../run.sh) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -24,10 +24,13 @@ #DO NOT MODIFY VARIABLES #unless the denali applicaiton is updated as well to match. HOME=/home/root + SDCARD_DEV=/dev/mmcblk1p1 SDCARD_MNT=/media/sd-card USB_DEV=/dev/sda1 USB_MNT=/media/usb +CLOUDSYNC_FOLDER=cloudsync # both for log and application + POSTLOG=$HOME/post.log POSTERR=$HOME/post.err POSTOUT=$HOME/post.out @@ -44,12 +47,10 @@ echo "" > $POSTERR echo "" > $POSTOUT - #create folders for sd-card and usb if not exist mkdir -p $SDCARD_MNT mkdir -p $USB_MNT - # ---------------------------------------- UPDATE #mounting usb mount $USB_DEV $USB_MNT @@ -73,6 +74,7 @@ # ---------------------------------------- SETUP & POST #Here only passed is logged and if nothing added to the post.log means it failed. + #setting up can interface ----------------- CANBus #current settings can be retrieved by the command below #$ ip -details -statistics link show can0 @@ -122,11 +124,12 @@ fi +# ---------------------------------------- Connections # stop the connection manager daemon killall connmand -# setup bluetooth +# ---------------------------------------- Bluetooth /usr/share/silex-uart/silex-uart.sh start 1>> $POSTOUT 2>> $POSTERR sleep 5 hciconfig hci0 up @@ -135,13 +138,14 @@ fi -# setup wifi +# ---------------------------------------- WiFi killall wpa_supplicant 1>> $POSTOUT 2>> $POSTERR if [[ ! -z $(dmesg | grep "wlan: driver loaded") ]]; then echo $POSTMSG_WIFI >> $POSTLOG fi +# ---------------------------------------- Sha256Sum #check the denali applicatoin checksum SHA_ACT=$(tail -c 83 $HOME/denali | cut -c19-82) SHA_EXP=$(head -c -83 $HOME/denali | sha256sum -b --tag | cut -c14-77) @@ -150,15 +154,34 @@ fi +# ---------------------------------------- CloudSync +# moving/ backing up the previous treatment logs so the new buff starts with fresh sequence +echo "Backing up CloudSync I/O buff" +CLOUDSYNC_PATH="$SDCARD_MNT"/"$CLOUDSYNC_FOLDER" +CLOUDSYNC_BACKUP="$CLOUDSYNC_PATH"_backup/$(currDate)/ +mkdir -p $CLOUDSYNC_BACKUP +mv $CLOUDSYNC_PATH/* $CLOUDSYNC_BACKUP +rm $HOME/$CLOUDSYNC_FOLDER/data/* +echo "Starting CloudSync" >> $POSTLOG +cd $HOME/$CLOUDSYNC_FOLDER/ +python3 ./cs.py start & +sleep 2 +echo "$(python3 ./cs.py status)" >> $POSTLOG +cd + + +# ---------------------------------------- Denali #launching denali application #TODO: -d(--enable-dialin-unhandled) added for the development phase and has to be removed later -$HOME/denali -u -d & +$HOME/denali -u -d & # -a has to be removed and is only for debugging to bypass the nonminimizable alarms. +# ---------------------------------------- END # tag the end time in the POST log file echo "End: $(date +"%d%m%Y%H%M%S")" >> $POSTLOG +# ---------------------------------------- Ethernet # setup ethernet # note: At this time the application is running and also the ehternet connection is not necessary # so the sleep here is not hurtung any part of the applicaion progress. Index: sources/cloudsync/CloudSyncController.cpp =================================================================== diff -u -r04c386c7752b972928ecbf34b3e6e7f135c8a343 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision 04c386c7752b972928ecbf34b3e6e7f135c8a343) +++ sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -415,7 +415,7 @@ */ void CloudSyncController::testWatchBuffDate() { - _datetime = QDateTime::currentDateTime(); + _datetime = QDateTime::currentDateTime().toUTC(); _secSinceEpoch = _datetime.toSecsSinceEpoch(); _timeFormatted = _datetime.toString(_timeFormat); QString dateFormatted = _datetime.toString(_dateFormat); @@ -695,6 +695,7 @@ ok = doResetFactory(); // if ( ! ok ) { } /* Not defined */ qint32 messageID = UI2CS(eMessageID_ResetFactory); + // TODO : Store registration success in here ok = sendUIBuff(QString("%1,1,%2").arg( messageID ).arg( ok ? eSucceed : eFailed )); return ok; } Index: sources/device/DeviceController.cpp =================================================================== diff -u -r79a6cfcb10472261f3ec26eaf0baf6f1245cd311 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 79a6cfcb10472261f3ec26eaf0baf6f1245cd311) +++ sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -200,15 +200,22 @@ bool DeviceController::driveSpaceCheck(const QString &vPath, qint64 &vTotalBytes, qint64 &vAvailableBytes, bool *vIsReadOnly) { // disabled coco begin validated: Needed User Interaction to make the device not ready so tested manually - bool isReadOnly; - if (! FileHandler::isMounted(vPath, &isReadOnly)) return false; - if (vIsReadOnly) *vIsReadOnly = isReadOnly; + bool isReadOnly = true; + bool isMounted = FileHandler::isMounted(vPath, &isReadOnly); + if ( vIsReadOnly ) *vIsReadOnly = isReadOnly; + QStorageInfo storage(vPath); bool isReady = storage.isReady(); - if (isReady) { + if ( isReady ) { vTotalBytes = storage.bytesTotal(); vAvailableBytes = storage.bytesAvailable(); } + + if ( ! isMounted || ! isReady ) { + isReady = false; + vTotalBytes = 0; + vAvailableBytes = 0; + } return isReady; } // disabled coco end @@ -235,6 +242,7 @@ { // disabled coco begin validated: Needed User Interaction so tested manually QString device = ""; + usbSpaceCheck(); if (usbSeek(device)) { if (! _umounted ) { usbMount(device); @@ -250,57 +258,102 @@ } /*! - * \brief DeviceController::sdcardFreeSpaceCheck - * \details Checks the drivers for available free space. + * \brief DeviceController::sdcardSpaceCheck + * \details Checks for the SD-Card drive space. */ void DeviceController::sdcardSpaceCheck() { - // disabled coco begin validated: Needed User Interaction so tested manually - + static bool mInitialized = false; // Old Info ; // Current info static bool mOIsReady ; bool mCIsReady ; static bool mOIsReadOnly; bool mCIsReadOnly ; static qint64 mOTotal ; qint64 mCTotal ; static qint64 mOAvailable ; qint64 mCAvailable ; + quint8 mPercent = 0; + mCIsReady = driveSpaceCheck(Storage::SDCard_Base_Path_Name, mCTotal, mCAvailable, &mCIsReadOnly); - /// DEBUG: qDebug() << " ===== " << Storage::SDCard_Base_Path_Name << mCIsReady; - if (mOIsReadOnly != mCIsReadOnly || mOIsReady != mCIsReady) { + if (mOIsReadOnly != mCIsReadOnly || mOIsReady != mCIsReady || ! mInitialized ) { mOIsReadOnly = mCIsReadOnly; + mOIsReady = mCIsReady; + mInitialized = true; emit didSDCardStateChange(mCIsReady, mCIsReadOnly); } if (! mCIsReady ) { mOIsReady = mCIsReady; mOTotal = 0; mOAvailable = 0; + emit didSDCardSpaceChange(mCIsReady, mCTotal, mCAvailable, mPercent); return; } - quint8 mPercent = mCTotal ? ((100 * mCAvailable) / mCTotal) : 0; + mPercent = mCTotal ? ((100 * mCAvailable) / mCTotal) : 0; if (mPercent < _minRequiredAvailableSpacePercent) { LOG_DEBUG(QString("SD-CARD space lower than %1%").arg(_minRequiredAvailableSpacePercent)); emit didSDCardSpaceChange(mCIsReady, mCTotal, mCAvailable, mPercent); emit didSDCardSpaceTooLow(_minRequiredAvailableSpacePercent); } /// DEBUG: qDebug() << Storage::SDCard_Base_Path_Name << mCIsReady << mOTotal << mCTotal << (mOTotal == mCTotal) << mOAvailable << mCAvailable << (mOAvailable == mCAvailable) << mPercent << mCIsReadOnly; - if (mOTotal == mCTotal && - mOAvailable == mCAvailable) { + mOAvailable == mCAvailable) { return; } mOIsReady = mCIsReady ; mOTotal = mCTotal ; mOAvailable = mCAvailable ; - if (_pauseSpaceCheck) return; + if (_pauseSpaceCheck) return; //TODO: may not be required, but needs a lot of time consuming testing. emit didSDCardSpaceChange(mCIsReady, mCTotal, mCAvailable, mPercent); /// DEBUG: qDebug() << Storage::SDCard_Base_Path_Name << mCIsReady << mCTotal << mCAvailable << mPercent ; } -// disabled coco end /*! + * \brief DeviceController::usbSpaceCheck + * \details Checks for the USB drive space. + */ +void DeviceController::usbSpaceCheck() +{ + static bool mInitialized = false; + // Old Info ; // Current info + static bool mOIsReady ; bool mCIsReady ; + static bool mOIsReadOnly; bool mCIsReadOnly ; + static qint64 mOTotal ; qint64 mCTotal ; + static qint64 mOAvailable ; qint64 mCAvailable ; + + quint8 mPercent = 0; + + mCIsReady = driveSpaceCheck(Storage::USB_Mount_Point, mCTotal, mCAvailable, &mCIsReadOnly); + if (mOIsReadOnly != mCIsReadOnly || mOIsReady != mCIsReady || ! mInitialized ) { + mOIsReadOnly = mCIsReadOnly; + mOIsReady = mCIsReady; + mInitialized = true; + emit didUSBStateChange(mCIsReady, mCIsReadOnly); + } + + if (! mCIsReady ) { + mOIsReady = mCIsReady; + mOTotal = 0; + mOAvailable = 0; + emit didUSBSpaceChange(mCIsReady, mCTotal, mCAvailable, mPercent); + return; + } + + mPercent = mCTotal ? ((100 * mCAvailable) / mCTotal) : 0; + if (mOTotal == mCTotal && + mOAvailable == mCAvailable) { + return; + } + + mOIsReady = mCIsReady ; + mOTotal = mCTotal ; + mOAvailable = mCAvailable ; + emit didUSBSpaceChange(mCIsReady, mCTotal, mCAvailable, mPercent); +} + + +/*! * \brief DeviceController::usbError * \details Logs any error which has been happened * On USB device vDevice @@ -358,7 +411,7 @@ // has been tested manually bool ok; _usbDrive = vDevice.toLatin1().constData(); - ok = ::mount(_usbDrive, USB_Mount_Point, USB_File_System, MS_SYNCHRONOUS, "") == 0; + ok = ::mount(_usbDrive, USB_Mount_Point, USB_File_System, MS_SYNCHRONOUS | MS_NOEXEC, "") == 0; if (ok) { _mounted = true; _removed = false; @@ -591,7 +644,7 @@ void DeviceController::ondoAddWatch(const QString &vFile) { if ( ! QFileInfo::exists(vFile)) { - if ( ! FileHandler::write(vFile, "", false) ) { + if ( ! FileHandler::write(vFile, "", false) ) { // if the file doesn't exist it has to be created to be watched. LOG_DEBUG(DeviceError::deviceErrorText(DeviceError::eDevice_Watch_Error_NotFound, 0)); return; } Index: sources/device/DeviceController.h =================================================================== diff -u -r79a6cfcb10472261f3ec26eaf0baf6f1245cd311 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/device/DeviceController.h (.../DeviceController.h) (revision 79a6cfcb10472261f3ec26eaf0baf6f1245cd311) +++ sources/device/DeviceController.h (.../DeviceController.h) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -173,6 +173,9 @@ */ void didUSBDriveRemove(); + void didUSBStateChange(bool vIsReady, bool vIsReadOnly); + void didUSBSpaceChange(bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent); + /*! * \brief didSDCardFreeSpaceChange * \param vReady - Device is mounted and ready @@ -222,6 +225,9 @@ // ----- SDCard void sdcardSpaceCheck(); + // ----- USBDrive + void usbSpaceCheck(); + SAFE_CALL_EX(doAddWatch, const QString &) }; } Index: sources/gui/GuiView.cpp =================================================================== diff -u -r79a6cfcb10472261f3ec26eaf0baf6f1245cd311 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/GuiView.cpp (.../GuiView.cpp) (revision 79a6cfcb10472261f3ec26eaf0baf6f1245cd311) +++ sources/gui/GuiView.cpp (.../GuiView.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -58,6 +58,10 @@ connect(&_GuiController, SIGNAL(didUSBDriveRemove()), this , SLOT( onUSBDriveRemove())); + // USB Drive + connect(&_DeviceController, SIGNAL( didUSBSpaceChange(bool, qint64, qint64, quint8)), + this , SLOT( onUSBSpaceChange(bool, qint64, qint64, quint8))); + // SD Card connect(&_GuiController, SIGNAL(didSDCardStateChange(bool,bool)), this , SLOT( onSDCardStateChange(bool,bool))); @@ -132,8 +136,8 @@ { // disabled coco begin validated: This needs user interaction to plug-in USB device // has been tested manually - usbReady (true ); - usbRemoved (false); + usbIsReady (true ); + usbIsRemoved(false); emit didUSBDriveMount (); } // disabled coco end @@ -147,8 +151,8 @@ { // disabled coco begin validated: This needs user interaction to plug-in USB device // has been tested manually - usbReady (false); - usbRemoved (false); + usbIsReady (false); + usbIsRemoved(false); emit didUSBDriveUmount(); } // disabled coco end @@ -162,8 +166,8 @@ { // disabled coco begin validated: This needs user interaction to plug-in USB device // has been tested manually - usbReady (false); - usbRemoved (true ); + usbIsReady (false); + usbIsRemoved(true ); emit didUSBDriveRemove(); } // disabled coco end @@ -205,24 +209,21 @@ */ void GuiView::onExport() { - // disabled coco begin validated: This needs user interaction to plug-in USB device - // has been tested manually emit didExport(); + exportRunning(false); } -// disabled coco end + /*! * \brief GuiView::doExportLog * \details emits didExportLog signal to notify other classes (GuiController) * , the User requested to export the log. */ void GuiView::doExportLog() { - // disabled coco begin validated: This needs user interaction to plug-in USB device - // has been tested manually + exportRunning(true); emit didExportLog(); } -// disabled coco end /*! * \brief GuiView::onSDCardSpaceChange @@ -247,3 +248,15 @@ sdIsLow ( vPercent <= Storage::Available_Space_Percent ); } // disabled coco end + +void GuiView::onUSBSpaceChange(bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent) +{ + // has been tested manually + /// DEBUG: qDebug() << vReady << vTotal << vAvailable << vPercent << Storage::Available_Space_Percent; + usbTotal ( vTotal ); + usbAvail ( vAvailable ); + usbPercent ( vPercent ); + usbIsReady ( vReady ); + // TODO : the space check should also be done for the USB as destination but needs calculation has will be done later. + // usbIsLow ( vPercent <= Storage::Available_Space_Percent ); +} Index: sources/gui/GuiView.h =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/GuiView.h (.../GuiView.h) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/gui/GuiView.h (.../GuiView.h) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -49,19 +49,27 @@ PROPERTY(quint64, sdTotal , 0 ) PROPERTY(quint64, sdAvail , 0 ) PROPERTY(quint8 , sdPercent , 0 ) - PROPERTY(quint8 , sdIsLow , false ) + PROPERTY(bool , sdIsLow , false ) // this property will be set if the sd-card space gets lower than required amount in percent that has been defined in DeviceController. PROPERTY(qint8 , sdTooLowPecent, -1) // -1 means the event never happened // disabled coco end #ifdef BUILD_FOR_DESKTOP - PROPERTY(bool , usbReady , true ) - PROPERTY(bool , usbRemoved , false ) + PROPERTY(bool , usbIsReady , true ) + PROPERTY(bool , usbIsRemoved , false ) #else - PROPERTY(bool , usbReady , false ) - PROPERTY(bool , usbRemoved , true ) + PROPERTY(bool , usbIsReady , false ) + PROPERTY(bool , usbIsRemoved , true ) #endif + + PROPERTY(quint64, usbTotal , 0 ) + PROPERTY(quint64, usbAvail , 0 ) + PROPERTY(quint8 , usbPercent , 0 ) + PROPERTY(bool , usbIsLow , false ) + + PROPERTY(bool , exportRunning , false ) + public: explicit GuiView(QObject *parent = nullptr); @@ -80,6 +88,8 @@ void onSDCardSpaceTooLow(quint8 vAvailablePercent); void onSDCardSpaceChange(bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent); + void onUSBSpaceChange (bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent); + public slots: // is public since will be used in the UI and is in the same thread. void doActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG void doActionTransmit(GuiActionType vAction, const QVariant &vData); // UI => HD/DG Index: sources/gui/qml/SDCProgressItem.qml =================================================================== diff -u --- sources/gui/qml/SDCProgressItem.qml (revision 0) +++ sources/gui/qml/SDCProgressItem.qml (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -0,0 +1,89 @@ +/*! + * + * Copyright (c) 2021-2022 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 SDCProgressItem.qml + * \author (last) Behrouz NematiPour + * \date (last) 20-Jul-2021 + * \author (original) Behrouz NematiPour + * \date (original) 16-Apr-2021 + * + */ + +// Qt +import QtQuick 2.12 + +// Project +// C++ imports +// Qml imports +import "qrc:/globals" +import "qrc:/components" + +/*! + * \brief SDCProgressItem is the component to provide user information about the SDCard. + * \detials This item includes the space left on the device in percent as well as the ProgressCircle for a graphical representation. + * The ProgressCircle turns red if the amount of free space left is less than defined (15% for now) + * The percent value in the circle will show "SD" if the device is not present/ready. + */ +Rectangle { id: _root // TEST : SD-Card not present may need to be handled with better indication(s). + + signal clicked + signal doubleClicked + + readonly property int sizePowers : 1000000 + + readonly property alias totalText : _totalText.text + readonly property alias total : _progressCircle.maximum + readonly property alias avail : _progressCircle.value + readonly property alias percent : _percent.text + property alias thickness : _progressCircle.thickness + + property bool displayInformation : true + + enabled : _GuiView.sdIsReady + color : Colors.transparent + anchors { + top : parent.top + right : parent.right + topMargin : 5 + rightMargin : 5 + } + width : 30 + height: width + radius: width + Text { id: _percent + visible : displayInformation + anchors.centerIn: parent + color: ! _GuiView.sdIsReady ? Colors.red : _GuiView.sdIsReadOnly ? "gray" : Colors.white + text : ! _GuiView.sdIsReady ? qsTr("SD") : _GuiView.sdPercent + font.pixelSize: 12 + font.bold: true + } + ProgressCircle { id: _progressCircle + anchors.fill: parent + diameter: _root.width + minimum : 0 + maximum : _GuiView.sdTotal / sizePowers // convert to MB since the value in byte is too big for ProgressCircle. + value : _GuiView.sdAvail / sizePowers // convert to MB since the value in byte is too big for ProgressCircle. + color : ! _GuiView.sdIsReady ? "red" : _GuiView.sdIsReadOnly ? "gray" : _GuiView.sdIsLow ? Colors.red : "green" + } + Text { id: _totalText + visible : _GuiView.sdIsReady && displayInformation + anchors.top: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + color : Colors.white + text : Variables.sizeConverted( _GuiView.sdTotal, _root.sizePowers ) + font.pixelSize: 12 + font.bold: true + } + + MouseArea { id: _mouseArea + anchors.fill : parent + anchors.margins : -20 // since the object visual is so small make the mouseArea bigger for the human finger to easier touch. + onClicked : _root.clicked() + onDoubleClicked : _root.doubleClicked() + } +} Fisheye: Tag 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac refers to a dead (removed) revision in file `sources/gui/qml/SDItem.qml'. Fisheye: No comparison available. Pass `N' to diff? Index: sources/gui/qml/USBProgressItem.qml =================================================================== diff -u --- sources/gui/qml/USBProgressItem.qml (revision 0) +++ sources/gui/qml/USBProgressItem.qml (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -0,0 +1,90 @@ +/*! + * + * Copyright (c) 2021-2022 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 USBProgressItem.qml + * \author (last) Behrouz NematiPour + * \date (last) 20-Jul-2021 + * \author (original) Behrouz NematiPour + * \date (original) 16-Apr-2021 + * + */ + +// Qt +import QtQuick 2.12 + +// Project +// C++ imports +// Qml imports +import "qrc:/globals" +import "qrc:/components" + +/*! + * \brief USBProgressItem is the component to provide user information about the USB Drive. + * \detials This item includes the space left on the device in percent as well as the ProgressCircle for a graphical representation. + * The ProgressCircle turns red if the amount of free space left is less than defined (15% for now) + * The percent value in the circle will show "USB" if the device is not present/ready. + */ +Rectangle { id: _root // TEST : USB-Drive not present may need to be handled with better indication(s). + + signal clicked + signal doubleClicked + + readonly property int sizePowers : 1000000 + + readonly property alias totalText : _totalText.text + readonly property alias total : _progressCircle.maximum + readonly property alias avail : _progressCircle.value + readonly property alias percent : _percent.text + property alias thickness : _progressCircle.thickness + + property bool displayInformation : true + + enabled : _GuiView.usbIsReady + color : Colors.transparent + anchors { + top : parent.top + right : parent.right + topMargin : 5 + rightMargin : 5 + } + width : 30 + height: width + radius: width + Text { id: _percent + visible : displayInformation + anchors.centerIn: parent + color: ! _GuiView.usbIsReady ? Colors.red : Colors.white + text : ! _GuiView.usbIsReady ? qsTr("USB") : _GuiView.usbPercent + font.pixelSize: 12 + font.bold: true + } + + ProgressCircle { id: _progressCircle + anchors.fill: parent + diameter: _root.width + minimum : 0 + maximum : _GuiView.usbTotal / sizePowers // convert to MB since the value in byte is too big for ProgressCircle. + value : _GuiView.usbAvail / sizePowers // convert to MB since the value in byte is too big for ProgressCircle. + color : ! _GuiView.usbIsReady ? "red" : "green" + } + Text { id: _totalText + visible : _GuiView.usbIsReady && displayInformation + anchors.top: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + color : Colors.white + text : Variables.sizeConverted( _GuiView.usbTotal, _root.sizePowers ) + font.pixelSize: 12 + font.bold: true + } + + MouseArea { id: _mouseArea + anchors.fill : parent + anchors.margins : -20 // since the object visual is so small make the mouseArea bigger for the human finger to easier touch. + onClicked : _root.clicked() + onDoubleClicked : _root.doubleClicked() + } +} Index: sources/gui/qml/components/BackButton.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/components/BackButton.qml (.../BackButton.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/components/BackButton.qml (.../BackButton.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -30,7 +30,7 @@ anchors { top : parent.top left : parent.left - margins : 35 + margins : Variables.headerButtonsMargin } Image { id: _image Index: sources/gui/qml/components/ConfirmButton.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/components/ConfirmButton.qml (.../ConfirmButton.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/components/ConfirmButton.qml (.../ConfirmButton.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -33,6 +33,6 @@ anchors { top : parent.top right : parent.right - margins : 35 + margins : Variables.headerButtonsMargin } } Index: sources/gui/qml/components/ExportButton.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/components/ExportButton.qml (.../ExportButton.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/components/ExportButton.qml (.../ExportButton.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -21,30 +21,25 @@ import "qrc:/components" TouchRect { id : _root - width : 155 - height : 50 - property var exportFunction : null + property bool isSmall: false - anchors.margins: 35 + property bool disabled : false + width : isSmall ? 155 : Variables.touchRectWidth + height : isSmall ? 50 : Variables.touchRectHeight + + anchors.margins: 35 text { text: qsTr("Export") - font.pixelSize: Fonts.fontPixelButton * 0.75 + font.pixelSize: Fonts.fontPixelButton * (isSmall ? 0.75 : 1) } - onClicked: { - if ( exportFunction instanceof Function ) { - exportFunction() - } else { - _GuiView.doExportLog() - } - } Connections { target: _GuiView onDidUSBDriveUmount : _root.enabled = false onDidUSBDriveRemove : _root.enabled = false - onDidUSBDriveMount : _root.enabled = true + onDidUSBDriveMount : _root.enabled = true && ! disabled onDidExportLog : _root.enabled = false - onDidExport : _root.enabled = true + onDidExport : _root.enabled = true && ! disabled } } Index: sources/gui/qml/components/StackItem.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/components/StackItem.qml (.../StackItem.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/components/StackItem.qml (.../StackItem.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -112,8 +112,7 @@ */ function reset() { stackView.clear() - stackView.push(stackView.initialItem) - info() + push(stackView.initialItem) } StackView { id : _stackView Index: sources/gui/qml/components/USBButton.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/components/USBButton.qml (.../USBButton.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/components/USBButton.qml (.../USBButton.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -35,9 +35,10 @@ _GuiView.doUSBDriveUmount() } - fading: ! _GuiView.usbReady && ! _GuiView.usbRemoved + fading: ! _GuiView.usbIsReady && ! _GuiView.usbIsRemoved Connections { target: _GuiView + onDidUSBDriveUmount : _root.enabled = false onDidUSBDriveRemove : _root.enabled = false onDidUSBDriveMount : _root.enabled = true onDidExportLog : _root.enabled = false Index: sources/gui/qml/compounds/InstructionView.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/compounds/InstructionView.qml (.../InstructionView.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/compounds/InstructionView.qml (.../InstructionView.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -71,8 +71,8 @@ } radius : _root.innerRadius // DEBUG : This helps getting the final size of the available room for the instruction images. - // onWidthChanged : console.debug( " ----- ", "_innerFrame.width :" , width , label) - // onHeightChanged : console.debug( " ----- ", "_innerFrame.height:" , height, label) + // onWidthChanged : console.debug( " ----- ", "_innerFrame.width :" , label, width ) + // onHeightChanged : console.debug( " ----- ", "_innerFrame.height:" , label, height) } Item { id: _containerSwipeView Index: sources/gui/qml/compounds/TouchGrid.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/compounds/TouchGrid.qml (.../TouchGrid.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/compounds/TouchGrid.qml (.../TouchGrid.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -64,6 +64,7 @@ return vValue } + // DEBUG: Rectangle { anchors.fill: _grid } Grid { id: _grid flow: Grid.TopToBottom anchors.centerIn: _root.alignCenter ? parent : undefined Index: sources/gui/qml/dialogs/NotificationDialog.qml =================================================================== diff -u -r301c0a2101eb9374145ae274c8d91460fc9a6a62 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/dialogs/NotificationDialog.qml (.../NotificationDialog.qml) (revision 301c0a2101eb9374145ae274c8d91460fc9a6a62) +++ sources/gui/qml/dialogs/NotificationDialog.qml (.../NotificationDialog.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -139,7 +139,7 @@ MouseArea { anchors.fill: _icon onClicked : if ( _minimizeArea.enabled ) _root.minimizeClicked() - onDoubleClicked : _sdItem.doubleClicked() + onDoubleClicked : _sdcProgressItem.doubleClicked() } } Index: sources/gui/qml/globals/Variables.qml =================================================================== diff -u -r7e503c5459ec77a2816d6c7789da9b206cedbe8a -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/globals/Variables.qml (.../Variables.qml) (revision 7e503c5459ec77a2816d6c7789da9b206cedbe8a) +++ sources/gui/qml/globals/Variables.qml (.../Variables.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -32,6 +32,7 @@ readonly property int dialogIconWidth : 50 readonly property int dialogIconHorizontalOffset : 25 readonly property int headerHeight : 100 + readonly property int headerButtonsMargin : 35 readonly property int mainMenuHeight : 70 @@ -139,6 +140,10 @@ readonly property int settingsInputWidth : 225 readonly property int settingsNotificationMargin : 10 + readonly property int settingsContentSidesMargin : Variables.headerButtonsMargin + readonly property int settingsContentBottomMargin : Variables.mainMenuHeight + // Alarm Bar height + Variables.notificationHeight + // notification Bar height + Variables.minVGap // Min Gap to give content the min border readonly property int settingsOptionWidth : 550 readonly property int settingsOptionHeight : 50 @@ -192,6 +197,13 @@ readonly property int venousLimitStep : +10; ///< PRS356,PRS357 // has to be the same since it's on the same line scale readonly property int venousLimitGap : +30; + function sizeConverted(vSize, vSizePowers, vRound = 2) { + return ( vSize + / vSizePowers // convert from byte to Giga byte + / 1000) // round to 1000 + .toFixed(vRound) // round to 1 floating point + } + function notSetVariable(vVariable, vLength, vChar) { let notSetVariableText = "_" //"‑" //"-" if (vLength === 0 ) notSetVariableText = "" Index: sources/gui/qml/main.qml =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/main.qml (.../main.qml) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/gui/qml/main.qml (.../main.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -236,6 +236,10 @@ // 3 - Footer MainMenu { id: _mainMenu + function isTreatment () { _mainMenu.itemPressed(0) } + function isManager () { _mainMenu.itemPressed(1) } + function isSettings () { _mainMenu.itemPressed(2) } + hidden: true // it should be hidden by default since the landing screen changed to init and it does not have the main menu untill the POST passes. titles: [ qsTr("Treatment") , qsTr("Manager") , qsTr("Settings") ] Component.onCompleted: { @@ -311,7 +315,7 @@ anchors { top : parent.top left : parent.left - leftMargin : 1090 + leftMargin : 1080 } horizontalAlignment : Text.Alignleft verticalAlignment : Text.AlignBottom @@ -337,7 +341,7 @@ } - SDItem { id: _sdItem + SDCProgressItem { id: _sdcProgressItem // TODO: disable this later. this is only for diagnostic purpose. onDoubleClicked : { _diagnosticsDialog.open() Index: sources/gui/qml/pages/MainStack.qml =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/MainStack.qml (.../MainStack.qml) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/gui/qml/pages/MainStack.qml (.../MainStack.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -74,10 +74,7 @@ } ScreenItem { id: _initialModeScreen - onVisibleChanged: - if (visible) { - _mainMenu.hidden = true - } + onVisibleChanged: if (visible) _mainMenu.hidden = true Image { id: _dialityLogo Behavior on opacity { OpacityAnimator { duration: 1000 } } opacity : _initialModeScreen.visible ? 1 : 0 @@ -128,9 +125,13 @@ } Connections { target: vHDOperationMode - // onFaultChanged : { page( _faultModeScreen , vfault )} // may needed later. + onIsTreatmentChanged : { if( visTreatment ) _mainMenu.isTreatment() } + onIsManagerChanged : { if( visManager ) _mainMenu.isManager () } + onIsSettingsChanged : { if( visSettings ) _mainMenu.isSettings () } + + onFaultChanged : { page( _faultModeScreen , vfault )} // may needed later. onServiceChanged : { page( _serviceModeScreen , vservice )} - onInitChanged : { page( _root.initialItem , vinit ) + onInitChanged : { page( _initialModeScreen , vinit ) if ( vinit ) vHDPOSTData.reset() // better to reset on vinit = true because the rest makes the screen animation to run } Index: sources/gui/qml/pages/TreatmentFlowBase.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/TreatmentFlowBase.qml (.../TreatmentFlowBase.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/pages/TreatmentFlowBase.qml (.../TreatmentFlowBase.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -28,6 +28,7 @@ ScreenItem { id: _root objectName: "_TreatmentFlowBase" + property alias informationText : _information.text property alias reasonText : _notification.text property alias header : _titleBar property alias title : _titleText @@ -38,6 +39,7 @@ property string instructionlocation : "" property var instructionStepNames : [] property var instructionStepImages : [] + readonly property bool instructionIsLast: instruction ? instruction.lastStep : true property bool hasTimeCircle : false readonly property alias timeCircle : _timeCircleLoader.item @@ -154,6 +156,14 @@ Footer { id: _footer } + NotificationBarSmall { id: _information + visible : text + color : Colors.transparent + textColor : Colors.white + imageSource : "" + text : "" + } + NotificationBar { id: _notification iconVisible: false } Index: sources/gui/qml/pages/UserConfirmation.qml =================================================================== diff -u -r7e503c5459ec77a2816d6c7789da9b206cedbe8a -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/UserConfirmation.qml (.../UserConfirmation.qml) (revision 7e503c5459ec77a2816d6c7789da9b206cedbe8a) +++ sources/gui/qml/pages/UserConfirmation.qml (.../UserConfirmation.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -62,6 +62,7 @@ MouseArea { anchors.fill: _showPassword + anchors.margins: -20 onPressed : _password.textInput.echoMode = TextInput.Normal onReleased : _password.textInput.echoMode = TextInput.Password } Index: sources/gui/qml/pages/endtreatment/rinseback/EndTreatmentRinsebackComplete.qml =================================================================== diff -u -r301c0a2101eb9374145ae274c8d91460fc9a6a62 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/endtreatment/rinseback/EndTreatmentRinsebackComplete.qml (.../EndTreatmentRinsebackComplete.qml) (revision 301c0a2101eb9374145ae274c8d91460fc9a6a62) +++ sources/gui/qml/pages/endtreatment/rinseback/EndTreatmentRinsebackComplete.qml (.../EndTreatmentRinsebackComplete.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -35,7 +35,7 @@ title.text : qsTr("Rinseback Complete") instructionBased : true header.confirmVisible : vTreatmentTime .time_IsLeft - header.confirmEnabled : vTreatmentRinseback .isCompleted + header.confirmEnabled : vTreatmentRinseback .isCompleted && _root.instructionIsLast hasTimeout : vTreatmentRinseback .timeoutTotal timeoutValue : vTreatmentRinseback .timeoutCountDown * 60 Index: sources/gui/qml/pages/posttreatment/PostTreatmentReview.qml =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/posttreatment/PostTreatmentReview.qml (.../PostTreatmentReview.qml) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/gui/qml/pages/posttreatment/PostTreatmentReview.qml (.../PostTreatmentReview.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -37,10 +37,11 @@ header.confirmText.text: qsTr("NEXT") ExportButton { id: _exportButton + isSmall : true anchors.top : parent.top anchors.left : parent.left - exportFunction : vPostTreatmentAdjustmentTreatmentLog.doExport - enabled : vPostTreatmentAdjustmentTreatmentLog.isIdle && _GuiView.usbReady + enabled : vPostTreatmentAdjustmentTreatmentLog.isIdle && _GuiView.usbIsReady + onClicked : vPostTreatmentAdjustmentTreatmentLog.doExport() } USBButton { id: _usbButton anchors.top : _exportButton.top @@ -109,6 +110,7 @@ onItemClicked: _root.itemClicked(vIndex) } } - reasonText: vPostTreatmentAdjustmentTreatmentLog.text() + reasonText : vPostTreatmentAdjustmentTreatmentLog.text() + informationText : vPostTreatmentAdjustmentTreatmentLog.notification } Index: sources/gui/qml/pages/pretreatment/create/PreTreatmentCreateStack.qml =================================================================== diff -u -r7e503c5459ec77a2816d6c7789da9b206cedbe8a -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/pretreatment/create/PreTreatmentCreateStack.qml (.../PreTreatmentCreateStack.qml) (revision 7e503c5459ec77a2816d6c7789da9b206cedbe8a) +++ sources/gui/qml/pages/pretreatment/create/PreTreatmentCreateStack.qml (.../PreTreatmentCreateStack.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -40,7 +40,10 @@ } function pagePatientID( vCondition ) { - if ( vCondition !== undefined && vCondition === false ) return + if ( vCondition !== undefined && vCondition === false ) { + _keyboard.setVisible(false) + return + } patientID = "" page( _pretreatmentPatientID ) Index: sources/gui/qml/pages/settings/SettingsBase.qml =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/settings/SettingsBase.qml (.../SettingsBase.qml) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/gui/qml/pages/settings/SettingsBase.qml (.../SettingsBase.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -35,6 +35,9 @@ property int topMarginTitle : 100 property int topMarginContent : 200 + property int bottomMarginContent : Variables.settingsContentBottomMargin + property int sidesMarginContent : Variables.settingsContentSidesMargin + property int itemIndex : 0 property alias title : _titleText.text Index: sources/gui/qml/pages/settings/SettingsExportLogs.qml =================================================================== diff -u --- sources/gui/qml/pages/settings/SettingsExportLogs.qml (revision 0) +++ sources/gui/qml/pages/settings/SettingsExportLogs.qml (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -0,0 +1,351 @@ +/*! + * + * Copyright (c) 2021-2022 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 SettingsVolumeBrightness.qml + * \author (last) Behrouz NematiPour + * \date (last) 07-Jun-2021 + * \author (original) Behrouz NematiPour + * \date (original) 06-Jun-2021 + * + */ + +// Qt +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import Qt.labs.folderlistmodel 2.12 + + +// TODO: Add the fileCopy function to have control over the copy +// TODO: Add cancel +// TODO: Add Service and Treatment log export and filter +// TODO: Add selecction export +// TODO: Add error display + +// Project +import Gui.Actions 0.1 + +// Qml imports +import "qrc:/" +import "qrc:/globals" +import "qrc:/components" + +/*! + * \brief SettingsExportLogs is used to Export logs, and display the SD-Card and USB device informaiton and list of files. + */ +SettingsBase { id: _root + itemIndex : SettingsStack.ExportLogs + confirmVisible : false + + USBButton { id: _usbEjectButton + width : 155 + height : 50 + anchors.right : _root.right + anchors.top : _root.top + anchors.margins : Variables.headerButtonsMargin + } + + Row { id : _contentRect + spacing : Variables.minVGap + anchors.fill : parent + anchors.topMargin : parent. topMarginContent - 25 // move 25 up + anchors.bottomMargin : parent.bottomMarginContent + anchors.rightMargin : parent. sidesMarginContent + anchors.leftMargin : parent. sidesMarginContent + anchors.horizontalCenter : parent.horizontalCenter + + readonly property int columnWidthProgress : 350 + readonly property int columnWidthFolder : 420 + readonly property int columnWidthFileName : 285 // 285 best combination + readonly property int columnWidthFileSize : 105 // 105 best combination + + Column { id : _progressColumn + property int progressWidth : 125 + property int progressHeight : height - _logTypeCombo.height - _logTypeExportButton.height + + spacing : 10 + width : _contentRect.columnWidthProgress + height : parent.height + anchors.verticalCenter : parent.verticalCenter + + Row { id : _logTypeRow + anchors.left : parent.left + width : parent.width + height : 50 + spacing : _logTypeCombo.width - _logTypeExportButton.width + + // FIXME: This combobox needs to be a global Component + ComboBox { id : _logTypeCombo + currentIndex : 0 + displayText : currentText + font.pixelSize : Fonts.fontPixelTextRectExtra + width : parent.width // 2 + height : parent.height + padding : 10 + model : [ + qsTr("Application" ), + qsTr("Service" ), + qsTr("Treatment" ) + ] + + background : Rectangle { + color : Colors.transparent + border.color : Colors.borderButton + radius : Variables.dialogRadius + } + + delegate: ItemDelegate { id : _logTypeDelegate + width : _logTypeCombo.width // + anchors.margins - 2 // 2 is the border width + height : 50 + contentItem: Text { + text : modelData + color : Colors.textMain + font : _logTypeCombo.font + padding : 10 + verticalAlignment : Text.AlignVCenter + } + background : Rectangle { + anchors.fill : parent + anchors.margins : 10 / 2 + visible : _logTypeDelegate.down || _logTypeDelegate.highlighted || _logTypeDelegate.visualFocus + color : _logTypeDelegate.down ? Colors.backgroundButtonSelect : + Colors.backgroundButtonSelectDark + } + highlighted : _logTypeCombo.highlightedIndex === index + } + popup: Popup { + y : _logTypeCombo.height + x : - _logTypeCombo.anchors.leftMargin + width : _logTypeCombo.width + _logTypeCombo.anchors.leftMargin + implicitHeight : contentItem.implicitHeight + contentItem : ListView { + clip : true + implicitHeight : contentHeight + currentIndex : _logTypeCombo.highlightedIndex + model : _logTypeCombo.popup.visible ? _logTypeCombo.delegateModel : null + } + background: Rectangle { + color : Colors.backgroundMain + border.color : Colors.borderButton + radius : Variables.dialogRadius + } + } + } + } + Column { + width : _progressColumn.progressWidth + height : _progressColumn.progressHeight - 2 * _progressColumn.spacing + Item { id : _SDC_item + width : _progressColumn.progressWidth + height : parent.height / 2 + + SDCProgressItem { id: _SDC_progressItem + thickness : 2 + displayInformation : false + anchors.fill : parent + } + Label { + anchors.left : _SDC_progressItem.right + anchors.leftMargin : _progressColumn.spacing + anchors.verticalCenter : parent.verticalCenter + text : qsTr("SD-Card") + " (MB)\n" + ("Free : %1\nTotal: %2").arg( Variables.sizeConverted( _GuiView.sdAvail, 1000, 3) ).arg( Variables.sizeConverted( _GuiView.sdTotal, 1000, 3) ) + } + Label { + anchors.fill : parent + verticalAlignment : Text.AlignVCenter + horizontalAlignment : Text.AlignHCenter + text : _SDC_progressItem.percent + } + } + Item { id : _USB_item + width : _progressColumn.progressWidth + height : parent.height / 2 + + USBProgressItem { id: _USB_progressItem + thickness : 2 + displayInformation : false + anchors.fill : parent + } + Label { + anchors.left : _USB_progressItem.right + anchors.leftMargin : _progressColumn.spacing + anchors.verticalCenter : parent.verticalCenter + text : qsTr("USB Drive") + " (MB)\n" + ("Free : %1\nTotal: %2").arg( Variables.sizeConverted( _GuiView.usbAvail, 1000, 3) ).arg( Variables.sizeConverted( _GuiView.usbTotal, 1000, 3) ) + } + Label { + anchors.fill : parent + verticalAlignment : Text.AlignVCenter + horizontalAlignment : Text.AlignHCenter + text : _USB_progressItem.percent + } + } + } + ExportButton { id : _logTypeExportButton + width : parent.width + height : Variables.touchRectHeight + radius : Variables.touchRectRadius + border.width : Variables.borderWidth + onClicked : _GuiView.doExportLog() + } + + } + Column { id : _sdcFolderColumn + spacing : 5 + width : _contentRect.columnWidthFolder + height : parent.height + anchors.verticalCenter : parent.verticalCenter + + Rectangle { id : _sdcFolderRectangle + color : Colors.transparent + border.color : Colors.borderButton + radius : Variables.dialogRadius + anchors.left : parent.left + width : parent.width + height : parent.height + + ScrollBar { + anchors.fill : _sdcFolderView + flickable : _sdcFolderView + } + + ListView { id : _sdcFolderView + clip : true + anchors.fill : parent + anchors.margins : 10 + spacing : 5 + FolderListModel { id : _sdcFolderModel + showDirs : false + sortField : FolderListModel.Time + folder : "file:///media/sd-card/log" // FIXME: ther has to be a View for this which also get changed by log type. + nameFilters : ["*.log"] // FIXME: ther has to be a View for this which also get changed by log type. + } + Component { id : _sdcFileDelegate + Row { id : _sdcFileRow + width : parent.width + height : 40 + Text { id : _sdcFileNameText + width : _contentRect.columnWidthFileName + text : fileName + color : Colors.textMain + font.pixelSize : Fonts.fontPixelTextRectExtra + verticalAlignment : Text.AlignVCenter + horizontalAlignment : Text.AlignLeft + } + Rectangle { + color: Colors.borderButtonUnselected + width : 1 + height : parent.height + _usbFolderColumn.spacing + } + Text { id : _sdcFileSizeText + width : _contentRect.columnWidthFileSize + text : Variables.sizeConverted( fileSize, 1000, 3) + color : Colors.textMain + font.pixelSize : Fonts.fontPixelTextRectExtra + verticalAlignment : Text.AlignVCenter + horizontalAlignment : Text.AlignRight + } + } + } + model : _sdcFolderModel + delegate : _sdcFileDelegate + } + } + } + + Column { id : _usbFolderColumn + // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there. + function updateModel() { + _usbFolderModel.folder = "file:///media/usb/log" // FIXME: there has to be a View for this which also get changed by log type. + _usbFolderModel.nameFilters = ["*.log"] // FIXME: there has to be a View for this which also get changed by log type. + } + function clearModel() { + _usbFolderModel.folder = "" + _usbFolderModel.nameFilters = [] + } + + // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there. + Timer { id: _usbUpdate + interval : 500 + repeat : true + running : _GuiView.exportRunning + onTriggered : { + _usbFolderColumn. clearModel() + _usbFolderColumn.updateModel() + console.debug("Updating usb") + } + } + + Connections { target: _GuiView + onDidUSBDriveUmount : _usbFolderColumn. clearModel() + onDidUSBDriveRemove : _usbFolderColumn. clearModel() + onDidExportLog : _usbFolderColumn. clearModel() + onDidUSBDriveMount : _usbFolderColumn.updateModel() + onDidExport : _usbFolderColumn.updateModel() + } + + spacing : 5 + width : _contentRect.columnWidthFolder + height : parent.height + anchors.verticalCenter : parent.verticalCenter + + Rectangle { id : _usbFolderRectangle + color : Colors.transparent + border.color : Colors.borderButton + radius : Variables.dialogRadius + anchors.left : parent.left + width : parent.width + height : parent.height + + ScrollBar { + anchors.fill : _usbFolderView + flickable : _usbFolderView + } + + ListView { id : _usbFolderView + clip : true + anchors.fill : parent + anchors.margins : 10 + spacing : 5 + FolderListModel { id : _usbFolderModel // FIXME: I don't like this model, it's too lazy and I don't have control over it. There has to be a Model for this. + showDirs : false + sortField : FolderListModel.Time + folder : "file:///media/usb" + nameFilters : ["*"] + } + Component { id : _usbFileDelegate + Row { id : _usbFileRow + width : parent.width + height : 40 + Text { id : _usbFileNameText + width : _contentRect.columnWidthFileName + text : fileName + color : Colors.textMain + font.pixelSize : Fonts.fontPixelTextRectExtra + verticalAlignment : Text.AlignVCenter + horizontalAlignment : Text.AlignLeft + } + Rectangle { + color: Colors.borderButtonUnselected + width: 1 + height: parent.height + _usbFolderColumn.spacing + } + Text { id : _usbFileSizeText + width : _contentRect.columnWidthFileSize + text : Variables.sizeConverted( fileSize, 1000, 3) + color : Colors.textMain + font.pixelSize : Fonts.fontPixelTextRectExtra + verticalAlignment : Text.AlignVCenter + horizontalAlignment : Text.AlignRight + } + } + } + model : _usbFolderModel + delegate : _usbFileDelegate + } + } + } + } +} Index: sources/gui/qml/pages/settings/SettingsHome.qml =================================================================== diff -u -r7e503c5459ec77a2816d6c7789da9b206cedbe8a -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/settings/SettingsHome.qml (.../SettingsHome.qml) (revision 7e503c5459ec77a2816d6c7789da9b206cedbe8a) +++ sources/gui/qml/pages/settings/SettingsHome.qml (.../SettingsHome.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -61,8 +61,6 @@ text.text: qsTr("Clear Alarm Condition") onClicked: _alarmItem.clearAlarm() } - USBButton { id: _usbButton } - ExportButton { id: _exportButton } } // The Main menu need to hide in case we have any alarm, if not the menu is covered by keyboard but the alram does not. Index: sources/gui/qml/pages/settings/SettingsStack.qml =================================================================== diff -u -r2d0bacfbe1b70055247eb40743405a5f9acb15e3 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/gui/qml/pages/settings/SettingsStack.qml (.../SettingsStack.qml) (revision 2d0bacfbe1b70055247eb40743405a5f9acb15e3) +++ sources/gui/qml/pages/settings/SettingsStack.qml (.../SettingsStack.qml) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -14,12 +14,13 @@ */ // Qt -import QtQuick 2.12 +import QtQuick 2.12 // Project import Gui.Actions 0.1 // Qml imports +import "qrc:/" import "qrc:/globals" import "qrc:/components" import "qrc:/compounds" @@ -46,6 +47,7 @@ DGSettings , Services , SetDateTime , + ExportLogs , Language , Calibration , SWUpdate , @@ -59,6 +61,7 @@ qsTr("DG Cleaning" ), // DGSettings qsTr("Service" ), // Service qsTr("Set Date And Time" ), // SetDateTime + qsTr("Export Logs" ), // ExportLogs qsTr("Set Language" ), // Language qsTr("Calibration " ), // Calibration qsTr("Software Update" ), // SWUpdate @@ -72,6 +75,7 @@ true , // DGSettings true , // Services true , // SetDateTime + true , // ExportLogs false , // Language false , // Calibration false , // SWUpdate @@ -85,12 +89,69 @@ true , // DGSettings ! serviceMode , // Services serviceMode , // SetDateTime + true , // ExportLogs false /* serviceMode phase 1 */ , // Language false /* serviceMode phase 1 */ , // Calibration false /* serviceMode phase 1 */ , // SWUpdate false /* serviceMode phase 1 */ , // FactoryReset ] + SettingsHome { id : _settingsHome + title : serviceMode ? qsTr("Service") : qsTr("Device Settings") + backVisible : false + confirmVisible : serviceMode + confirmText.text: qsTr("SHUTDOWN") + onConfirmClicked: _GuiView.doActionTransmit(GuiActions.ID_PowerOff, GuiActions.NoData) + itemsText : _root.itemsText + itemsEnabled : _root.itemsEnabled + itemsVisible : _root.itemsVisible + onItemClicked : { + switch (vIndex) { + case SettingsStack.Information: + push(_settingsInformation) + break + + case SettingsStack.VolumeBrightness: + vDevice.doInitBrightness() + push(_settingsVolumeBrightness) + break + + case SettingsStack.WiFi: + vNetwork.doInit() + push( _settingsWiFi ) + // _settingsWiFi.setFocus() // No keyboard popup. + break + + case SettingsStack.Bluetooth: + push( _settingsBluetooth ) + break + + case SettingsStack.DGSettings: + push( _settingsDGSettings ) + break + + case SettingsStack.Services: + push(_servicePassword) + _servicePassword.setFocus() + break + + case SettingsStack.SetDateTime: + vDateTime.doInit() + push( _settingsDateTime ) + _settingsDateTime.setFocus() + break + + case SettingsStack.ExportLogs: + push( _settingsExportLogs ) + break + + default: + console.debug("Unknown Index", vIndex) + break + } + } + } + SettingsBase { id: _settingsInformation itemIndex : SettingsStack.Information confirmVisible : false @@ -153,24 +214,28 @@ } SettingsVolumeBrightness { id: _settingsVolumeBrightness - itemIndex : SettingsStack.VolumeBrightness + itemIndex : SettingsStack.VolumeBrightness } SettingsDateTime { id: _settingsDateTime - itemIndex : SettingsStack.SetDateTime + itemIndex : SettingsStack.SetDateTime } SettingsWiFi { id: _settingsWiFi - itemIndex : SettingsStack.WiFi + itemIndex : SettingsStack.WiFi } SettingsBluetoothCuff { id: _settingsBluetooth } SettingsDG { id: _settingsDGSettings - itemIndex : SettingsStack.DGSettings + itemIndex : SettingsStack.DGSettings } + SettingsExportLogs { id: _settingsExportLogs + itemIndex : SettingsStack.ExportLogs + } + UserConfirmation { id: _servicePassword itemIndex : SettingsStack.Services title : qsTr("Service Password") @@ -197,73 +262,27 @@ } } - SettingsHome { id : _settingsHome - title : serviceMode ? qsTr("Service") : qsTr("Device Settings") - backVisible : false - confirmVisible : serviceMode - confirmText.text: qsTr("SHUTDOWN") - onConfirmClicked: _GuiView.doActionTransmit(GuiActions.ID_PowerOff, GuiActions.NoData) - itemsText : _root.itemsText - itemsEnabled : _root.itemsEnabled - itemsVisible : _root.itemsVisible - onItemClicked : { - switch (vIndex) { - case SettingsStack.Information: - push(_settingsInformation) - break - - case SettingsStack.VolumeBrightness: - vDevice.doInitBrightness() - push(_settingsVolumeBrightness) - break - - case SettingsStack.SetDateTime: - vDateTime.doInit() - push( _settingsDateTime ) - _settingsDateTime.setFocus() - break - - case SettingsStack.WiFi: - vNetwork.doInit() - push( _settingsWiFi ) - // _settingsWiFi.setFocus() // No keyboard popup. - break - - case SettingsStack.Bluetooth: - push( _settingsBluetooth ) - break - - case SettingsStack.DGSettings: - push( _settingsDGSettings ) - break - - case SettingsStack.Services: - push(_servicePassword) - _servicePassword.setFocus() - break - - default: - console.debug("Unknown Index", vIndex) - break - } - } - } - Connections { target: vAdjustmentServiceMode onAdjustmentTriggered : { if ( vAdjustmentServiceMode.adjustment_Accepted ) { - _settingsHome.notificationText = "" - serviceMode = true + _settingsHome.notificationText = "" } else { _settingsHome.notificationText = vAdjustmentServiceMode.text() } } } + Connections { target: vHDOperationMode + onServiceChanged : { push( _settingsHome , vservice ) + serviceMode = vservice + _mainMenu.hidden = vservice + } + } + onVisibleChanged: { if (visible) { - _mainMenu.hidden = false + _mainMenu.hidden = serviceMode } else { stackView.initialItem = null Index: sources/model/dg/adjustment/settings/MAdjustDGVersionsResponse.h =================================================================== diff -u -r301c0a2101eb9374145ae274c8d91460fc9a6a62 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/model/dg/adjustment/settings/MAdjustDGVersionsResponse.h (.../MAdjustDGVersionsResponse.h) (revision 301c0a2101eb9374145ae274c8d91460fc9a6a62) +++ sources/model/dg/adjustment/settings/MAdjustDGVersionsResponse.h (.../MAdjustDGVersionsResponse.h) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -78,9 +78,9 @@ public: - Type_Enum typeText () const override { return Type_Enum::eEvent ; } - Unit_Enum unitText () const override { return Unit_Enum::eDG ; } - QString infoText () const override { return QString("Version") ; } + Type_Enum typeText () const override { return Type_Enum::eEvent ; } + Unit_Enum unitText () const override { return Unit_Enum::eDG ; } + QString infoText () const override { return QString("VersionRsp") ; } struct Data { quint8 mMajor = 0; /*!< DG Versions Major value of type quint8 extracted out */ Index: sources/model/hd/alarm/MAlarmMapping.cpp =================================================================== diff -u -r13a271ff9262b297f76fa2f97110ff5e0f3f1e1b -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/model/hd/alarm/MAlarmMapping.cpp (.../MAlarmMapping.cpp) (revision 13a271ff9262b297f76fa2f97110ff5e0f3f1e1b) +++ sources/model/hd/alarm/MAlarmMapping.cpp (.../MAlarmMapping.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -7,7 +7,7 @@ * * \file MAlarmMapping.cpp * \author (last) Behrouz NematiPour - * \date (last) 22-Jun-2022 + * \date (last) 27-Jun-2022 * \author (original) Behrouz NematiPour * \date (original) 03-May-2021 * @@ -76,7 +76,7 @@ /*0040*/case GuiAlarmID::ALARM_ID_DIAL_OUT_PUMP_OFF_CHECK : { result = QObject::tr("Dialysis outlet pump failed motor off check.\nMeasured speed while commanded off." ); break; } /* 40*/ /*0041*/case GuiAlarmID::ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK : { result = QObject::tr("Dialysis outlet pump failed motor direction check.\nMeasured vs commanded." ); break; } /* 41*/ /*0042*/case GuiAlarmID::ALARM_ID_DIAL_OUT_PUMP_ROTOR_SPEED_CHECK : { result = QObject::tr("Dialysis outlet pump failed rotor speed check.\nMismatch with rotor and motor speeds." ); break; } /* 42*/ -/*0043*/case GuiAlarmID::ALARM_ID__AVAILABLE_3 : { result = QObject::tr("Alarm ID available for use." ); break; } /* 43*/ +/*0043*/case GuiAlarmID::ALARM_ID_HD_BLOOD_LEAK_SELF_TEST_FAULT : { result = QObject::tr("HD blood leak self test fault." ); break; } /* 43*/ /*0044*/case GuiAlarmID::ALARM_ID_UI_COMM_TIMEOUT : { result = QObject::tr("User interface communication timeout." ); break; } /* 44*/ /*0045*/case GuiAlarmID::ALARM_ID_HD_COMM_TOO_MANY_BAD_CRCS : { result = QObject::tr("HD too many bad communications CRC." ); break; } /* 45*/ /*0046*/case GuiAlarmID::ALARM_ID_CAN_MESSAGE_NOT_ACKED : { result = QObject::tr("System message that required acknowledgment was not acknowledged." ); break; } /* 46*/ @@ -107,7 +107,7 @@ /*0071*/case GuiAlarmID::ALARM_ID_HD_VENOUS_PRESSURE_SELF_TEST_FAILURE : { result = QObject::tr("HD venous pressure self-test failure alarm." ); break; } /* 71*/ /*0072*/case GuiAlarmID::ALARM_ID_HD_BLOOD_FLOW_STATUS_SELF_TEST_FAILURE : { result = QObject::tr("HD blood flow meter status check self-test failure alarm." ); break; } /* 72*/ /*0073*/case GuiAlarmID::ALARM_ID_HD_DIALYSATE_FLOW_STATUS_SELF_TEST_FAILURE : { result = QObject::tr("HD dialysate flow meter status check self-test failure alarm." ); break; } /* 73*/ -/*0074*/case GuiAlarmID::ALARM_ID_HD_BLOOD_LEAK_SELF_TEST_FAILURE : { result = QObject::tr("HD blood leak detector self-test failure alarm." ); break; } /* 74*/ +/*0074*/case GuiAlarmID::ALARM_ID_HD_BLOOD_LEAK_SELF_TEST_SEND_TIMEOUT : { result = QObject::tr("HD blood leak detector self-test transmit timeout." ); break; } /* 74*/ /*0075*/case GuiAlarmID::ALARM_ID_HD_SYRINGE_PUMP_SELF_TEST_FAILURE : { result = QObject::tr("HD syringe pump self-test failure alarm." ); break; } /* 75*/ /*0076*/case GuiAlarmID::ALARM_ID_HD_VOLTAGE_OUT_OF_RANGE : { result = QObject::tr("HD monitored voltage is out of range." ); break; } /* 76*/ /*0077*/case GuiAlarmID::ALARM_ID_DG_VOLTAGE_OUT_OF_RANGE : { result = QObject::tr("DG monitored voltage is out of range." ); break; } /* 77*/ @@ -145,8 +145,8 @@ /*0109*/case GuiAlarmID::ALARM_ID_HD_SYRINGE_PUMP_VOLUME_ERROR : { result = QObject::tr("HD syringe pump volume check error." ); break; } /* 109*/ /*0110*/case GuiAlarmID::ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR : { result = QObject::tr("HD syringe pump speed check error." ); break; } /* 110*/ /*0111*/case GuiAlarmID::ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR : { result = QObject::tr("HD syringe pump not stopped in off state error." ); break; } /* 111*/ -/*0112*/case GuiAlarmID::ALARM_ID_HD_BLOOD_LEAK_ZERO_CMD_TIMEOUT : { result = QObject::tr("HD blood leak zero command timeout." ); break; } /* 112*/ -/*0113*/case GuiAlarmID::ALARM_ID__AVAILABLE_4 : { result = QObject::tr("Unused." ); break; } /* 113*/ +/*0112*/case GuiAlarmID::ALARM_ID_HD_BLOOD_LEAK_ZERO_CMD_SEND_TIMEOUT : { result = QObject::tr("HD blood leak zero command transmit timeout." ); break; } /* 112*/ +/*0113*/case GuiAlarmID::ALARM_ID_HD_BLOOD_LEAK_ZERO_CMD_FAULT : { result = QObject::tr("HD blood leak zero command fault." ); break; } /* 113*/ /*0114*/case GuiAlarmID::ALARM_ID_HD_VENOUS_BUBBLE_SELF_TEST_FAILURE : { result = QObject::tr("HD venous air bubble detector self-test failure." ); break; } /* 114*/ /*0115*/case GuiAlarmID::ALARM_ID_DG_TEMPERATURE_SENSOR_OUT_OF_RANGE : { result = QObject::tr("DG temperature sensor out of range." ); break; } /* 115*/ /*0116*/case GuiAlarmID::ALARM_ID_DG_TEMPERATURE_SENSOR_ADC_OUT_OF_RANGE : { result = QObject::tr("DG temperature sensor ADC out of range." ); break; } /* 116*/ @@ -321,7 +321,7 @@ /*0285*/case GuiAlarmID::ALARM_ID_HD_TREATMENT_RECIRC_TIMEOUT_WARNING : { result = QObject::tr("HD treatment recirculate timeout warning." ); break; } /* 285*/ /*0286*/case GuiAlarmID::ALARM_ID_HD_TREATMENT_RINSEBACK_TIMEOUT_WARNING : { result = QObject::tr("HD treatment rinseback complete timeout warning." ); break; } /* 286*/ /*0287*/case GuiAlarmID::ALARM_ID_HD_FPGA_CLOCK_SPEED_CHECK_FAILURE : { result = QObject::tr("HD processor clock speed checks against FPGA clock failure." ); break; } /* 287*/ -/*0288*/case GuiAlarmID::ALARM_ID__AVAILABLE_9 : { result = QObject::tr("Alarm ID available for use." ); break; } /* 288*/ +/*0288*/case GuiAlarmID::ALARM_ID_HD_LOAD_CELL_PRIMARY_BACKUP_DRIFT_OUT_OF_RANGE : { result = QObject::tr("HD load cells primary/back up drift out of range." ); break; } /* 288*/ /*0289*/case GuiAlarmID::ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION: { result = QObject::tr("DG dialysate or concentrate caps not closed." ); break; } /* 289*/ /*0290*/case GuiAlarmID::ALARM_ID_DG_FLOW_TOO_LOW_WHILE_HEATER_ON : { result = QObject::tr("DG flow too low while heater is on." ); break; } /* 290*/ /*0291*/case GuiAlarmID::NUM_OF_ALARM_IDS : { result = QObject::tr("Total number of alarms." ); break; } /* 291*/ Index: sources/storage/FileHandler.cpp =================================================================== diff -u -r79a6cfcb10472261f3ec26eaf0baf6f1245cd311 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/storage/FileHandler.cpp (.../FileHandler.cpp) (revision 79a6cfcb10472261f3ec26eaf0baf6f1245cd311) +++ sources/storage/FileHandler.cpp (.../FileHandler.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -272,7 +272,11 @@ if (path.at(lastIndex) == "/") path.remove(lastIndex, 1); // check to see if the path in the list of mounted rootPaths /// DEBUG: qDebug() << " +++++ " << QStorageInfo::mountedVolumes(); - foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) { + // FIXME : This function blocks the Device controller thread + // It has been observed during the USB plug test and getting the drive info(space) that + // immediately after the mount this function laggs to get the information for about 2-5 sec. + auto mountedVolumes = QStorageInfo::mountedVolumes(); + foreach (const QStorageInfo &storage, mountedVolumes) { if (storage.isValid() && storage.isReady()) { if ( storage.rootPath() == path ) { if (vIsReadOnly) *vIsReadOnly = storage.isReadOnly(); Index: sources/storage/Logger.cpp =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/storage/Logger.cpp (.../Logger.cpp) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/storage/Logger.cpp (.../Logger.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -331,6 +331,7 @@ */ bool Logger::exportLogs() { + // qDebug() << " ~~~~~~~~~~ " << QThread::currentThread()->objectName(); int result = 0; static QString mOSource; QString mDestination = USB_Mount_Point; @@ -401,10 +402,11 @@ mOExtension = mCExtension; // Remove Logs mLogFileFilter = QString("*%1").arg(mCExtension); - /// DEBUG: since it has been manually tested this will help next time for test. - /// qDebug() << "@" << mCSource << mLogFileFilter << mCExtension << iType << _logTypeMaxUsageLimit[iType]; + // DEBUG: since it has been manually tested this will help next time for test. + // qDebug() << "@" << mCSource << mLogFileFilter << mCExtension << iType << _logTypeMaxUsageLimit[iType]; QFileInfoList fileInfoList = FileHandler::find(mCSource, {mLogFileFilter}, _logTypeMaxUsageLimit[iType]); removeCount = fileInfoList.count(); + // qDebug() << "@" << removeCount << fileInfoList; if (removeCount) { LOG_DEBUG(QString("Removing %1 logs of type (%2) more than %3% limit from folder %4") .arg(removeCount) @@ -417,8 +419,8 @@ } else { QString mFileName = mCSource + info.fileName(); - /// DEBUG: since it has been manually tested this will help next time for test. - /// qDebug() << "#" << mFileName; + // DEBUG: since it has been manually tested this will help next time for test. + // qDebug() << "#" << mFileName; bool ok = QFile::remove(mFileName); if (ok) { LOG_DEBUG(QString("Removing %1 succeeded").arg(mFileName)); Index: sources/storage/Logger.h =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/storage/Logger.h (.../Logger.h) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/storage/Logger.h (.../Logger.h) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -126,14 +126,16 @@ // 1 - Since now both the Log and Datum are in the same place and file they have same percentage. // if separated then the percentage has to be separated // 2 - the total in _logTypeExpiryDay is not 100 and it has to be summed up with Storage::Available_Space_Percent. - // so it is 70% for Event/Datum + 15% Service + 15% free = 100% total + // so it is 50% for Event/Datum + 15% Service + 35% free = 100% total + // If the available SD-Card size is < Storage::Available_Space_Percent( 15 ) the remove logger will remove any of log types to retain percentage for each (50 for log, 15 for servc) + // The deletion will continue to get 35% free space, as has been calculated above. const QHash _logTypeMaxUsageLimit { #ifdef MIXED_EVENT_DATUM - { LogType::eLogEvent, 70 }, // in percent - { LogType::eLogDatum, 70 }, // in percent + { LogType::eLogEvent, 50 }, // in percent + { LogType::eLogDatum, 50 }, // in percent #else - { LogType::eLogEvent, 35 }, // in percent - { LogType::eLogDatum, 35 }, // in percent + { LogType::eLogEvent, 25 }, // in percent + { LogType::eLogDatum, 25 }, // in percent #endif { LogType::eLogDebug, 15 }, // in percent // Not Sure yet so commented out in the remove. Index: sources/storage/Settings.h =================================================================== diff -u -r79a6cfcb10472261f3ec26eaf0baf6f1245cd311 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/storage/Settings.h (.../Settings.h) (revision 79a6cfcb10472261f3ec26eaf0baf6f1245cd311) +++ sources/storage/Settings.h (.../Settings.h) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -29,6 +29,10 @@ namespace Storage { +// TODO - IMPORTANT: this MVC needs to change to configurations in oppose to Settings. +// It named settings because it suppose to be like QSettings, +// but since we have settings it is mixing up with that and is very confusing. + class Settings { // Settings Index: sources/storage/TreatmentLog.cpp =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/storage/TreatmentLog.cpp (.../TreatmentLog.cpp) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/storage/TreatmentLog.cpp (.../TreatmentLog.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -363,18 +363,29 @@ bool TreatmentLog::exportLog() { bool ok = true; - QString dstPath = Storage::USB_Mount_Point ; - dstPath += Storage::Log_Folder_Treatment ; - QString srcFile = _lastTxInfo.mFileName ; - QString dstFile = dstPath + QFileInfo(srcFile).fileName(); + QString status = ""; + QString dstPath = Storage::USB_Mount_Point ; + dstPath += Storage::Log_Folder_Treatment ; + QString srcFile = _lastTxInfo.mFileName ; + QString srcFileName = QFileInfo(srcFile).fileName() ; + QString dstFile = dstPath + srcFileName; // HERE: expose to the UI dialog as the rejection/notification result - if ( ! Storage::FileHandler::makeFolder ( dstPath ) ) { LOG_DEBUG ( QString( "Couldn't create folder on USB drive to export TxLog" ) ); ok = false; goto lOut; } - if ( ! QFileInfo::exists ( srcFile ) ) { LOG_DEBUG ( QString( "TxLog '%1' doesn't exist" ).arg( srcFile ) ); ok = false; goto lOut; } - if ( QFileInfo::exists ( dstFile ) ) { LOG_DEBUG ( QString( "TxLog '%1' already exists" ).arg( dstFile ) ); ok = false; goto lOut; } - if ( ! QFile::copy (srcFile, dstFile ) ) { LOG_DEBUG ( QString( "Unable to Export TxLog '%1' to '%2'" ).arg( srcFile ).arg( dstFile ) ); ok = false; goto lOut; } + if ( ! Storage::FileHandler::makeFolder ( dstPath ) ) { status = QString( "Couldn't create folder on USB drive to export TxLog" ); ok = false; goto lOut; } + if ( ! QFileInfo::exists ( srcFile ) ) { status = QString( "Treatment Log '%1' doesn't exist" ).arg( srcFile ); ok = false; goto lOut; } + if ( QFileInfo::exists ( dstFile ) ) { status = QString( "Treatment Log '%1' already exists" ).arg( dstFile ); ok = false; goto lOut; } + if ( ! QFile::copy (srcFile, dstFile ) ) { status = QString( "Unable to Export TxLog '%1' to '%2'" ).arg( srcFile ).arg( dstFile ); ok = false; goto lOut; } lOut: - if ( ! ok ) LOG_EVENT_UI ( QString( "Unable to Export TxLog" )); + if ( ! ok ) { + LOG_DEBUG(status); + status = "Unable to export treatment log '" + srcFileName +"'"; + } + else { + status = "Treatment log '" + srcFileName + "' exported successfully"; + LOG_EVENT_UI(status); + } + + emit didNotification(status); return ok; } Index: sources/storage/TreatmentLog.h =================================================================== diff -u -r7e503c5459ec77a2816d6c7789da9b206cedbe8a -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/storage/TreatmentLog.h (.../TreatmentLog.h) (revision 7e503c5459ec77a2816d6c7789da9b206cedbe8a) +++ sources/storage/TreatmentLog.h (.../TreatmentLog.h) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -243,6 +243,8 @@ const QString &vPatientID , const QString &vFileName ); void didTxCodeReceive ( const QString &vTxCode ); + + void didNotification ( const QString &vNotification); }; } Index: sources/view/hd/adjustment/posttreatment/VPostTreatmentAdjustTreatmentLog.cpp =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/view/hd/adjustment/posttreatment/VPostTreatmentAdjustTreatmentLog.cpp (.../VPostTreatmentAdjustTreatmentLog.cpp) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/view/hd/adjustment/posttreatment/VPostTreatmentAdjustTreatmentLog.cpp (.../VPostTreatmentAdjustTreatmentLog.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -42,6 +42,9 @@ connect(&_TreatmentLog , &TreatmentLog::didTxCodeReceive, [=](const QString &vTxCode) { txCode( vTxCode ); } ); + + connect(&_TreatmentLog , &TreatmentLog::didNotification, + [=](const QString &vNotification) { notification(vNotification); } ); } /*! Index: sources/view/hd/adjustment/posttreatment/VPostTreatmentAdjustTreatmentLog.h =================================================================== diff -u -rec7f919fdb70ff29a8de627937e4ad7008e59c1c -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/view/hd/adjustment/posttreatment/VPostTreatmentAdjustTreatmentLog.h (.../VPostTreatmentAdjustTreatmentLog.h) (revision ec7f919fdb70ff29a8de627937e4ad7008e59c1c) +++ sources/view/hd/adjustment/posttreatment/VPostTreatmentAdjustTreatmentLog.h (.../VPostTreatmentAdjustTreatmentLog.h) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -94,6 +94,7 @@ PROPERTY(QStringList , parametersText , {}) PROPERTY(QString , txCode , "") + PROPERTY(QString , notification , "") PROPERTY(bool , isIdle , true ) PROPERTY(bool , isReady , false ) Index: sources/view/hd/data/VHDOperationModeData.cpp =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/view/hd/data/VHDOperationModeData.cpp (.../VHDOperationModeData.cpp) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/view/hd/data/VHDOperationModeData.cpp (.../VHDOperationModeData.cpp) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -43,6 +43,10 @@ standbyDGDisinfectChemical ( vData.mSubMode == GuiHDStandbyStates ::STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE ); } + isTreatment ( ! _service ); + isSettings ( _service ); + isManager ( false ); // Always false, not used/implemented for now. + // Go to home is kind of tricky and needs to be managed here in the backend. // It seems we need more states. // It can be handled in the QML but two things will happen that none of which are good. Index: sources/view/hd/data/VHDOperationModeData.h =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r86e9dfbff50cb7e16fd94c16c1c818cef3b47eac --- sources/view/hd/data/VHDOperationModeData.h (.../VHDOperationModeData.h) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/view/hd/data/VHDOperationModeData.h (.../VHDOperationModeData.h) (revision 86e9dfbff50cb7e16fd94c16c1c818cef3b47eac) @@ -61,6 +61,10 @@ PROPERTY( bool , home , false ) ///< Special Home mode // see in the cpp file. + PROPERTY( bool , isTreatment , false ) + PROPERTY( bool , isManager , false ) + PROPERTY( bool , isSettings , false ) + Q_PROPERTY(QString text READ text NOTIFY opModeChanged) VIEW_DEC(VHDOperationMode, HDOperationModeData)