Index: firmware/App/Modes/ModeHeatDisinfectActiveCool.c =================================================================== diff -u -r1475b55c0a91327f63a99ee5e40a7b55e0c43a06 -r2e56064726838bfb626ec3ea40132c4e3681639a --- firmware/App/Modes/ModeHeatDisinfectActiveCool.c (.../ModeHeatDisinfectActiveCool.c) (revision 1475b55c0a91327f63a99ee5e40a7b55e0c43a06) +++ firmware/App/Modes/ModeHeatDisinfectActiveCool.c (.../ModeHeatDisinfectActiveCool.c) (revision 2e56064726838bfb626ec3ea40132c4e3681639a) @@ -45,15 +45,19 @@ // The acid pump is 2% faster than the acid pump to create a flow from acid to bicarb line during heat disinfect #define BICARB_PUMP_SPEED_ML_PER_MIN -30.0F ///< Bicarb concentrate pump speed in mL/min. #define RSRVR_FILL_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) +#define RSRVR_DRAIN_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) +#define RSRVR_DRAIN_STEADY_TIMEOUT_MS ( 6 * MS_PER_SECOND ) +#define RSRVR_DRAIN_TARGET_RPM 2400 +#define RSRVR_MIX_DRAIN_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 mix drain timeout in ms. +#define RSRVR_MIX_DRAIN_TEMPERATURE_THRESHOLD_C 60.0F ///< Temperature threshold for performing mix drain or normal drain. #define TARGET_THD_SENSOR_FOR_RINSING_C 44.0F // TODO remove ///< Target THd temperature sensor value before rinsing in C. #define ROF_COOL_DOWN_CIRCULATION_TIME_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) // TODO remove ///< RO filter cool down circulation timer in milliseconds. #define ROF_COOL_DOWN_MAX_TIME_MS ( 300 * SEC_PER_MIN * MS_PER_SECOND ) // todo remove ///< RO filter cool down maximum state time in milliseconds. -// Active cool down defines -#define ROF_ACTIVE_COOL_DOWN_TARGET_FLOW_LPM 0.3F ///< RO active cool down target flow in L/min. -#define ROF_ACTIVE_COOL_DOWN_MAX_PRESSURE_PSI 30 ///< RO active cool down maximum pressure in psi. - +// RO filter cool down defines +#define ROF_ACTIVE_COOL_TARGET_FLOW_LPM 0.3F ///< RO active cool down target flow in L/min. +#define ROF_ACTIVE_COOL_MAX_ALLOWED_PRESSURE_PSI 30 ///< RO active cool down maximum pressure in psi. #define ROF_ACTIVE_COOL_TARGET_RSRVR_FILL_ML 750.0F #define ROF_ACTIVE_COOL_TARGET_TEMP_C 45.0F #define ROF_ACTIVE_COOL_BELOW_TEMP_TIMEOUT_MS ( 30 * MS_PER_SECOND ) @@ -62,6 +66,14 @@ #define ROF_ACTIVE_COOL_RSRVR_MIX_DRAIN_TIMEOUT_MS ( 2.5 * SEC_PER_MIN * MS_PER_SECOND ) #define ROF_ACTIVE_COOL_MIX_DRAIN_STEADY_TIMEOUT_MS ( 15 * MS_PER_SECOND ) +// Reservoir cool down defines +#define RSRVR_ACTIVE_COOL_TARGET_FLOW_LPM 0.8F +#define RSRVR_ACTIVE_COOL_MAX_ALLOWED_PRESSURE_PSI 130 +#define RSRVR_ACTIVE_COOL_FILL_TARGET_FILL_ML 1850.0F +#define RSRVR_ACTIVE_COOL_TARGET_TEMP_C 40.0F +#define RSRVR_ACTIVE_COOL_BELOW_TARGET_TEMP_TIMEOUT_MS ( 15 * MS_PER_SECOND ) +#define RSRVR_ACTIVE_COOL_TARGET_TEMP_TIMEOUT_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) + static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T heatDisinfectActiveCoolState; ///< Mode heat disinfect active cool state. static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T heatDisinfectActiceCoolPrevState; ///< Mode heat disinfect active cool previous state. static U32 stateStartTimeMS; ///< Mode heat disinfect active cool state timer in milliseconds. @@ -71,14 +83,15 @@ static ALARM_ID_T alarmDetectedPendingTrigger; ///< Mode heat disinfect active cool pending alarm trigger. static DIS_RSRVR_STATUS_T rsrvrsStatus; ///< Mode heat disinfect active cool reservoirs status. static U32 tempBelowTargetStartTimeMS; ///< Mode heat disinfect active cool temperature below target time in milliseconds. +static CANCELLATION_MODE_T cancellationMode; ///< Cancellation mode. // ********** private function prototypes ********** static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolStartState( void ); -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolFillR1State( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolMixDrainR1State( void ); -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolFillR2State( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolMixDrainR2State( void ); +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolFillR1State( void ); +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolFillR2State( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR2FillR1ToR2State( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR1FillR2ToR1State( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR1State( void ); @@ -92,8 +105,11 @@ static void publishHeatDisinfectActiveCoolData( void ); static void monitorModeHeatDisinfectActiveCool( void ); static void setHeatDisinfectActiveCoolActuators( DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMgmtTimeout( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrPartialFill( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMgmtTimeoutStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrPartialFillStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMixDrainStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrFillStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrDrainStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); /*********************************************************************//** * @brief @@ -110,16 +126,18 @@ { heatDisinfectActiveCoolState = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_START; heatDisinfectActiceCoolPrevState = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_START; - stateStartTimeMS = 0; + stateStartTimeMS = getMSTimerCount(); dataPublishCounter = 0; - overallHeatDisinfectActiveCoolTimer = 0; + overallHeatDisinfectActiveCoolTimer = getMSTimerCount(); ROFCoolingTimer = 0; alarmDetectedPendingTrigger = ALARM_ID_NO_ALARM; - tempBelowTargetStartTimeMS = 0; + tempBelowTargetStartTimeMS = getMSTimerCount(); + cancellationMode = CANCELLATION_MODE_NONE; // Initialize the reservoirs rsrvrsStatus.rsrvrFillStableTime = 0; rsrvrsStatus.rsrvrFillStableTimeoutMS = RSRVRS_FULL_STABLE_TIME_COUNT; + rsrvrsStatus.isThisInitialDrain = TRUE; rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].drainInit = FALSE; rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].loadCell = LOAD_CELL_RESERVOIR_1_PRIMARY; rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = NUM_OF_DG_RESERVOIR_STATUS; @@ -170,22 +188,22 @@ heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolStartState(); break; - case DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE: - heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolFillR1State(); - break; - case DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE: heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolMixDrainR1State(); break; - case DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE: - heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolFillR2State(); - break; - case DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE: heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolMixDrainR2State(); break; + case DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE: + heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolFillR1State(); + break; + + case DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE: + heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolFillR2State(); + break; + case DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE: heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolDrainR2FillR1ToR2State(); break; @@ -336,145 +354,93 @@ * The handleHeatDisinfectActiveCoolStartState function handles the heat * disinfect active cool start state. * @details Inputs: none - * @details Outputs: overallHeatDisinfectActiveCoolTimer, stateTimer + * @details Outputs: stateStartTimeMS, rsrvrsStatus * @return next state of the heat disinfect active cool state machine *************************************************************************/ static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolStartState( void ) { - DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE; - setHeatDisinfectActiveCoolActuators( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE ); + DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE; - overallHeatDisinfectActiveCoolTimer = getMSTimerCount(); + setHeatDisinfectActiveCoolActuators( state ); + stateStartTimeMS = getMSTimerCount(); - rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_BELOW_TARGET; - tempBelowTargetStartTimeMS = getMSTimerCount(); + rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_ABOVE_TARGET; - /* TODO remove when cooling was at least tested once. - * DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COOL_DOWN_RO_FILTER; - overallHeatDisinfectActiveCoolTimer = getMSTimerCount(); - ROFCoolingTimer = 0; - stateTimer = getMSTimerCount(); - - // De-energize all the valves that are not in the path anymore - // and wait for the RO membrane to be cooled down. - setValveState( VPI, VALVE_STATE_CLOSED ); - setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VBF, VALVE_STATE_OPEN ); - setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); - setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - setROPumpTargetFlowRateLPM( ROF_ACTIVE_COOL_DOWN_TARGET_FLOW_LPM, ROF_ACTIVE_COOL_DOWN_MAX_PRESSURE_PSI );*/ - return state; } -// TODO add doxygen -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolFillR1State( void ) +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolMixDrainR1State( void ) { - DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE; - F32 THdTemperatureC = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); + DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE; - if ( THdTemperatureC > ROF_ACTIVE_COOL_TARGET_TEMP_C ) - { - tempBelowTargetStartTimeMS = getMSTimerCount(); - } + state = checkRsrvrMixDrainStatus( DG_RESERVOIR_1, state ); - if ( DG_RESERVOIR_BELOW_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus ) - { - rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = getDisinfectRsrvrFillStatus( DG_RESERVOIR_1, &rsrvrsStatus, ROF_ACTIVE_COOL_TARGET_RSRVR_FILL_ML, - RSRVR_FILL_TIMEOUT_MS, stateStartTimeMS ); - } - else if ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus ) - { - if ( TRUE == didTimeout( tempBelowTargetStartTimeMS, ROF_ACTIVE_COOL_BELOW_TEMP_TIMEOUT_MS ) ) - { - setHeatDisinfectActiveCoolActuators( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE ); - tempBelowTargetStartTimeMS = 0; - stateStartTimeMS = getMSTimerCount(); - state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE; - } - else - { - deenergizeActuators( NO_PARK_CONC_PUMPS ); - rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_ABOVE_TARGET; - tempBelowTargetStartTimeMS = 0; - stateStartTimeMS = getMSTimerCount(); - state = DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE; - } - } - - state = checkRsrvrMgmtTimeout( DG_RESERVOIR_1, state ); - return state; } -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolMixDrainR1State( void ) +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolMixDrainR2State( void ) { - DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE; + DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE; - if ( ( TRUE == didTimeout( stateStartTimeMS, ROF_ACTIVE_COOL_MIX_DRAIN_VALVE_ON_TIMEOUT_MS ) ) && ( FALSE == isDrainPumpOn() ) ) - { - setHeatDisinfectActiveCoolActuators( DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE ); - } - else if ( ( DG_RESERVOIR_ABOVE_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus ) && ( TRUE == isDrainPumpOn() ) ) - { - rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = getDisinfectRsrvrDrainStatus( DG_RESERVOIR_1, &rsrvrsStatus, - ROF_ACTIVE_COOL_MIX_DRAIN_STEADY_TIMEOUT_MS, - ROF_ACTIVE_COOL_RSRVR_MIX_DRAIN_TIMEOUT_MS, stateStartTimeMS ); - } - else if ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus ) - { - setHeatDisinfectActiveCoolActuators( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE ); - rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus = DG_RESERVOIR_BELOW_TARGET; - stateStartTimeMS = getMSTimerCount(); - state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE; - } + tempBelowTargetStartTimeMS = getMSTimerCount(); + state = checkRsrvrMixDrainStatus( DG_RESERVOIR_2, state ); - state = checkRsrvrMgmtTimeout( DG_RESERVOIR_1, state ); - return state; } -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolFillR2State( void ) +// TODO add doxygen +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolFillR1State( void ) { - DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE; + DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE; + state = checkRsrvrPartialFillStatus( DG_RESERVOIR_1, state ); + return state; } -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolMixDrainR2State( void ) +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolFillR2State( void ) { - DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE; + DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE; + state = checkRsrvrPartialFillStatus( DG_RESERVOIR_2, state ); + return state; } + static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR2FillR1ToR2State( void ) { DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE; + state = checkRsrvrFillStatus( DG_RESERVOIR_1, state ); + return state; } static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR1FillR2ToR1State( void ) { DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE; + state = checkRsrvrFillStatus( DG_RESERVOIR_2, state ); + return state; } static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR1State( void ) { DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE; + state = checkRsrvrDrainStatus( DG_RESERVOIR_1, state ); + return state; } static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR2State( void ) { DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_STATE; + state = checkRsrvrDrainStatus( DG_RESERVOIR_2, state ); + return state; } @@ -554,7 +520,89 @@ static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolCancelWaterPathState( void ) { DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_WATER_PATH_STATE; + U32 drainSteadyTimeoutMS = RSRVR_DRAIN_STEADY_TIMEOUT_MS; + U32 drainTimeoutMS = RSRVR_DRAIN_TIMEOUT_MS; + if ( CANCELLATION_MODE_NONE == cancellationMode ) + { + U32 targetRPM = RSRVR_DRAIN_TARGET_RPM; + F32 TDi = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); + F32 TRo = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); + + // The two sensors must be less than a threshold to decide if mix drain is needed to normal drain + if ( ( TDi >= RSRVR_MIX_DRAIN_TEMPERATURE_THRESHOLD_C ) && ( TRo >= RSRVR_MIX_DRAIN_TEMPERATURE_THRESHOLD_C ) ) + { + // The fluid is hot so this is a mix drain. Set the VPd to direct the cold inlet fluid to drain + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); + + drainSteadyTimeoutMS = ROF_ACTIVE_COOL_MIX_DRAIN_STEADY_TIMEOUT_MS; + drainTimeoutMS = RSRVR_MIX_DRAIN_TIMEOUT_MS; + targetRPM = ROF_ACTIVE_COOL_TARGET_DARIN_RPM; + cancellationMode = CANCELLATION_MODE_HOT; + } + + rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_ABOVE_TARGET; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus = DG_RESERVOIR_ABOVE_TARGET; + + // The drain is set to start from reservoir 2 since all the actuators have been de-energized + // Set the drain valve to reservoir 2 + setValveState( VRD2, VALVE_STATE_OPEN ); + setDrainPumpTargetRPM( targetRPM ); + + // Start the timer for drain timeout + stateStartTimeMS = getMSTimerCount(); + } + + // If reservoir 2 is empty, set to drain reservoir 1 + if ( DG_RESERVOIR_ABOVE_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus ) + { + // If the cancellation water path cannot be done, got to basic cancellation path + rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus = getDisinfectRsrvrDrainStatus( DG_RESERVOIR_2, &rsrvrsStatus, drainSteadyTimeoutMS, + drainTimeoutMS, stateStartTimeMS ); + + if ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus ) + { + // Set the drain valve to reservoir 1 and close reservoir 2 + setValveState( VRD1, VALVE_STATE_OPEN ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + } + } + else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus ) + { + // Stop the actuators that are running before going to basic cancellation path + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + signalDrainPumpHardStop(); + + state = DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_BASIC_PATH_STATE; + } + + // If reservoir 2 has already been drained and reservoir 1 is empty, reset and switch to complete + if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus ) && + ( DG_RESERVOIR_ABOVE_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus ) ) + { + // If the cancellation water path cannot be done, got to basic cancellation path + rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = getDisinfectRsrvrDrainStatus( DG_RESERVOIR_1, &rsrvrsStatus, drainSteadyTimeoutMS, + drainTimeoutMS, stateStartTimeMS ); + + if ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus ) + { + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + signalDrainPumpHardStop(); + failHeatDisinfectActiveCool(); + } + } + else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus ) + { + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + signalDrainPumpHardStop(); + + state = DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_BASIC_PATH_STATE; + } + return state; } @@ -660,35 +708,33 @@ { switch ( state ) { - case DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE: + case DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE: // Valves setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_CLOSED ); setValveState( VSP, VALVE_STATE_CLOSED ); - setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); + setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); - setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); - setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRD1, VALVE_STATE_OPEN ); setValveState( VRD2, VALVE_STATE_CLOSED ); - setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); - setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); // UV reactors turnOnUVReactor( INLET_UV_REACTOR ); turnOffUVReactor( OUTLET_UV_REACTOR ); // Concentrate pumps - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN ); - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_SPEED_ML_PER_MIN ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); // RO pump - setROPumpTargetFlowRateLPM( ROF_ACTIVE_COOL_DOWN_TARGET_FLOW_LPM, ROF_ACTIVE_COOL_DOWN_MAX_PRESSURE_PSI ); + signalROPumpHardStop(); // Drain pump - signalDrainPumpHardStop(); + setDrainPumpTargetRPM( ROF_ACTIVE_COOL_TARGET_DARIN_RPM ); break; - case DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE: + case DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE: // Valves setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_CLOSED ); @@ -698,22 +744,50 @@ setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRD1, VALVE_STATE_OPEN ); - setValveState( VRD2, VALVE_STATE_CLOSED ); + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_OPEN ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); // UV reactors turnOnUVReactor( INLET_UV_REACTOR ); turnOffUVReactor( OUTLET_UV_REACTOR ); // Concentrate pumps - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID , NO_PARK_CONC_PUMPS ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB , NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); // RO pump signalROPumpHardStop(); // Drain pump setDrainPumpTargetRPM( ROF_ACTIVE_COOL_TARGET_DARIN_RPM ); break; + case DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE: + // Valves + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VBF, VALVE_STATE_CLOSED ); + setValveState( VSP, VALVE_STATE_CLOSED ); + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); + setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); + // UV reactors + turnOnUVReactor( INLET_UV_REACTOR ); + turnOffUVReactor( OUTLET_UV_REACTOR ); + // Concentrate pumps + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_SPEED_ML_PER_MIN ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + // RO pump + setROPumpTargetFlowRateLPM( ROF_ACTIVE_COOL_TARGET_FLOW_LPM, ROF_ACTIVE_COOL_MAX_ALLOWED_PRESSURE_PSI ); + // Drain pump + signalDrainPumpHardStop(); + break; + case DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE: // Valves setValveState( VPI, VALVE_STATE_OPEN ); @@ -737,14 +811,11 @@ requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); // RO pump - setROPumpTargetFlowRateLPM( ROF_ACTIVE_COOL_DOWN_TARGET_FLOW_LPM, ROF_ACTIVE_COOL_DOWN_MAX_PRESSURE_PSI ); + setROPumpTargetFlowRateLPM( ROF_ACTIVE_COOL_TARGET_FLOW_LPM, ROF_ACTIVE_COOL_MAX_ALLOWED_PRESSURE_PSI ); // Drain pump signalDrainPumpHardStop(); break; - case DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE: - break; - case DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE: // Valves setValveState( VPI, VALVE_STATE_OPEN ); @@ -753,33 +824,104 @@ setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); - setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_OPEN ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); // UV reactors turnOnUVReactor( INLET_UV_REACTOR ); - turnOffUVReactor( OUTLET_UV_REACTOR ); + turnOnUVReactor( OUTLET_UV_REACTOR ); // Concentrate pumps setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN ); setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_SPEED_ML_PER_MIN ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); // RO pump - setROPumpTargetFlowRateLPM( ROF_ACTIVE_COOL_DOWN_TARGET_FLOW_LPM, ROF_ACTIVE_COOL_DOWN_MAX_PRESSURE_PSI ); + setROPumpTargetFlowRateLPM( RSRVR_ACTIVE_COOL_TARGET_FLOW_LPM, RSRVR_ACTIVE_COOL_MAX_ALLOWED_PRESSURE_PSI ); // Drain pump - signalDrainPumpHardStop(); + setDrainPumpTargetRPM( RSRVR_DRAIN_TARGET_RPM ); break; case DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE: + // Valves + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VBF, VALVE_STATE_CLOSED ); + setValveState( VSP, VALVE_STATE_CLOSED ); + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); + setValveState( VRD1, VALVE_STATE_OPEN ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + // UV reactors + turnOnUVReactor( INLET_UV_REACTOR ); + turnOnUVReactor( OUTLET_UV_REACTOR ); + // Concentrate pumps + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_SPEED_ML_PER_MIN ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + // RO pump + setROPumpTargetFlowRateLPM( RSRVR_ACTIVE_COOL_TARGET_FLOW_LPM, RSRVR_ACTIVE_COOL_MAX_ALLOWED_PRESSURE_PSI ); + // Drain pump + setDrainPumpTargetRPM( RSRVR_DRAIN_TARGET_RPM ); break; case DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE: + // Valves + setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VBF, VALVE_STATE_CLOSED ); + setValveState( VSP, VALVE_STATE_CLOSED ); + setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRD1, VALVE_STATE_OPEN ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + // UV reactors + turnOffUVReactor( INLET_UV_REACTOR ); + turnOffUVReactor( OUTLET_UV_REACTOR ); + // Concentrate pumps + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID , NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB , NO_PARK_CONC_PUMPS ); + // RO pump + signalROPumpHardStop(); + // Drain pump + setDrainPumpTargetRPM( RSRVR_DRAIN_TARGET_RPM ); break; case DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_STATE: + // Valves + setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VBF, VALVE_STATE_CLOSED ); + setValveState( VSP, VALVE_STATE_CLOSED ); + setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_OPEN ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + // UV reactors + turnOffUVReactor( INLET_UV_REACTOR ); + turnOffUVReactor( OUTLET_UV_REACTOR ); + // Concentrate pumps + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); + // RO pump + signalROPumpHardStop(); + // Drain pump + setDrainPumpTargetRPM( RSRVR_DRAIN_TARGET_RPM ); break; case DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_START: @@ -791,18 +933,19 @@ } } -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMgmtTimeout( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ) +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMgmtTimeoutStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ) { if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) { + deenergizeActuators( NO_PARK_CONC_PUMPS ); heatDisinfectActiceCoolPrevState = state; state = DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_WATER_PATH_STATE; } return state; } -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrPartialFill( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ) +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrPartialFillStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ) { F32 THdTemperatureC = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); @@ -821,24 +964,163 @@ if ( TRUE == didTimeout( tempBelowTargetStartTimeMS, ROF_ACTIVE_COOL_BELOW_TEMP_TIMEOUT_MS ) ) { stateStartTimeMS = getMSTimerCount(); - state = ( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE == state ? - DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE : DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE ); + + if ( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE == state ) + { + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE; + } + else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE == state ) + { + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE; + } setHeatDisinfectActiveCoolActuators( state ); } else { deenergizeActuators( NO_PARK_CONC_PUMPS ); rsrvrsStatus.rsrvr[ rsrvrID ].rStatus = DG_RESERVOIR_ABOVE_TARGET; stateStartTimeMS = getMSTimerCount(); - state = ( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE == state ? - DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE : DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE ); + + if ( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE == state ) + { + state = DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE; + } + else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE == state ) + { + state = DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE; + } } } - state = checkRsrvrMgmtTimeout( rsrvrID, state ); + state = checkRsrvrMgmtTimeoutStatus( rsrvrID, state ); return state; } +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMixDrainStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ) +{ + if ( ( TRUE == didTimeout( stateStartTimeMS, ROF_ACTIVE_COOL_MIX_DRAIN_VALVE_ON_TIMEOUT_MS ) ) && ( FALSE == isDrainPumpOn() ) ) + { + setHeatDisinfectActiveCoolActuators( state ); + } + else if ( ( DG_RESERVOIR_ABOVE_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) && ( TRUE == isDrainPumpOn() ) ) + { + rsrvrsStatus.rsrvr[ rsrvrID ].rStatus = getDisinfectRsrvrDrainStatus( rsrvrID, &rsrvrsStatus, ROF_ACTIVE_COOL_MIX_DRAIN_STEADY_TIMEOUT_MS, + ROF_ACTIVE_COOL_RSRVR_MIX_DRAIN_TIMEOUT_MS, stateStartTimeMS ); + } + else if ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) + { + DG_RESERVOIR_ID_T switchRsrvrID = ( DG_RESERVOIR_1 == rsrvrID ? DG_RESERVOIR_2 : DG_RESERVOIR_1 ); + + if ( TRUE == rsrvrsStatus.isThisInitialDrain ) + { + if ( DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE == state ) + { + deenergizeActuators( NO_PARK_CONC_PUMPS ); + rsrvrsStatus.rsrvr[ switchRsrvrID ].rStatus = DG_RESERVOIR_ABOVE_TARGET; + state = DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE; + } + else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE == state ) + { + rsrvrsStatus.rsrvr[ switchRsrvrID ].rStatus = DG_RESERVOIR_BELOW_TARGET; + rsrvrsStatus.isThisInitialDrain = FALSE; + state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE; + } + } + else + { + rsrvrsStatus.rsrvr[ switchRsrvrID ].rStatus = DG_RESERVOIR_BELOW_TARGET; + + if ( DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE == state ) + { + state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE; + } + else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE == state ) + { + state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE; + } + setHeatDisinfectActiveCoolActuators( state ); + } + + stateStartTimeMS = getMSTimerCount(); + } + + state = checkRsrvrMgmtTimeoutStatus( rsrvrID, state ); + + return state; +} + +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrFillStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ) +{ + F32 TDiTemperatureC = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); + + if ( TDiTemperatureC > RSRVR_ACTIVE_COOL_TARGET_TEMP_C ) + { + tempBelowTargetStartTimeMS = getMSTimerCount(); + } + + if ( DG_RESERVOIR_BELOW_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) + { + rsrvrsStatus.rsrvr[ rsrvrID ].rStatus = getDisinfectRsrvrFillStatus( rsrvrID, &rsrvrsStatus, RSRVR_ACTIVE_COOL_FILL_TARGET_FILL_ML, + RSRVR_FILL_TIMEOUT_MS, stateStartTimeMS ); + } + else if ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) + { + if ( TRUE == didTimeout( tempBelowTargetStartTimeMS, RSRVR_ACTIVE_COOL_BELOW_TARGET_TEMP_TIMEOUT_MS ) ) + { + stateStartTimeMS = getMSTimerCount(); + + if ( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE == state ) + { + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE; + } + else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE == state ) + { + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE; + } + setHeatDisinfectActiveCoolActuators( state ); + } + else if ( TRUE == didTimeout( stateStartTimeMS, DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE ) ) + { + state = DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_WATER_PATH_STATE; + } + } + + state = checkRsrvrMgmtTimeoutStatus( rsrvrID, state ); + + return state; +} + +static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrDrainStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ) +{ + if ( DG_RESERVOIR_ABOVE_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) + { + rsrvrsStatus.rsrvr[ rsrvrID ].rStatus = getDisinfectRsrvrDrainStatus( rsrvrID, &rsrvrsStatus, RSRVR_DRAIN_STEADY_TIMEOUT_MS, + RSRVR_DRAIN_TIMEOUT_MS, stateStartTimeMS ); + } + else if ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) + { + if ( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE == state ) + { + DG_RESERVOIR_ID_T switchRsrvrID = ( DG_RESERVOIR_1 == rsrvrID ? DG_RESERVOIR_2 : DG_RESERVOIR_1 ); + + rsrvrsStatus.rsrvr[ switchRsrvrID ].rStatus = DG_RESERVOIR_ABOVE_TARGET; + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_STATE; + setHeatDisinfectActiveCoolActuators( state ); + } + else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_STATE == state ) + { + deenergizeActuators( NO_PARK_CONC_PUMPS ); + state = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COMPLETE; + } + + stateStartTimeMS = getMSTimerCount(); + } + + state = checkRsrvrMgmtTimeoutStatus( rsrvrID, state ); + + return state; +} + /**@}*/