/*! * * Copyright (c) 2021-2024 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 VTDTreatmentStatesData.cpp * \author (last) Behrouz NematiPour * \date (last) 20-Jul-2023 * \author (original) Behrouz NematiPour * \date (original) 11-Apr-2021 * */ #include "VTDTreatmentStatesData.h" #include // Project #include "GuiController.h" //ENUM Checks //TODO: ---------- Improve me ---------- // This part of the code is a WIP example to fail the build if the enum is changed but UI doesn't aware. #define ENUM_PRINT( vTYPE ) {} // qDebug() << v##vTYPE #define ENUM_CHECK_O( vTYPE, vVALUE ) vTYPE v##vTYPE = static_cast(vVALUE); switch(v##vTYPE) #define ENUM_CHECK( vTYPE, vENUM ) case vTYPE::vENUM : { if ( vTYPE::vENUM == v##vTYPE) ENUM_PRINT(vTYPE); } break; #define ENUM_CHECK_C( vTYPE, vENUM ) case vTYPE::vENUM : break; #define ENUM_READ( vTYPE, vENUM, vSTATE ) vSTATE( vTYPE::vENUM == v##vTYPE); VIEW_DEF_CLASS(VTDTreatmentStates) /*! * \brief VTreatmentAdjustmentSaline::initConnections * \details Initializes the message(s) connection * \note This class not only listens to its dedicated message TreatmentStatesData, * But also listens to other messages which affect ultrafiltration and saline bolus state. * These extra messages are AdjustSalineResponseData , AdjustUltrafiltrationStateResponseData. * Which ever comes first will set its related properties. * Since the properties wont set twice if they have the same value it does not affect performance so much. * Also FW suppose to send the TreatmentStatesData related message immediately after the two others. */ void VTDTreatmentStates::initConnections() { ACTION_VIEW_CONNECTION(TreatmentStatesData ); // these messages sending the same states as in message 15 (TreatmentStates above) // it is redundant and with a better messaging protocol // the one in the Adjustment messages should be removed since it is not sent on each state change // and will be sent only once to the request. ACTION_VIEW_CONNECTION(AdjustUltrafiltrationStateResponseData ); } /*! * \brief VTDTreatmentStates::onActionReceive * \details sets the properties for the received data of Treatment States * \param vData - Treatment States data */ void VTDTreatmentStates::onActionReceive(const TreatmentStatesData &vData) { subMode ( vData.mSubMode ); ufState ( vData.mIsolatedUFState ); salineState ( vData.mSalineState ); salineState ( vData.mSalineState ); // Ultrafiltration states // Saline Bolus states ENUM_CHECK_O( GuiSalineStates, vData.mSalineState ) { ENUM_CHECK ( GuiSalineStates, SALINE_BOLUS_STATE_IDLE ) ENUM_CHECK ( GuiSalineStates, SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP ) ENUM_CHECK ( GuiSalineStates, SALINE_BOLUS_STATE_IN_PROGRESS ) ENUM_CHECK_C( GuiSalineStates, NUM_OF_SALINE_BOLUS_STATES ) } ENUM_READ ( GuiSalineStates, SALINE_BOLUS_STATE_IDLE , sbIdle ); ENUM_READ ( GuiSalineStates, SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP , sbWaitPump ); ENUM_READ ( GuiSalineStates, SALINE_BOLUS_STATE_IN_PROGRESS , sbRunning ); // Heparin States _heparin = false; ENUM_CHECK_O( GuiHeparinStates, vData.mHeparinState ) { ENUM_CHECK ( GuiHeparinStates, HEPARIN_STATE_OFF ) ENUM_CHECK ( GuiHeparinStates, HEPARIN_STATE_STOPPED ) ENUM_CHECK ( GuiHeparinStates, HEPARIN_STATE_PAUSED ) ENUM_CHECK ( GuiHeparinStates, HEPARIN_STATE_INITIAL_BOLUS ) ENUM_CHECK ( GuiHeparinStates, HEPARIN_STATE_DISPENSING ) ENUM_CHECK ( GuiHeparinStates, HEPARIN_STATE_COMPLETED ) ENUM_CHECK ( GuiHeparinStates, HEPARIN_STATE_EMPTY ) ENUM_CHECK_C( GuiHeparinStates, NUM_OF_HEPARIN_STATES ) } ENUM_READ ( GuiHeparinStates, HEPARIN_STATE_OFF , hpOff ); _heparin = _heparin || _hpOff ; ENUM_READ ( GuiHeparinStates, HEPARIN_STATE_STOPPED , hpStopped ); _heparin = _heparin || _hpStopped ; ENUM_READ ( GuiHeparinStates, HEPARIN_STATE_PAUSED , hpPaused ); _heparin = _heparin || _hpPaused ; ENUM_READ ( GuiHeparinStates, HEPARIN_STATE_INITIAL_BOLUS , hpInitial_bolus ); _heparin = _heparin || _hpInitial_bolus ; ENUM_READ ( GuiHeparinStates, HEPARIN_STATE_DISPENSING , hpDispensing ); _heparin = _heparin || _hpDispensing ; ENUM_READ ( GuiHeparinStates, HEPARIN_STATE_COMPLETED , hpCompleted ); _heparin = _heparin || _hpCompleted ; ENUM_READ ( GuiHeparinStates, HEPARIN_STATE_EMPTY , hpEmpty ); _heparin = _heparin || _hpEmpty ; emit heparinChanged(_heparin); // Treatment states ENUM_CHECK_O( GuiTreatmentStates, vData.mSubMode ) { ENUM_CHECK ( GuiTreatmentStates, TREATMENT_START_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_BLOOD_PRIME_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_DIALYSIS_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_PAUSED_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_RINSEBACK_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_RECIRC_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_END_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_ISO_UF_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_SALINE_BOLUS_STATE ) ENUM_CHECK ( GuiTreatmentStates, TREATMENT_DIALYSATE_PAUSED_STATE ) ENUM_CHECK_C( GuiTreatmentStates, NUM_OF_TREATMENT_STATES ) } // Treatment states - Basics ENUM_READ ( GuiTreatmentStates, TREATMENT_START_STATE , txStart ); // Treatment states - Dialysis bool mDialysis = vData.mSubMode == GuiTreatmentStates ::TREATMENT_DIALYSIS_STATE ; if ( mDialysis ) { ENUM_CHECK_O( GuiDialysisState, vData.mDialysisState ) { ENUM_CHECK ( GuiDialysisState, DIALYSIS_UF_STATE ) ENUM_CHECK ( GuiDialysisState, DIALYSIS_UF_PAUSED_STATE ) ENUM_CHECK_C( GuiDialysisState, NUM_OF_DIALYSIS_STATES ) } ENUM_READ ( GuiDialysisState, DIALYSIS_UF_STATE , dyUltrafiltration ); ENUM_READ ( GuiDialysisState, DIALYSIS_UF_PAUSED_STATE , dySalineBolus ); } txDialysis ( mDialysis ); // it's the main dialysis event so moved last to have all the sub-dialysis-states updated prior to. // TODO : Check with Qt.5.15.10 // NOTE : For Rinseback and Recirculate // 1 - it seems we may never need the txRinseback // since in the Rinseback state parameter of the Treatment State the first state of each has the same meaning // it may only be used to know when those parameters have valid values to update the properties. // Kept for now because cannot be sure that it will change later or not. // 2 - if there could be a way to export enums to qml and qml can raise an error if an incorrect enum used, // then it would be absolutely preferred to use enum instead of properties // currently if just one property being defined/used to send the current state to the qml, there is no way to make sure if incorrect/undefined // enum is used or not. // in Qt user/developer can literally type GuiActions.abcdefg and qml will never complain and only if compared with the state will return false. // Treatment states - Rinse back // Rinseback states bool mRinseback = vData.mSubMode == GuiTreatmentStates ::TREATMENT_RINSEBACK_STATE ; if ( mRinseback ) { ENUM_CHECK_O( GuiRinsebackStates, vData.mRinsebackState ) { ENUM_CHECK ( GuiRinsebackStates, RINSEBACK_STOP_INIT_STATE ) ENUM_CHECK ( GuiRinsebackStates, RINSEBACK_RUN_STATE ) ENUM_CHECK ( GuiRinsebackStates, RINSEBACK_PAUSED_STATE ) ENUM_CHECK ( GuiRinsebackStates, RINSEBACK_STOP_STATE ) ENUM_CHECK ( GuiRinsebackStates, RINSEBACK_RUN_ADDITIONAL_STATE ) ENUM_CHECK ( GuiRinsebackStates, RINSEBACK_RECONNECT_PATIENT_STATE ) ENUM_CHECK_C( GuiRinsebackStates, NUM_OF_RINSEBACK_STATES ) } ENUM_READ ( GuiRinsebackStates, RINSEBACK_STOP_INIT_STATE , rbInit ); ENUM_READ ( GuiRinsebackStates, RINSEBACK_RUN_STATE , rbRun ); ENUM_READ ( GuiRinsebackStates, RINSEBACK_PAUSED_STATE , rbPaused ); ENUM_READ ( GuiRinsebackStates, RINSEBACK_STOP_STATE , rbStop ); ENUM_READ ( GuiRinsebackStates, RINSEBACK_RUN_ADDITIONAL_STATE , rbAdditional ); ENUM_READ ( GuiRinsebackStates, RINSEBACK_RECONNECT_PATIENT_STATE , rbReconnect ); } txRinseback ( mRinseback ); // it's the main rinseback event so moved last to have all the sub-rinseback-states updated prior to. // Recirculate states bool mRecirculate = vData.mSubMode == GuiTreatmentStates ::TREATMENT_RECIRC_STATE ; if ( mRecirculate ) { ENUM_CHECK_O( GuiRecirculateStates, vData.mRecirculateState ) { ENUM_CHECK ( GuiRecirculateStates, TREATMENT_RECIRC_DISCONNECT_PATIENT_STATE ) ENUM_CHECK ( GuiRecirculateStates, TREATMENT_RECIRC_RECIRC_STATE ) ENUM_CHECK ( GuiRecirculateStates, TREATMENT_RECIRC_STOPPED_STATE ) ENUM_CHECK ( GuiRecirculateStates, TREATMENT_RECIRC_RECONNECT_PATIENT_STATE ) ENUM_CHECK_C( GuiRecirculateStates, NUM_OF_TREATMENT_RECIRC_STATES ) } ENUM_READ ( GuiRecirculateStates, TREATMENT_RECIRC_DISCONNECT_PATIENT_STATE , rcDisconnect ); ENUM_READ ( GuiRecirculateStates, TREATMENT_RECIRC_RECIRC_STATE , rcStarted ); ENUM_READ ( GuiRecirculateStates, TREATMENT_RECIRC_STOPPED_STATE , rcStopped ); ENUM_READ ( GuiRecirculateStates, TREATMENT_RECIRC_RECONNECT_PATIENT_STATE , rcReconnect ); } txRecirculate ( mRecirculate ); // it's the main recirculate even so moved last to have all the sub-recirculate-states updated prior to. // Blood Prime states bool mBloodPrime = vData.mSubMode == GuiTreatmentStates ::TREATMENT_BLOOD_PRIME_STATE ; if ( mBloodPrime ) { ENUM_CHECK_O( GuiBloodPrimeStates, vData.mBloodPrimeState ) { ENUM_CHECK ( GuiBloodPrimeStates, BLOOD_PRIME_RAMP_STATE ) ENUM_CHECK_C( GuiBloodPrimeStates, NUM_OF_BLOOD_PRIME_STATES ) } ENUM_READ ( GuiBloodPrimeStates, BLOOD_PRIME_RAMP_STATE , bpRamp ); } txBloodPrime ( mBloodPrime ); // Treatment End states bool mTreatmentEnd = vData.mSubMode == GuiTreatmentStates ::TREATMENT_END_STATE ; if ( mTreatmentEnd ) { ENUM_CHECK_O( GuiTreatmentEndStates, vData.mTreatmentEndState ) { ENUM_CHECK ( GuiTreatmentEndStates, TREATMENT_END_WAIT_FOR_RINSEBACK_STATE ) ENUM_CHECK ( GuiTreatmentEndStates, TREATMENT_END_PAUSED_STATE ) ENUM_CHECK_C( GuiTreatmentEndStates, NUM_OF_TREATMENT_END_STATES ) } ENUM_READ ( GuiTreatmentEndStates, TREATMENT_END_WAIT_FOR_RINSEBACK_STATE , teWaitRinseback ); ENUM_READ ( GuiTreatmentEndStates, TREATMENT_END_PAUSED_STATE , tePaused ); } txEnd ( mTreatmentEnd ); // Treatment Stop states bool mTreatmentStop = vData.mSubMode == GuiTreatmentStates ::TREATMENT_PAUSED_STATE ; if ( mTreatmentStop ) { ENUM_CHECK_O( GuiTreatmentPausedStates, vData.mTreatmentStopState ) { ENUM_CHECK ( GuiTreatmentPausedStates, TREATMENT_PAUSED_RECIRC_STATE ) ENUM_CHECK ( GuiTreatmentPausedStates, TREATMENT_PAUSED_RECIRC_DIALYSATE_ONLY_STATE ) ENUM_CHECK ( GuiTreatmentPausedStates, TREATMENT_PAUSED_RECIRC_BLOOD_ONLY_STATE ) ENUM_CHECK ( GuiTreatmentPausedStates, TREATMENT_PAUSED_NO_RECIRC_STATE ) ENUM_CHECK ( GuiTreatmentPausedStates, TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE ) ENUM_CHECK_C( GuiTreatmentPausedStates, NUM_OF_TREATMENT_PAUSED_STATES ) } ENUM_READ ( GuiTreatmentPausedStates, TREATMENT_PAUSED_RECIRC_STATE , tsRecirculate ) ENUM_READ ( GuiTreatmentPausedStates, TREATMENT_PAUSED_RECIRC_DIALYSATE_ONLY_STATE, tsRecirculateDialysate ) ENUM_READ ( GuiTreatmentPausedStates, TREATMENT_PAUSED_RECIRC_BLOOD_ONLY_STATE , tsRecirculateBlood ) ENUM_READ ( GuiTreatmentPausedStates, TREATMENT_PAUSED_NO_RECIRC_STATE , tsRecirculateNo ) ENUM_READ ( GuiTreatmentPausedStates, TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE , tsRecoverBloodDetect ) } txStop ( mTreatmentStop ); txTreatment ( _txDialysis || _txStop ); } /*! * \brief VTDTreatmentStates::onActionReceive * \details message handler for the message AdjustUltrafiltrationStateResponse data * \param vData - AdjustUltrafiltrationStateResponse data */ void VTDTreatmentStates::onActionReceive(const AdjustUltrafiltrationStateResponseData &) { // Ultrafiltration states }