Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r2315fd382b764d7bb7de5c208d67aa86f8a1a687 -re056d7264626adbe83149a51dcca723d8feb98bf --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 2315fd382b764d7bb7de5c208d67aa86f8a1a687) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision e056d7264626adbe83149a51dcca723d8feb98bf) @@ -8,7 +8,7 @@ * @file ModeHeatDisinfect.c * * @author (last) Bill Bracken -* @date (last) 22-Aug-2022 +* @date (last) 26-Oct-2022 * * @author (original) Sean * @date (original) 20-Apr-2020 @@ -19,6 +19,7 @@ #include "ConcentratePumps.h" #include "ConductivitySensors.h" +#include "CPLD.h" #include "DrainPump.h" #include "Heaters.h" #include "LoadCell.h" @@ -38,15 +39,12 @@ #include "Timers.h" #include "UVReactors.h" #include "Valves.h" -#include "CPLD.h" /** * @addtogroup DGHeatDisinfectMode * @{ */ -// TODO add the cooling, test the higher target flow to reduce the gradient - // ********** private definitions ********** // General defines @@ -64,7 +62,7 @@ // Flush drain path state defines #define FLUSH_DRAIN_WAIT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. -#define MIN_INLET_TEMPERATURE_C 25.0F ///< Minimum water inlet temperature in C. +#define MIN_INLET_TEMPERATURE_C 15.0F ///< Minimum water inlet temperature in C. TODO original temperature was 25 C #define MAX_INLET_CONDUCTIVITY_US_PER_CM 2000.0F ///< Maximum water inlet conductivity in us/cm // Flush circulation path state defines @@ -82,7 +80,7 @@ #define RSRVRS_PARTIAL_FILL_VOL_ML 500.0F ///< Reservoirs 1 & 2 partial volume in mL. #define RSRVRS_FULL_STABLE_TIME_COUNT ( ( 4 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in counts. #define RSRVRS_FILL_UP_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. TODO original value was 5 mins -#define RSRVRS_500ML_FILL_UP_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. +#define RSRVRS_500ML_FILL_UP_TIMEOUT_MS ( 4 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. TODO original value was 2 mins #define RSRVRS_DRAIN_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. // Fill and heat water @@ -91,11 +89,13 @@ // R1 to R2 & R2 to R1 heat disinfect circulation #define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 1.3F ///< Heat disinfect target RO flow rate in L/min. +#define HEAT_DISINFECT_TARGET_RO_FLOW_TRANSFER_LPM 0.8F ///< Heat disinfect target RO flow rate in L/min when transferring between reservoirs. #define HEAT_DISINFECT_MAX_RO_PRESSURE_PSI 30 ///< Heat disinfect maximum RO pressure in psi. #define HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI 12.0F ///< Heat disinfect target drain outlet pressure in psi. +#define HEAT_DISINFECT_TARGET_DRAIN_FILL_R2_PSI 9.0F ///< Heat disinfect target drain R2 fill outplet pressure in PSI #define HEAT_DISINFECT_TIME_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time for each section in milliseconds. #define HEAT_DISINFECT_START_TEMP_TIMOUT_MS ( 4 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect reaching to minimum temperature timeout in milliseconds. -#define RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 maximum volume out of range timeout during heat disinfect. +#define RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ( 0.5F * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 maximum volume out of range timeout during heat disinfect. TODO change this to 5 seconds #define RSRVRS_MAX_TARGET_VOL_CHANGE_ML 100.0F ///< Reservoirs 1 & 2 maximum allowed volume change when full during heat disinfect. #define POST_HEAT_DISINFECT_WAIT_TIME_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect final wait time before flushing the system in milliseconds. #define HEAT_DISINFECT_MAX_TEMP_GRADIENT_C 15.0F ///< Heat disinfect maximum allowed temperature gradient in between hottest and coldest sensors. @@ -105,6 +105,7 @@ #define THD_REACH_BELOW_45_AFTER_CIRC_TIME_MS ( 5 * MS_PER_SECOND ) ///< Number of circulations that are needed to make the RO filter is below 45 C. #define ROF_COOL_DOWN_TARGET_FLOW_LPM 0.3F ///< RO filter cool down target flow in L/min. #define ROF_COOL_DOWN_CIRCULATION_TIME_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down circulation timer in milliseconds. +#define ROF_COOL_DOWN_MAX_TIME_MS ( 4 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down maximum state time in milliseconds. #define TARGET_THD_SENSOR_FOR_RINSING_C 44.0F ///< Target THd temperature sensor value before rinsing in C. // Mix drain R1 and R2 @@ -140,6 +141,13 @@ NUM_OF_HEAT_DISINFECT_STATUS ///< Number of heat disinfect status. } HEAT_DISINFECT_STATUS_T; +/// Non-volatile write structure +typedef struct +{ + BOOL hasDisStatusBeenWrittenToNV; ///< Boolean flag to indicate whether the disinfect status been written to NV or not. + BOOL hasDisCompleteDateBeenWrittenToNV; ///< Boolean flag to indicate whether the disinfect complete date been written to NV or not. +} DISINFECT_NV_OPS_T; + // ********** private data ********** static DG_HEAT_DISINFECT_STATE_T heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; ///< Current active heat disinfect state. @@ -165,12 +173,11 @@ static U32 rsrvrFillStableTimeCounter; ///< Reservoirs fill stable time counter. static ALARM_ID_T alarmDetectedPendingTrigger; ///< Heat disinfect alarm to raise. static BOOL isDrainPumpInMixDrainOn = FALSE; ///< Flag to indicate the drain pump is on during mix drain. -static U32 ROFCirculationTimer = 0; ///< RO filter circulation timer. static U32 ROFCoolingTimer = 0; ///< RO filter cooling timer. -static BOOL hasROFCirculationBeenStarted = FALSE; ///< Flag to indicate the water in RO filter has been recirculated. static U32 targetDisinfectTime = 0; ///< Target disinfect time. static BOOL haveDrainParamsBeenInit[ NUM_OF_DG_RESERVOIRS ]; ///< Boolean flag to indicate whether the drain parameters have been reset or not. static U32 tempGradOutOfRangeTimer; ///< Temperature gradient out of range start timer. +static DISINFECT_NV_OPS_T disinfectNVOps; ///< Disinfect non-volatile memory operations. // ********** private function prototypes ********** @@ -191,9 +198,11 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownROFilterState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectMixDrainR1State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectMixDrainR2State( void ); +#if 0 //wjb static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR1ToR2State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseR2ToR1AndDrainR1State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRinseCirculationState( void ); +#endif static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeBasicPathState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeWaterPathState( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCompleteState( void ); @@ -204,6 +213,7 @@ static HEAT_DISINFECT_STATUS_T getHeatDisinfectStatus( void ); static void publishHeatDisinfectData( void ); static void monitorModeHeatDisinfect( void ); +static void writeDisinfectDataToNV( void ); /*********************************************************************//** * @brief @@ -217,35 +227,35 @@ * isPartialDisinfectInProgress, isDrainPumpOnInMixDrain, * hasROFCirculationBeenStarted, ROFCirculationTimer, targetDisinfectTime * ROFCirculationCoolingCounter, concentratePumpsPrimeTimer, - * haveDrainParamsBeenInit, tempGradOutOfRangeTimer + * haveDrainParamsBeenInit, tempGradOutOfRangeTimer, disinfectNVOps * @return none *************************************************************************/ void initHeatDisinfectMode( void ) { - heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; - prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; - heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_NOT_RUNNING; - stateTimer = 0; - isThisLastDrain = FALSE; - stateTrialCounter = 0; - areTempSensorsInRange = FALSE; - rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; - rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; - R1HeatDisinfectVol = 0.0; - R2HeatDisinfectVol = 0.0; - overallHeatDisinfectTimer = 0; - cancellationMode = CANCELLATION_MODE_NONE; - rsrvrFillStableTimeCounter = 0; - isPartialDisinfectInProgress = FALSE; - isDrainPumpInMixDrainOn = FALSE; - ROFCirculationTimer = 0; - ROFCoolingTimer = 0; - hasROFCirculationBeenStarted = FALSE; - concentratePumpsPrimeTimer = 0; - targetDisinfectTime = 0; - haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; - haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; - tempGradOutOfRangeTimer = 0; + heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; + prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_NOT_RUNNING; + stateTimer = 0; + isThisLastDrain = FALSE; + stateTrialCounter = 0; + areTempSensorsInRange = FALSE; + rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; + rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; + R1HeatDisinfectVol = 0.0; + R2HeatDisinfectVol = 0.0; + overallHeatDisinfectTimer = 0; + cancellationMode = CANCELLATION_MODE_NONE; + rsrvrFillStableTimeCounter = 0; + isPartialDisinfectInProgress = FALSE; + isDrainPumpInMixDrainOn = FALSE; + ROFCoolingTimer = 0; + concentratePumpsPrimeTimer = 0; + targetDisinfectTime = 0; + haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; + haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; + tempGradOutOfRangeTimer = 0; + disinfectNVOps.hasDisCompleteDateBeenWrittenToNV = FALSE; + disinfectNVOps.hasDisStatusBeenWrittenToNV = FALSE; } /*********************************************************************//** @@ -349,6 +359,7 @@ heatDisinfectState = handleHeatDisinfectMixDrainR2State(); break; +#if 0 //wjb case DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2: heatDisinfectState = handleHeatDisinfectRinseR1ToR2State(); break; @@ -360,7 +371,7 @@ case DG_HEAT_DISINFECT_STATE_RINSE_CIRCULATION: heatDisinfectState = handleHeatDisinfectRinseCirculationState(); break; - +#endif case DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH: heatDisinfectState = handleHeatDisinfectCancelModeBasicPathState(); break; @@ -1126,6 +1137,13 @@ setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + + // Set the RO flow to maximum pressure of 30psi since it is the maximum pressure on the RO filter + // at inlet temperature > 45 C + setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_TRANSFER_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + + // Set the drain pump to control mode + setDrainPumpTargetOutletPressure( HEAT_DISINFECT_TARGET_DRAIN_FILL_R2_PSI ); // Although there is fluid in both reservoirs, but they are set to empty // to begin the transition of hot water from R1 to R2. rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; @@ -1179,7 +1197,15 @@ // Get the current volumes to be monitored during R2 to R1 heat disinfect state R1HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); R2HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + // Set the drain pump to control mode + setDrainPumpTargetOutletPressure( HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI ); + + // Set the RO flow to maximum pressure of 30psi since it is the maximum pressure on the RO filter + // at inlet temperature > 45 C + setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) @@ -1249,7 +1275,7 @@ * disinfect cool down heaters state. The state continues running the fluid * while the heaters are off for a certain period of time. * @details Inputs: stateTimer - * @details Outputs: stateTimer + * @details Outputs: stateTimer, heatDisinfectUIState * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownHeatersState( void ) @@ -1259,6 +1285,8 @@ // Set the heat disinfect UI state heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COOL_DOWN_DEVICE; + writeDisinfectDataToNV(); + if ( TRUE == didTimeout( stateTimer, POST_HEAT_DISINFECT_WAIT_TIME_MS ) ) { // Stop the drain pump and the RO pump to exit the closed loop @@ -1267,17 +1295,20 @@ // De-energize all the valves that are not in the path anymore // and wait for the RO membrane to be cooled down. - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPI, VALVE_STATE_CLOSED ); - setValveState( VBF, VALVE_STATE_CLOSED ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); - ROFCoolingTimer = getMSTimerCount(); - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; + 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_COOL_DOWN_TARGET_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + + ROFCoolingTimer = 0; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; } return state; @@ -1288,65 +1319,54 @@ * The handleHeatDisinfectCoolDownROFilterState function handles the heat * disinfect cool down RO filter state. The state monitors the temperature * at THd and if it is less than 45 C, it transitions to the next state. - * @details Inputs: stateTimer, rsrvr1Status, hasROFCirculationBeenStarted, - * ROFCirculationCoolingCounter - * @details Outputs: stateTimer, rsrvr1Status, hasROFCirculationBeenStarted, - * ROFCirculationCoolingCounter + * @details Inputs: stateTimer, ROFCoolingTimer + * @details Outputs: stateTimer, ROFcoolingTimer, heatDisinfectUIState * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownROFilterState( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; + // THd is the closet sensor to the RO filter and this temperature is monitored + // until it is dropped below 45 C to be able to run fluid through the RO filter + F32 THdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); // Set the heat disinfect UI state heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COOL_DOWN_DEVICE; - // THd is the closet sensor to the RO filter and this temperature is monitored - // until it is dropped below 45 C to be able to run fluid through the RO filter - F32 THdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); + if ( ( 0 == ROFCoolingTimer ) && ( THdTemp < TARGET_THD_SENSOR_FOR_RINSING_C ) ) + { + // Temperature is below target - perform mandatory cool down + ROFCoolingTimer = getMSTimerCount(); + } + else if ( THdTemp >= TARGET_THD_SENSOR_FOR_RINSING_C ) + { + // Temperature is not below target - reset the timer and keep looking + ROFCoolingTimer = 0; + } - // Check if the coldest spot temperature is less than 45 C so the RO filter can safely run - if ( ( FALSE == isROPumpRunning() ) && ( THdTemp < TARGET_THD_SENSOR_FOR_RINSING_C ) ) + if ( ( 0 != ROFCoolingTimer ) && ( TRUE == didTimeout( ROFCoolingTimer, ROF_COOL_DOWN_CIRCULATION_TIME_MS ) ) ) { - U32 time = calcTimeSince( ROFCoolingTimer ); + // Temperature is below target, transition to next state + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VBF, VALVE_STATE_CLOSED ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - if ( time <= THD_REACH_BELOW_45_AFTER_CIRC_TIME_MS ) - { - setValveState( VPI, VALVE_STATE_OPEN ); - setValveState( VBF, VALVE_STATE_CLOSED ); - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + signalROPumpHardStop(); - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1; - } - else - { - // Set the valves to circulation. VBf is opened because the fluid in the RO filter might still be hot - 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 ); - - // Set the RO flow to maximum pressure of 30psi since it is the maximum pressure on the RO filter - // at inlet temperature > 45 C - setROPumpTargetFlowRateLPM( ROF_COOL_DOWN_TARGET_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); - - hasROFCirculationBeenStarted = TRUE; - ROFCirculationTimer = getMSTimerCount(); - } + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1; } - // If the RO filter water circulation is in progress and the time for it has elapsed, stop the pump - else if ( ( TRUE == hasROFCirculationBeenStarted ) && ( TRUE == didTimeout( ROFCirculationTimer, ROF_COOL_DOWN_CIRCULATION_TIME_MS ) ) ) + else if ( ( TRUE == didTimeout( stateTimer, ROF_COOL_DOWN_MAX_TIME_MS ) ) ) { - hasROFCirculationBeenStarted = FALSE; - ROFCoolingTimer = getMSTimerCount(); - signalROPumpHardStop(); + prevHeatDisinfectState = state; + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; // TODO - cool down alarm? + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } return state; @@ -1426,6 +1446,7 @@ } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { +#if 0 //wjb // Done with draining the reservoirs signalDrainPumpHardStop(); @@ -1447,6 +1468,8 @@ stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2; +#endif + state = DG_HEAT_DISINFECT_STATE_COMPLETE; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { @@ -1457,6 +1480,7 @@ return state; } +#if 0 //wjb /*********************************************************************//** * @brief * The handleHeatDisinfectRinseR1ToR2State function handles the heat @@ -1519,7 +1543,9 @@ return state; } +#endif +#if 0 //wjb /*********************************************************************//** * @brief * The handleHeatDisinfectRinseR2ToR1AndDrainR1State function handles the @@ -1588,7 +1614,7 @@ // De-energize all the valves and set the VDr to drain R2 setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD2, VALVE_STATE_OPEN ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); @@ -1626,7 +1652,9 @@ return state; } +#endif +#if 0 //wjb /*********************************************************************//** * @brief * The handleHeatDisinfectRinseCirculationState function handles the @@ -1648,6 +1676,7 @@ return state; } +#endif /*********************************************************************//** * @brief @@ -1770,16 +1799,15 @@ failHeatDisinfect(); } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VRD2, VALVE_STATE_CLOSED ); - signalDrainPumpHardStop(); - - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; - } } + else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) + { + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + signalDrainPumpHardStop(); + prevHeatDisinfectState = state; + state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + } return state; } @@ -1939,14 +1967,19 @@ /*********************************************************************//** * @brief * The getHeatDisinfectStatus function monitors and returns the current - * stage of heat disinfect cycle. If the level of the reservoirs is drifted - * consecutively for the define period of time, it sets the reservoir leak - * time out alarm. If the target temperature is not reached within the - * defined period of time, it set the temperature out of range alarm. - * If the heat disinfect has started or has elapsed, it set the status of - * heat disinfect accordingly. - * @details Inputs: areRsrvrsLeaking, areRsrvrsLeaking - * @details Outputs: areRsrvrsLeaking, areRsrvrsLeaking, heatDisinfectState + * stage of heat disinfect cycle. It monitors + * 1) The temperature gradient betweeen TPo and Thd + * 2) Reservoir 1 or Reservoir 2 have lost more than allowed loss volume + * 3) THd must be above the minimum target disinfect temp for the + * target disinfect time + * 4) The overall heat disinfect time + * + * @details Inputs: tempGradOutOfRangeTimer, areRsrvrsLeaking, + * isPartialDisinfectInProgress, heatDisinfectTimer, + * targetDisinfectTime + * @details Outputs: tempGradOutOfRangeTimer, alarmDetectedPendingTrigger, + * areRsrvrsLeaking, isPartialDisinfectInProgress, + * heatDisinfectTimer, targetDisinfectTime * @return status of the heat disinfect (i.e in progress, complete) *************************************************************************/ static HEAT_DISINFECT_STATUS_T getHeatDisinfectStatus( void ) @@ -1961,33 +1994,22 @@ // Check if the temperature gradient in between the coldest and the hottest spot is more than the specified temperature and // the timer has not started yet, start it - bool gradientOutOfRange = ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) ? TRUE : FALSE; - if ( !gradientOutOfRange ) + BOOL gradientOutOfRange = ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) ? TRUE : FALSE; + + if ( TRUE != gradientOutOfRange ) { tempGradOutOfRangeTimer = 0; } else if ( 0 == tempGradOutOfRangeTimer ) { - tempGradOutOfRangeTimer = getMSTimerCount()); + tempGradOutOfRangeTimer = getMSTimerCount(); } else if ( TRUE == didTimeout( tempGradOutOfRangeTimer, HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ) ) { - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANAGE; + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANGE; status = HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE; } -/* - if ( ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && ( 0 == tempGradOutOfRangeTimer ) ) - { - tempGradOutOfRangeTimer = getMSTimerCount(); - } - else if ( ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && - ( TRUE == didTimeout( tempGradOutOfRangeTimer, HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ) ) ) - { - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANAGE; - status = HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE; - } -*/ // Check if either reservoir 1 or reservoir 2 are losing volume more than allowed volume if ( ( TRUE == isR1OutOfRange ) || ( TRUE == isR2OutOfRange ) ) { @@ -2047,10 +2069,10 @@ requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); } } - else if ( ( TRUE == isPartialDisinfectInProgress ) && ( ThdTemp > HEAT_DISINFECT_START_TEMPERATURE_C ) ) - { - status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS; - } +//wjb else if ( ( TRUE == isPartialDisinfectInProgress ) && ( ThdTemp > HEAT_DISINFECT_START_TEMPERATURE_C ) ) +//wjb { +//wjb status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS; +//wjb } // If heat disinfect temperature has been reached, check if this stage of heat disinfect is done if ( ( TRUE == isPartialDisinfectInProgress ) && ( TRUE == didTimeout( heatDisinfectTimer, HEAT_DISINFECT_TIME_MS ) ) ) @@ -2077,7 +2099,7 @@ *************************************************************************/ static void publishHeatDisinfectData( void ) { - if ( ++dataPublishCounter > HEAT_DISINFECT_DATA_PUB_INTERVAL ) + if ( ++dataPublishCounter >= HEAT_DISINFECT_DATA_PUB_INTERVAL ) { MODE_HEAT_DISINFECT_DATA_T data; MODE_HEAT_DISINFECT_UI_DATA_T uiData; @@ -2134,7 +2156,7 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif { - if ( ( STATE_OPEN == getSwitchStatus( CONCENTRATE_CAP ) ) && ( STATE_OPEN == getSwitchStatus( DIALYSATE_CAP ) ) ) + if ( ( STATE_OPEN == getSwitchStatus( CONCENTRATE_CAP ) ) || ( STATE_OPEN == getSwitchStatus( DIALYSATE_CAP ) ) ) { // Set the variables to fail and go to cancel water path. Set the pending alarm to no alarm so the cancel water path // will not be raising the alarm at end of the cancel water path. The recoverable alarm is raised here in this function @@ -2146,4 +2168,25 @@ } } +/*********************************************************************//** + * @brief + * The writeDisinfectDataToNV function writes the disinfection data to the + * non-volatile memory. + * @details Inputs: disinfectNVOps + * @details Outputs: disinfectNVOps + * @return: none + *************************************************************************/ +static void writeDisinfectDataToNV( void ) +{ + if ( FALSE == disinfectNVOps.hasDisCompleteDateBeenWrittenToNV ) + { + disinfectNVOps.hasDisCompleteDateBeenWrittenToNV = setDisinfectStatus( TRUE ); + } + + if ( FALSE == disinfectNVOps.hasDisStatusBeenWrittenToNV ) + { + disinfectNVOps.hasDisStatusBeenWrittenToNV = setLastDisinfectDate( USAGE_INFO_HEAT_DISINFECT, getRTCTimestamp() ); + } +} + /**@}*/