Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r6dde3576087b002b0b94879ef1677fc19e563899 -rfb79cc82233d712817d0c9ff6567253aa65bd622 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 6dde3576087b002b0b94879ef1677fc19e563899) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision fb79cc82233d712817d0c9ff6567253aa65bd622) @@ -145,17 +145,8 @@ static U32 dataPublishCounter = 0; ///< Heat Disinfect data publish counter. static CANCELLATION_MODES_T cancellationMode = CANCELLATION_MODE_NONE; ///< Cancellation mode. static U32 rsrvrFillStableTimeCounter = 0; ///< Reservoirs fill stable time counter. +static ALARM_ID_T alarm; ///< Heat disinfect alarm to raise. -// TODO test code -static U32 tempCounter = 0; -static BOOL endone = FALSE; -static BOOL dedone = FALSE; -static BOOL vro = FALSE; -static BOOL vrd = FALSE; -static BOOL vri = FALSE; -static BOOL vrf = FALSE; -// TODO test code - // ********** private function prototypes ********** static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectStartState( void ); @@ -181,7 +172,7 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeWaterPath( void ); static void resetActuators( void ); -static void setModeToFailed( DG_HEAT_DISINFECT_STATE_T state ); +static void setModeToFailed( void ); static RESERVOIRS_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout, DG_HEAT_DISINFECT_STATE_T cancellationState ); static RESERVOIRS_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout, DG_HEAT_DISINFECT_STATE_T cancellationState ); @@ -196,32 +187,28 @@ * @details Outputs: heatDisinfectState, stateTimer, isThisLastDrain, * stateTrialCounter, areTempSensorsInRange, rsrvr1Status, rsrvr2Status, * R1HeatDisinfectVol, R2HeatDisinfectVol, hasPostHeatDisinfectWaitStarted, - * overallHeatDisinfectTimer TODO fill up as we go + * overallHeatDisinfectTimer, cancellationMode, rsrvrFillStableTimeCounter, + * heatDisinfectPostTimer, isPartialDisinfectInProgress * @return none *************************************************************************/ void initHeatDisinfectMode( void ) { - heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; - prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; - stateTimer = 0; - isThisLastDrain = FALSE; - stateTrialCounter = 0; - areTempSensorsInRange = FALSE; - rsrvr1Status = RESERVOIR_STATUS_UNKNOWN; - rsrvr2Status = RESERVOIR_STATUS_UNKNOWN; - R1HeatDisinfectVol = 0.0; - R2HeatDisinfectVol = 0.0; - hasPostDisinfectWaitStarted = FALSE; - overallHeatDisinfectTimer = 0; - cancellationMode = CANCELLATION_MODE_NONE; - rsrvrFillStableTimeCounter = 0; - heatDisinfectPostTimer = 0; - isPartialDisinfectInProgress = FALSE; - - tempCounter = 0; - dedone = FALSE; - endone = FALSE; - vro = vrd = vri = vrf = FALSE; + heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; + prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; + stateTimer = 0; + isThisLastDrain = FALSE; + stateTrialCounter = 0; + areTempSensorsInRange = FALSE; + rsrvr1Status = RESERVOIR_STATUS_UNKNOWN; + rsrvr2Status = RESERVOIR_STATUS_UNKNOWN; + R1HeatDisinfectVol = 0.0; + R2HeatDisinfectVol = 0.0; + hasPostDisinfectWaitStarted = FALSE; + overallHeatDisinfectTimer = 0; + cancellationMode = CANCELLATION_MODE_NONE; + rsrvrFillStableTimeCounter = 0; + heatDisinfectPostTimer = 0; + isPartialDisinfectInProgress = FALSE; } /*********************************************************************//** @@ -247,8 +234,6 @@ *************************************************************************/ U32 execHeatDisinfectMode( void ) { - //checkInletPressureFault(); // TODO what is this? - switch ( heatDisinfectState ) { case DG_HEAT_DISINFECT_STATE_START: @@ -413,91 +398,11 @@ if ( ppiPressure < MIN_INLET_PRESSURE_PSI && fabs( TDiTemp - TRoTemp ) > MAX_START_STATE_TEMP_SENSORS_DIFF_C ) { prevHeatDisinfectState = state; + alarm = ALARM_ID_DG_HEAT_DISINFECT_INLET_PRES_AND_TEMP_SNSRS_OUT; state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; } else { - // TODO Test code remove - /*if ( endone != TRUE ) - { - if ( vro != TRUE ) - { - setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); - vro = TRUE; - tempCounter = 0; - } - else if ( vrd != TRUE && tempCounter > 5 ) - { - setValveState( VRD, VALVE_STATE_R1_C_TO_NC ); - vrd = TRUE; - tempCounter = 0; - } - else if ( vri != TRUE && tempCounter > 5 ) - { - setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); - vri = TRUE; - tempCounter = 0; - } - else if ( vrf != TRUE && tempCounter > 5 ) - { - setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); - vrf = TRUE; - tempCounter = 0; - endone = TRUE; - } - - tempCounter++; - state = DG_HEAT_DISINFECT_STATE_START; - } - else if ( endone == TRUE && dedone != TRUE ) - { - if ( vro == TRUE ) - { - setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - vro = FALSE; - tempCounter = 0; - } - else if ( vrd == TRUE && tempCounter > 5 ) - { - setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); - vrd = FALSE; - tempCounter = 0; - } - else if ( vri == TRUE && tempCounter > 5 ) - { - setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); - vri = FALSE; - tempCounter = 0; - } - else if ( vrf == TRUE && tempCounter > 5 ) - { - setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - vrf = FALSE; - tempCounter = 0; - dedone = TRUE; - } - - tempCounter++; - state = DG_HEAT_DISINFECT_STATE_START; - } - - if ( dedone == TRUE && endone == TRUE ) - { - // Close VPi to prevent wasting water - setValveState( VPI, VALVE_STATE_CLOSED ); - // Request a tare for reservoir 1 - tareReservoir(); - // Set the actuators to drain R1 - setValveState( VRD, VALVE_STATE_R1_C_TO_NC ); - setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - - rsrvrFillStableTimeCounter = 0; - // Assume reservoir 1 is full and drain it - rsrvr1Status = RESERVOIR_STATUS_FULL; - stateTimer = getMSTimerCount(); - }*/ - // TODO test code remove - // Close VPi to prevent wasting water setValveState( VPI, VALVE_STATE_CLOSED ); // Request a tare for reservoir 1 @@ -645,6 +550,7 @@ // Couldn't get a good water sample after a couple of trials and the disinfect cycle failed else { + alarm = ALARM_ID_DG_HEAT_DISINFECT_INLET_COND_AND_TEMP_OUT; prevHeatDisinfectState = state; state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; } @@ -690,6 +596,7 @@ // State failed. Cancel heat disinfect mode else { + alarm = ALARM_ID_DG_TEMP_SENSORS_DIFF_OUT_OF_RANGE; prevHeatDisinfectState = state; state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; } @@ -738,7 +645,8 @@ // If R1 is not full, keep monitoring for R1 level and timeout if ( rsrvr1Status == RESERVOIR_STATUS_EMPTY ) { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, + DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); } // Once R1 is full, keep monitoring for R2 level and timeout else if( rsrvr1Status == RESERVOIR_STATUS_FULL ) @@ -794,7 +702,8 @@ // First reservoir 2 must be completely full if ( rsrvr2Status == RESERVOIR_STATUS_EMPTY ) { - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, + DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); } // Once R2 is full, R1 must be partially full else if( rsrvr2Status == RESERVOIR_STATUS_FULL ) @@ -841,7 +750,7 @@ if ( rsrvr2Status == RESERVOIR_STATUS_FULL ) { rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, - DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH ); } else if ( rsrvr2Status == RESERVOIR_STATUS_EMPTY ) { @@ -871,7 +780,7 @@ if ( rsrvr1Status == RESERVOIR_STATUS_FULL ) { rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, - DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH ); } else if ( rsrvr1Status == RESERVOIR_STATUS_EMPTY ) { @@ -917,7 +826,8 @@ // First reservoir 1 must be full if ( rsrvr1Status == RESERVOIR_STATUS_EMPTY ) { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, + DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); } // Once reservoir 1 is full, check the status of reservoir 2 since the water overflows to reservoir 2 else if ( rsrvr1Status == RESERVOIR_STATUS_FULL ) @@ -932,7 +842,6 @@ setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NC ); - //setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); @@ -1026,7 +935,8 @@ } else if ( rsrvr1Status == RESERVOIR_STATUS_FULL ) { - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, + DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); if ( rsrvr2Status == RESERVOIR_STATUS_FULL ) { @@ -1122,7 +1032,7 @@ if ( rsrvr1Status == RESERVOIR_STATUS_FULL ) { rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, - DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH ); } else if ( rsrvr1Status == RESERVOIR_STATUS_EMPTY ) { @@ -1152,7 +1062,7 @@ if ( rsrvr2Status == RESERVOIR_STATUS_FULL ) { rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, - DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH ); } else if ( rsrvr2Status == RESERVOIR_STATUS_EMPTY ) { @@ -1178,7 +1088,7 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; - F32 ThdTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); //TODO change this to actual TPm sensor later + F32 ThdTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); //TODO change this to actual THd sensor later // Check if the coldest spot temperature is less than 45 C so the RO filter // can safely run fluid through @@ -1218,7 +1128,8 @@ if ( rsrvr1Status == RESERVOIR_STATUS_EMPTY ) { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, + DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); } else if ( rsrvr1Status == RESERVOIR_STATUS_FULL ) { @@ -1270,7 +1181,8 @@ // First reservoir 2 must be completely full if ( rsrvr2Status == RESERVOIR_STATUS_EMPTY ) { - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, + DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ); } // Once reservoir 2 is completely full, monitor reservoir 1 else if ( rsrvr2Status == RESERVOIR_STATUS_FULL ) @@ -1344,8 +1256,7 @@ // Set the cancellation mode cancellationMode = CANCELLATION_MODE_BASIC; - // Pass the previous heat disinfect state for alarm report - setModeToFailed( prevHeatDisinfectState ); + setModeToFailed(); return state; } @@ -1362,7 +1273,7 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; - /*if ( cancellationMode == CANCELLATION_MODE_NONE ) + if ( cancellationMode == CANCELLATION_MODE_NONE ) { // Stop all the actuators first then decide who should run next resetActuators(); @@ -1391,9 +1302,7 @@ // The drain is set to start from reservoir 2 since all the actuators have been de-energized // Start the drain pump - // TODO for testing only remove setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - //TODo for testing only remove // Start the timer for drain timeout stateTimer = getMSTimerCount(); @@ -1402,7 +1311,9 @@ // If reservoir 2 is empty, set to drain reservoir 1 if ( rsrvr2Status == RESERVOIR_STATUS_FULL ) { - rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, state ); + // If the cancellation water path cannot be done, got to basic cancellation path + rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH ); if ( rsrvr2Status == RESERVOIR_STATUS_EMPTY ) { @@ -1414,17 +1325,18 @@ // If reservoir 2 has already been drained and reservoir 1 is empty, reset and switch to complete if ( ( rsrvr2Status == RESERVOIR_STATUS_EMPTY ) && ( rsrvr1Status == RESERVOIR_STATUS_FULL ) ) { - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, state ); + // If the cancellation water path cannot be done, got to basic cancellation path + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS, + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH ); if ( rsrvr1Status == RESERVOIR_STATUS_EMPTY ) { // Done with heat disinfect mode state = DG_HEAT_DISINFECT_STATE_COMPLETE; - // Pass the previous heat disinfect state for alarm report - setModeToFailed( prevHeatDisinfectState ); + setModeToFailed(); } - }*/ + } return state; } @@ -1468,14 +1380,13 @@ * @brief * The setModeToFailed function sets the heat disinfect mode to failed * by changing the state to complete. - * @details Inputs: heatDisinfectState - * @details Outputs: heatDisinfectState - * @param failedStated which is the state heat disinfect mode failed + * @details Inputs: alarm, prevHeatDisinfectState + * @details Outputs: none * @return none *************************************************************************/ -static void setModeToFailed( DG_HEAT_DISINFECT_STATE_T failedState ) +static void setModeToFailed( void ) { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_HEAT_DISINFECT_CYCLE_FAILED, failedState ) + SET_ALARM_WITH_1_U32_DATA( alarm, prevHeatDisinfectState ) } /*********************************************************************//** @@ -1517,6 +1428,7 @@ else if ( didTimeout( stateTimer, timeout ) ) { // Failed to fill ontime. Update the previous heat disinfect state and transition to basic cancellation + alarm = ALARM_ID_DG_RESERVOIR_FILL_TIMEOUT; prevHeatDisinfectState = heatDisinfectState; heatDisinfectState = cancellationState; status = RESERVOIR_STATUS_UNKNOWN; @@ -1552,6 +1464,7 @@ // Failed to drain ontime. Update the previous heat disinfect state and transition to basic cancellation prevHeatDisinfectState = heatDisinfectState; heatDisinfectState = cancellationState; + alarm = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; status = RESERVOIR_STATUS_UNKNOWN; } @@ -1577,7 +1490,7 @@ BOOL isR2OutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - R2HeatDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML; // Check if either reservoir 1 or reservoir 2 are losing volume more than allowed volume - /*if ( isR1OutOfRange || isR2OutOfRange ) + if ( isR1OutOfRange || isR2OutOfRange ) { // If the leak is the first time after a while, set the flag and start the timer if ( FALSE == areRsrvrsLeaking ) @@ -1589,14 +1502,15 @@ else if ( didTimeout( rsrvrsVolMonitorTimer, RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ) ) { areRsrvrsLeaking = FALSE; + alarm = ALARM_ID_DG_RESERVOIR_LEAK_TIMEOUT; status = HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT; } } // Reservoirs are in range else { areRsrvrsLeaking = FALSE; - }*/ + } // If the coldest spot which is TPm is less than minimum heat disinfect temperature, // reset the heat disinfect timers and check whether heating up has timed out @@ -1609,6 +1523,7 @@ if ( didTimeout( stateTimer, HEAT_DISINFECT_START_TEMP_TIMOUT_MS ) ) { // Heating up to minimum temperature for heat disinfect failed + alarm = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; status = HEAT_DISINFECT_HEAT_UP_TIMEOUT; } } @@ -1670,8 +1585,9 @@ data.overallElapsedTime = calcTimeSince( overallHeatDisinfectTimer ); data.stateElapsedTime = calcTimeSince( stateTimer ); data.cancellationMode = (U32)cancellationMode; - data.R1FillLevel = R1HeatDisinfectVol; - data.R2FillLevel = R2HeatDisinfectVol; + data.R1FillLevel = R1HeatDisinfectVol; + data.R2FillLevel = R2HeatDisinfectVol; + // If the mode is in the actual heat disinfect states, publish the elapsed time, otherwise publish 0 to avoid confusion if ( heatDisinfectState == DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2 || heatDisinfectState == DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1 ) {