Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r29774d3ecdfd0aab4e2a262690be9c12d4d9752e -r7da39d889ee615026129bae2b31f488ac5abb0f1 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 29774d3ecdfd0aab4e2a262690be9c12d4d9752e) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 7da39d889ee615026129bae2b31f488ac5abb0f1) @@ -8,7 +8,7 @@ * @file ModeStandby.c * * @author (last) Dara Navaei -* @date (last) 10-Nov-2023 +* @date (last) 10-Oct-2024 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -30,6 +30,7 @@ #include "ModeStandby.h" #include "ModeTreatment.h" #include "ModeTreatmentParams.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "RTC.h" #include "Switches.h" @@ -87,11 +88,11 @@ static HD_STANDBY_STATE_T handleStandbyModeDGCleaningModeInProgressState( void ); static void handleDisinfectCancel( BOOL stop ); -static void setRequestedCleaningMode( DG_OP_MODE_T opMode ); +static void setRequestedCleaningMode( DG_OP_MODE_T opMode, BOOL isHeatDisPassiveCool ); static void clearCurrentCleaningModeStatus( void ); static void handleChemFlushSampleCollection( void ); static void handleROPermeateSampleCollection( void ); -static BOOL isDGDisinfectValid( void ); +static BOOL isDGDisinfectValid( REQUEST_REJECT_REASON_CODE_T* rejReason ); static BOOL haveHDDGServicesBeenExpired( REQUEST_REJECT_REASON_CODE_T* rejReason ); /*********************************************************************//** @@ -272,26 +273,16 @@ { rejReason = REQUEST_REJECT_REASON_BATTERY_IS_NOT_CHARGED; } -#ifndef _RELEASE_ - else if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SERVICE_AND_DISINFECT_CHECK ) != SW_CONFIG_ENABLE_VALUE ) -#endif + + if ( getTestConfigStatus( TEST_CONFIG_SKIP_DISINFECT_AND_SERVICE_TX_BLOCKERS ) != TRUE ) { - if ( getTestConfigStatus( TEST_CONFIG_SKIP_DISINFECT_AND_SERVICE_TX_BLOCKERS ) != TRUE ) + if ( getHeatDisinfectTemperatureSensorValue() > MAX_ALLOWED_RO_FILTER_TEMP_FOR_TX_C ) { - // Verify HD and DG are not over due for service - if ( haveHDDGServicesBeenExpired( &rejReason ) != TRUE ) - { - // Verify DG is disinfected - if ( FALSE == isDGDisinfectValid() ) - { - rejReason = REQUEST_REJECT_REASON_DG_DISINFECT_HAS_BEEN_EXPIRED; - } - else if ( getHeatDisinfectTemperatureSensorValue() > MAX_ALLOWED_RO_FILTER_TEMP_FOR_TX_C ) - { - rejReason = REQUEST_REJECT_REASON_DG_RO_FILTER_TEMPERATURE_OUT_OF_RANGE; - } - } + rejReason = REQUEST_REJECT_REASON_DG_RO_FILTER_TEMPERATURE_OUT_OF_RANGE; } + + haveHDDGServicesBeenExpired( &rejReason ); + isDGDisinfectValid( &rejReason ); } // If no reason to reject request to start treatment, set flag to initiate treatment workflow @@ -367,7 +358,7 @@ * The signalUserInitiateFlushMode function handles user initiation of flush * mode. * @details Inputs: currentStandbyState - * @details Outputs: flushStartReqReceived, currentStandbyState + * @details Outputs: currentStandbyState * @return TRUE if signal accepted, FALSE if not *************************************************************************/ BOOL signalUserInitiateFlushMode( void ) @@ -381,7 +372,7 @@ { if ( TRUE == isDGCommunicating() ) { - setRequestedCleaningMode( DG_MODE_FLUS ); + setRequestedCleaningMode( DG_MODE_FLUS, FALSE ); result = TRUE; currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; rejReason = REQUEST_REJECT_REASON_NONE; @@ -400,13 +391,13 @@ /*********************************************************************//** * @brief - * The signalUserInitiateFlushMode function handles user initiation of heat - * disinfect mode. + * The signalUserInitiateHeatDisinfectActiveCoolMode function handles user + * initiation of heat disinfect with active cool mode. * @details Inputs: currentStandbyState - * @details Outputs: heatDisinfectStartReqReceived + * @details Outputs: currentStandbyState * @return TRUE if signal accepted, FALSE if not *************************************************************************/ -BOOL signalUserInitiateHeatDisinfectMode( void ) +BOOL signalUserInitiateHeatDisinfectActiveCoolMode( void ) { BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; @@ -417,7 +408,7 @@ { if ( TRUE == isDGCommunicating() ) { - setRequestedCleaningMode( DG_MODE_HEAT ); + setRequestedCleaningMode( DG_MODE_HEAT, FALSE ); result = TRUE; currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; rejReason = REQUEST_REJECT_REASON_NONE; @@ -439,7 +430,7 @@ * The signalUserInitiateChemicalDisinfectMode function handles user * initiation of chemical disinfect mode. * @details Inputs: currentStandbyState - * @details Outputs: chemDisinfectStartReqReceived + * @details Outputs: currentStandbyState * @return TRUE if signal accepted, FALSE if not *************************************************************************/ BOOL signalUserInitiateChemicalDisinfectMode( void ) @@ -453,7 +444,93 @@ { if ( TRUE == isDGCommunicating() ) { - setRequestedCleaningMode( DG_MODE_CHEM ); + if ( TRUE == isChemDisinfectEnabledInInstitRecord() ) + { + setRequestedCleaningMode( DG_MODE_CHEM, FALSE ); + result = TRUE; + currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_CHEM_DISINFECT_NOT_ENABLED_INST_CONFIG; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + } + + sendDisinfectConfirmResponse( result, rejReason ); + + return result; +} + +/*********************************************************************//** + * @brief + * The signalUserInitiateChemicalDisinfectFlushMode function handles user + * initiation of chemical disinfect flush mode. + * @details Inputs: currentStandbyState + * @details Outputs: currentStandbyState + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalUserInitiateChemicalDisinfectFlushMode( void ) +{ + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + + if ( MODE_STAN == getCurrentOperationMode() ) + { + if ( ( STANDBY_WAIT_FOR_DISINFECT_STATE == currentStandbyState ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + if ( TRUE == isChemDisinfectEnabledInInstitRecord() ) + { + setRequestedCleaningMode( DG_MODE_CHFL, FALSE ); + result = TRUE; + currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_CHEM_DISINFECT_NOT_ENABLED_INST_CONFIG; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + } + + sendDisinfectConfirmResponse( result, rejReason ); + + return result; +} + +/*********************************************************************//** + * @brief + * The signalUserInitiateROPermeateSampleMode function handles user + * initiation of RO permeate sample mode. + * @details Inputs: currentStandbyState + * @details Outputs: currentStandbyState + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalUserInitiateROPermeateSampleMode( void ) +{ + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + + if ( MODE_STAN == getCurrentOperationMode() ) + { + if ( ( STANDBY_WAIT_FOR_DISINFECT_STATE == currentStandbyState ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + setRequestedCleaningMode( DG_MODE_ROPS, FALSE ); result = TRUE; currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; rejReason = REQUEST_REJECT_REASON_NONE; @@ -472,13 +549,13 @@ /*********************************************************************//** * @brief - * The signalUserInitiateChemcialDisinfectFlushMode function handles user - * initiation of chemical disinfect flush mode. + * The signalUserInitiateHeatDisinfectPassiveCoolMode function handles user + * initiation of passive cool heat disinfect mode. * @details Inputs: currentStandbyState - * @details Outputs: chemDisinfectFlushStartReqReceived, currentStandbyState + * @details Outputs: currentStandbyState * @return TRUE if signal accepted, FALSE if not *************************************************************************/ -BOOL signalUserInitiateChemcialDisinfectFlushMode( void ) +BOOL signalUserInitiateHeatDisinfectPassiveCoolMode( void ) { BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; @@ -489,7 +566,7 @@ { if ( TRUE == isDGCommunicating() ) { - setRequestedCleaningMode( DG_MODE_CHFL ); + setRequestedCleaningMode( DG_MODE_HEAT, TRUE ); result = TRUE; currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; rejReason = REQUEST_REJECT_REASON_NONE; @@ -508,13 +585,13 @@ /*********************************************************************//** * @brief - * The signalUserInitiateROPermeateSampleMode function handles user - * initiation of RO permeate sample mode. + * The signalUserInitiateActiveCoolMode function handles user initiation of + * active cool mode. * @details Inputs: currentStandbyState - * @details Outputs: roPermeateSampleStartReqReceived, currentStandbyState + * @details Outputs: currentStandbyState * @return TRUE if signal accepted, FALSE if not *************************************************************************/ -BOOL signalUserInitiateROPermeateSampleMode( void ) +BOOL signalUserInitiateActiveCoolMode( void ) { BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; @@ -525,7 +602,7 @@ { if ( TRUE == isDGCommunicating() ) { - setRequestedCleaningMode( DG_MODE_ROPS ); + setRequestedCleaningMode( DG_MODE_HCOL, FALSE ); result = TRUE; currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; rejReason = REQUEST_REJECT_REASON_NONE; @@ -542,6 +619,7 @@ return result; } + /*********************************************************************//** * @brief * The signalInitiateStandbyDisinfectSubmode function handles user @@ -700,7 +778,7 @@ case DG_MODE_CHFL: case DG_MODE_HCOL: case DG_MODE_ROPS: - setRequestedCleaningMode( dgOperationMode ); + setRequestedCleaningMode( dgOperationMode, FALSE ); state = STANDBY_WAIT_FOR_DG_CLEANING_MODE_TO_START_STATE; break; @@ -765,7 +843,14 @@ break; case DG_MODE_HEAT: - cmdStartDGHeatDisinfect(); + if ( DG_CMD_START_HEAT_DISINFECT_ACTIVE_COOL == currentDGCleaningMode.startRequestCmdID ) + { + cmdStartDGHeatDisinfectActiveCool(); + } + else + { + cmdStartDGHeatDisinfectPassiveCool(); + } break; case DG_MODE_CHEM: @@ -779,10 +864,35 @@ case DG_MODE_ROPS: cmdStartDGROPermeateSampleMode(); break; + + case DG_MODE_HCOL: + cmdStartDGActiveCool(); + break; } state = STANDBY_WAIT_FOR_DG_CLEANING_MODE_CMD_RESPONSE_STATE; } + else + { + switch ( getDGOpMode() ) + { + case DG_MODE_FLUS: + case DG_MODE_HEAT: + case DG_MODE_CHEM: + case DG_MODE_CHFL: + case DG_MODE_ROPS: + // This is for the situations that any of the disinfect modes are started using the proxy commands while the HD + // is in this state of the Standby Mode. + setRequestedCleaningMode( getDGOpMode(), FALSE ); + state = STANDBY_WAIT_FOR_DG_CLEANING_MODE_TO_START_STATE; + currentDGCleaningMode.startCleaningMode = FALSE; + break; + default: + // Do nothing we are not in the cleaning mode + break; + } + } + return state; } @@ -864,6 +974,8 @@ { state = STANDBY_WAIT_FOR_TREATMENT_STATE; clearAlarm( currentDGCleaningMode.alarmID ); + // In case alarm 306 has been triggered, and it was not cleared, clear it upon exiting the disinfection mode. + clearAlarm( ALARM_ID_DG_TURN_OFF_INLET_WATER_VALVES ); clearCurrentCleaningModeStatus(); } @@ -951,9 +1063,11 @@ * @details Inputs: currentDGCleaningMode * @details Outputs: none * @param opMode DG operation mode that has been requested (i.e. heat disinfect) + * @param isHeatDisPassiveCool boolean flag to indicate whether this is a passive + * cool heat disinfect or not. * @return none *************************************************************************/ -static void setRequestedCleaningMode( DG_OP_MODE_T opMode ) +static void setRequestedCleaningMode( DG_OP_MODE_T opMode, BOOL isHeatDisPassiveCool ) { switch ( opMode ) { @@ -968,7 +1082,7 @@ case DG_MODE_HEAT: currentDGCleaningMode.startCleaningMode = TRUE; - currentDGCleaningMode.startRequestCmdID = DG_CMD_START_HEAT_DISINFECT; + currentDGCleaningMode.startRequestCmdID = ( FALSE == isHeatDisPassiveCool ? DG_CMD_START_HEAT_DISINFECT_ACTIVE_COOL : DG_CMD_START_HEAT_DISINFECT_PASSIVE_COOL ); currentDGCleaningMode.dgOpMode = DG_MODE_HEAT; currentDGCleaningMode.sampleRqstTrgrd = FALSE; currentDGCleaningMode.alarmID = ALARM_ID_HD_DISINFECT_HEAT; @@ -994,9 +1108,8 @@ break; case DG_MODE_HCOL: - // Cannot start active cool from settings in the UI currentDGCleaningMode.startCleaningMode = FALSE; - currentDGCleaningMode.startRequestCmdID = DG_CMD_NONE; + currentDGCleaningMode.startRequestCmdID = DG_CMD_START_ACTIVE_COOL; currentDGCleaningMode.dgOpMode = DG_MODE_HCOL; currentDGCleaningMode.sampleRqstTrgrd = FALSE; currentDGCleaningMode.alarmID = ALARM_ID_HD_DISINFECT_HEAT_COOL; @@ -1148,9 +1261,10 @@ * acceptable to start another treatment. * @details Inputs: none * @details Outputs: none + * @param rejReason pointer to the provided reject reason buffer to be send to UI * @return TRUE if the disinfect is valid otherwise, FALSE ***********************************************************************/ -static BOOL isDGDisinfectValid( void ) +static BOOL isDGDisinfectValid( REQUEST_REJECT_REASON_CODE_T* rejReason ) { DG_SERVICE_AND_USAGE_DATA_T data; BOOL status = FALSE; @@ -1189,6 +1303,16 @@ BOOL isFlushValid = ( ( ( TRUE == isBasicFlushValid ) || ( TRUE == isChemFlushValid ) || ( TRUE == isHeatDisCoolFlushValid ) || ( TRUE == isHeatDisFlushValid ) ) ? TRUE : FALSE ); + if ( FALSE == isFlushValid ) + { + *rejReason = REQUEST_REJECT_REASON_DG_FILTER_FLUSH_HAS_BEEN_EXPIRED; + } + + if ( ( FALSE == isHeatDisValid ) || ( FALSE == isChemFlushComplete ) || ( FALSE == hasDisBeenDone ) ) + { + *rejReason = REQUEST_REJECT_REASON_DG_DISINFECT_HAS_BEEN_EXPIRED; + } + // If all of the above conditions are true, it means we can start a treatment if ( ( TRUE == hasDisBeenDone ) && ( TRUE == isHeatDisValid ) && ( TRUE == isChemFlushComplete ) && ( TRUE == isFlushValid ) ) {