Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -r5109bb981cab2025fcb9de33e303d046085efa18 -r20244278848db264bc95062f4d8df907da93abe5 --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 5109bb981cab2025fcb9de33e303d046085efa18) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 20244278848db264bc95062f4d8df907da93abe5) @@ -8,7 +8,7 @@ * @file ModeChemicalDisinfect.c * * @author (last) Dara Navaei -* @date (last) 16-May-2023 +* @date (last) 02-Jun-2023 * * @author (original) Sean * @date (original) 04-Apr-2020 @@ -76,7 +76,7 @@ #define RSRVRS_PARTIAL_FILL_UP_TIMEOUT_MS ( 7 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. #define RSRVRS_ALMOST_FULL_FILL_UP_TIMEOUT_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. It is assumed the reservoir is nearly full to begin. #define RESERVOIR_FULL_VOLUME_CHANGE_LIMIT_ML 5.0F ///< The maximum difference between the short-term and long-term filtered reservoir volumes in ml that determines the reservoir is full. -#define RESERVOIR_MINIMUM_FULL_VOLUME_ML 1700.0F ///< When filling the reservoir, the volume reading must be at least this value before checking for the volume to level off. +#define RESERVOIR_MINIMUM_FULL_VOLUME_ML 1850.0F ///< When filling the reservoir, the volume reading must be at least this value before checking for the volume to level off. #define RSRVRS_FILL_TO_FULL_STABLE_TASK_INT ( ( 2 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in task intervals. // Prime acid line state defines @@ -113,7 +113,7 @@ // Parameters controlling chemical disinfect #define TARGET_CHEM_DISINFECT_TIME_MS ( 12 * SEC_PER_MIN * MS_PER_SECOND ) ///< Expected chemical disinfect time in ms. -#define CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect reaching to minimum temperature timeout in milliseconds. +#define CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect reaching to minimum temperature timeout in milliseconds. #define CHEM_DISINFECT_TARGET_TEMPERATURE_C 37.0F ///< Chemical disinfect target water temperature in C. #define CHEM_DISINFECT_MINIMUM_TEMPERATURE_C 35.0F ///< Chemical disinfect target water temperature in C. #define CHEM_DISINFECT_HEATER_CONTROL_TEMPERATURE_C 45.0F ///< Chemical disinfect heater control water temperature in C. @@ -469,17 +469,24 @@ if ( FALSE == isAlarmActive( ALARM_ID_DG_CHEM_DISINFECT_INSERT_ACID ) ) { - // Set all the actuators to reset and de-energized state - deenergizeActuators( NO_PARK_CONC_PUMPS ); - setValveState( VPI, VALVE_STATE_CLOSED ); - setValveState( VRD1, VALVE_STATE_OPEN ); - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); + if ( ( STATE_CLOSED == getSwitchStatus( CONCENTRATE_CAP ) ) || ( STATE_OPEN == getSwitchStatus( DIALYSATE_CAP ) ) ) + { + activateAlarmNoData( ALARM_ID_DG_CHEM_DISINFECT_INSERT_ACID ); + } + else + { + // Set all the actuators to reset and de-energized state + deenergizeActuators( NO_PARK_CONC_PUMPS ); + setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VRD1, VALVE_STATE_OPEN ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - // Assume reservoir 1 is full and drain it - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; - stateTimer = getMSTimerCount(); + // Assume reservoir 1 is full and drain it + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; + stateTimer = getMSTimerCount(); + } } return state; @@ -753,7 +760,8 @@ } } // Check if the acid conductivity value has been above the threshold for the specified time period - if ( ++primeAcidSteadyStateCounter >= PRIME_ACID_STEADY_CONDUCTIVITY_TASK_INT ) + if ( ( ++primeAcidSteadyStateCounter >= PRIME_ACID_STEADY_CONDUCTIVITY_TASK_INT ) || + ( TRUE == getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) ) ) { // Turn off the concentrate pump requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); @@ -922,7 +930,7 @@ * transitions to the next state. * @details Inputs: stateTimer, rsrvr1Status, rsrvr2Status * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status, - * chemDisinfectUIState + * chemDisinfectUIState, prevChemDisinfectState * @return next state of the chemical disinfect state machine *************************************************************************/ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectR1ToR2State( void ) @@ -938,14 +946,16 @@ { // Heating up to minimum temperature for chemical disinfect failed alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE; - chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } if ( TRUE == didTimeout( stateTimer, MAX_DISINFECT_STATE_TIME_MS ) ) { // Heating up to minimum temperature for chemical disinfect failed alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE; - chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } if ( chemDisinfectReservoirTime >= DISINFECT_CYCLE_PERIOD_MS ) @@ -1040,14 +1050,16 @@ { // Heating up to minimum temperature for chemical disinfect failed alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE; - chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } if ( TRUE == didTimeout( stateTimer, MAX_DISINFECT_STATE_TIME_MS ) ) { // Heating up to minimum temperature for chemical disinfect failed alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE; - chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } if ( chemDisinfectReservoirTime >= DISINFECT_CYCLE_PERIOD_MS ) @@ -1096,8 +1108,9 @@ setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_OPEN ); - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R2_FILL_R1_TO_R2; + stateTimer = getMSTimerCount(); + rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; + state = DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R2_FILL_R1_TO_R2; } } else @@ -1567,7 +1580,8 @@ } else if ( TdiTemp < CHEM_DISINFECT_MINIMUM_TEMPERATURE_C ) { - isChemDisinfectTempAboveTarget = FALSE; + isChemDisinfectTempAboveTarget = FALSE; + ischemDisinfectWarmupTargetReached = FALSE; } if ( TRUE == isChemDisinfectTempAboveTarget ) @@ -1646,12 +1660,21 @@ if ( ( DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2 == chemDisinfectState ) || ( DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1 == chemDisinfectState ) ) { BOOL isRsrvrVolumeOutOfRange = FALSE; - isRsrvrLeaking = FALSE; - isRsrvrVolumeOutOfRange |= fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - R1FullVolume ) > RSRVRS_MAX_LEAK_VOL_CHANGE_ML; - isRsrvrVolumeOutOfRange |= fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - R2FullVolume ) > RSRVRS_MAX_LEAK_VOL_CHANGE_ML; + //isRsrvrLeaking = FALSE; - if ( ( TRUE == isRsrvrVolumeOutOfRange ) ) + if ( DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2 == chemDisinfectState ) { + isRsrvrVolumeOutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - R1FullVolume ) > RSRVRS_MAX_LEAK_VOL_CHANGE_ML; + } + else + { + isRsrvrVolumeOutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - R2FullVolume ) > RSRVRS_MAX_LEAK_VOL_CHANGE_ML; + } + + isRsrvrLeaking = ( TRUE == isRsrvrLeaking ? isRsrvrLeaking : FALSE ); + + if ( TRUE == isRsrvrVolumeOutOfRange ) + { // If the leak is the first time after a while, set the flag and start the timer if ( FALSE == isRsrvrLeaking ) { @@ -1672,13 +1695,22 @@ if ( ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) && ( NELSON_NONE == nelsonSupport ) ) #endif { - // If the dialysate cap is closed during any state other the start state, alarm. In start state we are still looking for - // the user to insert the acid into the dialysate port and hit ok - if ( ( STATE_CLOSED == getSwitchStatus( DIALYSATE_CAP ) ) && ( chemDisinfectState != DG_CHEM_DISINFECT_STATE_START ) ) + // If the concentrate cap is closed during any state other the start state, alarm. In start state we are still looking for + // the user to insert the acid into the concentrate port and hit ok + if ( ( ( STATE_CLOSED == getSwitchStatus( CONCENTRATE_CAP ) || ( STATE_OPEN == getSwitchStatus( DIALYSATE_CAP ) ) ) ) && + ( chemDisinfectState != DG_CHEM_DISINFECT_STATE_START ) ) { prevChemDisinfectState = chemDisinfectState; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_CAP_NOT_IN_PROPER_POSITION; + + if ( STATE_CLOSED == getSwitchStatus( CONCENTRATE_CAP ) ) + { + alarmDetectedPendingTrigger = ALARM_ID_DG_CONCENTRATE_CAP_NOT_IN_PROPER_POSITION; + } + if ( STATE_OPEN == getSwitchStatus( DIALYSATE_CAP ) ) + { + alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_CAP_NOT_IN_PROPER_POSITION; + } } } @@ -1709,10 +1741,13 @@ } } - if ( ( TRUE == isDGFaultAlarmActive() ) && ( chemDisinfectState != DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH ) ) + if ( ( TRUE == isDGFaultAlarmActive() ) || ( TRUE == isAnyCleaningModeInletWaterConditionActive() ) ) { - prevChemDisinfectState = chemDisinfectState; - chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + if ( chemDisinfectState != DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH ) + { + prevChemDisinfectState = chemDisinfectState; + chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + } } }