Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r9c785a779da348df1c066ae0da2d0f53de7ea936 -rca5377e6e1b63de2c1dc06ba855e23fc8713bd02 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 9c785a779da348df1c066ae0da2d0f53de7ea936) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision ca5377e6e1b63de2c1dc06ba855e23fc8713bd02) @@ -1,7 +1,20 @@ +/************************************************************************** +* +* Copyright (c) 2021-2023 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file Reservoirs.c +* +* @author (last) Dara Navaei +* @date (last) 07-Mar-2023 +* +* @author (original) Dara Navaei +* @date (original) 21-Nov-2021 +* +***************************************************************************/ - -// TODO the copyright will be added automatically - #include // For reservoir management calculations #include "DGInterface.h" @@ -10,6 +23,7 @@ #include "MessageSupport.h" #include "ModeTreatment.h" #include "ModeTreatmentParams.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "Reservoirs.h" #include "TaskGeneral.h" @@ -20,24 +34,34 @@ #define RESERVOIR_SETTLE_TIME_MS 5000 ///< Allocated time to settle the filled reservoir in milliseconds. #define RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS 8000 ///< Reservoir extra time in during the cycle for error in milliseconds. -#define MAX_RESERVOIR_VOLUME_ML 1950.0 ///< Maximum allowed fluid in a reservoir in milliliters. -#define MAX_RESERVOIR_DILUTION 0.15 ///< Maximum reservoir dilution limit. -#define MAX_RESERVOIR_RECIRCULATION 1.1 ///< Maximum reservoir recirculation limit. +#define MAX_RESERVOIR_VOLUME_ML 1900.0F ///< Maximum allowed fluid in a reservoir in milliliters. +#define MAX_RESERVOIR_DILUTION 0.15F ///< Maximum reservoir dilution limit. +#define MAX_RESERVOIR_RECIRCULATION_400_MLP 1.1F ///< Maximum reservoir recirculation limit <= 400mL/m. +#define MAX_RESERVOIR_RECIRCULATION_450_MLP 1.15F ///< Maximum reservoir recirculation limit <= 450mL/m. +#define MAX_RESERVOIR_RECIRCULATION_500_MLP 1.2F ///< Maximum reservoir recirculation limit <= 500mL/m. +#define MAX_RESERVOIR_RECIRCULATION_550_MLP 1.3F ///< Maximum reservoir recirculation limit <= 550mL/m. +#define MAX_RESERVOIR_RECIRCULATION_600_MLP 1.4F ///< Maximum reservoir recirculation limit <= 600mL/m. +#define RESERVOIR_FLOW_400_MLP 400.0F ///< Reservoir flow rate 400mL/m. +#define RESERVOIR_FLOW_450_MLP 450.0F ///< Reservoir flow rate 450mL/m. +#define RESERVOIR_FLOW_500_MLP 500.0F ///< Reservoir flow rate 500mL/m. +#define RESERVOIR_FLOW_550_MLP 550.0F ///< Reservoir flow rate 550mL/m. +#define RESERVOIR_FLOW_600_MLP 600.0F ///< Reservoir flow rate 600mL/m. #define MAX_RESERVOIR_DEPLETION_TIME_MS ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Maximum allowed depletion time in milliseconds. #define RESERVOIR_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the reservoir data is published on the CAN bus. +#define RESERVOIR_DEPLETION_INTERVAL ( MAX_RESERVOIR_DEPLETION_TIME_MS / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) for maximum allowed depletion time. -#define DIALYSATE_FLOW_RATE_350_ML_PER_MIN 0.35 ///< Dialysate flow rate 350 mL/min. -#define DIALYSATE_FLOW_RATE_400_ML_PER_MIN 0.4 ///< Dialysate flow rate 400 mL/min. -#define DIALYSATE_FLOW_RATE_500_ML_PER_MIN 0.5 ///< Dialysate flow rate 500 mL/min. -#define DIALYSATE_FLOW_RATE_550_ML_PER_MIN 0.55 ///< Dialysate flow rate 550 mL/min. -#define TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN 0.5 ///< Target fill flow rate for dialysate flow rates in between 100 to 350 mL/min. -#define TGT_FILL_FLOW_FOR_DIA_FLOW_550_TO_600_ML_PER_MIN 0.8 ///< Target fill flow rate for dialysate flow rates in between 500 to 600 mL/min. +#define DIALYSATE_FLOW_RATE_350_ML_PER_MIN 0.35F ///< Dialysate flow rate 350 mL/min. +#define DIALYSATE_FLOW_RATE_550_ML_PER_MIN 0.55F ///< Dialysate flow rate 550 mL/min. +#define TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN 0.5F ///< Target fill flow rate for dialysate flow rates in between 100 to 350 mL/min. +#define TGT_FILL_FLOW_FOR_DIA_FLOW_550_TO_600_ML_PER_MIN 0.8F ///< Target fill flow rate for dialysate flow rates in between 500 to 600 mL/min. -#define DIA_FLOW_TO_FILL_FLOW_SECOND_ORDER_COEFF 10.0 ///< Dialysate flow rate to fill flow rate second order coefficient. -#define DIA_FLOW_TO_FILL_FLOW_FIRST_ORDER_COEFF 7.5 ///< Dialysate flow rate to fill flow rate first order coefficient. -#define DIA_FLOW_TO_FILL_FLOW_CONSTANT 2.0 ///< Dialysate flow rate to fill flow rate constant. +#define DIA_FLOW_TO_FILL_FLOW_SECOND_ORDER_COEFF 10.0F ///< Dialysate flow rate to fill flow rate second order coefficient. +#define DIA_FLOW_TO_FILL_FLOW_FIRST_ORDER_COEFF 7.5F ///< Dialysate flow rate to fill flow rate first order coefficient. +#define DIA_FLOW_TO_FILL_FLOW_CONSTANT 2.0F ///< Dialysate flow rate to fill flow rate constant. +#define MAX_RESERVOIR_VOL_BEFORE_SWITCH_ML 1900.0F ///< Maximum reservoir volume before we switch reservoirs (in mL). + // ********** private data ********** /// States of the treatment reservoir management state machine. @@ -53,25 +77,25 @@ } TREATMENT_RESERVOIR_MGMT_STATE_T; static TREATMENT_RESERVOIR_MGMT_STATE_T reservoirsState; ///< Treatment mode's reservoirs state. -static U32 timeStartMS = 0; ///< Active reservoir start time in milliseconds. -static U32 timeDepleteMS = 0; ///< Active reservoir depletion time in milliseconds. -static F32 volSpentML = 0.0; ///< Active reservoir spent volume in milliliters. -static U32 reservoirPublicationCounter = 0; ///< Reservoirs data publication timer counter. -static F32 dilutionLevelPct = 0.0; ///< Reservoir dilution level. -static DG_OP_MODE_T dgOpMode = DG_MODE_INIT; ///< DG operation mode. -static U32 dgSubMode = 0; ///< DG operation submode. -static U32 timeReservoirInUseMS = 0; ///< Reservoir time in use in milliseconds. -static F32 volSpentUFML = 0.0; ///< Ultrafiltration volume in milliliters. +static U32 timeStartMS; ///< Active reservoir start time in milliseconds. +static U32 timeDepleteMS; ///< Active reservoir depletion time in milliseconds. +static F32 volSpentML; ///< Active reservoir spent volume in milliliters. +static U32 reservoirPublicationCounter; ///< Reservoirs data publication timer counter. +static F32 dilutionLevelPct; ///< Reservoir dilution level. +static DG_OP_MODE_T dgOpMode; ///< DG operation mode. +static U32 dgSubMode; ///< DG operation submode. +static U32 timeReservoirInUse; ///< Reservoir time in use in milliseconds. +static F32 volSpentUFML; ///< Ultrafiltration volume in milliliters. static DG_RESERVOIR_ID_T activeReservoir; ///< Active reservoir. -static F32 recirculationLevelPct = 0.0; ///< Recirculation level in percent. -static U32 reservoirSwitchStartTimeMS = 0; ///< Reservoir switch start time in milliseconds. -static S32 timeWaitToFillMS = 0; ///< Time to wait to fill in milliseconds. -static F32 targetFillFlowLPM = 0.0; ///< Target fill flow in liters/minutes. -static U32 previousDialysateFlowMLP = 0; ///< Previous dialysate flow rate in mL/min. -static F32 previousUFFlowMLP = 0.0; ///< Previous ultrafiltration flow rate in mL/min. +static F32 recirculationLevelPct; ///< Recirculation level in percent. +static U32 reservoirSwitchStartTimeMS; ///< Reservoir switch start time in milliseconds. +static S32 timeWaitToFillMS; ///< Time to wait to fill in milliseconds. +static F32 targetFillFlowLPM; ///< Target fill flow in liters/minutes. +static U32 previousDialysateFlowMLP; ///< Previous dialysate flow rate in mL/min. +static F32 previousUFFlowMLP; ///< Previous ultrafiltration flow rate in mL/min. static DG_MIXING_RATIOS_T ratios; ///< Mixing ratios and fill prep time in milliseconds structure. -static const F32 RESERVOIR_DILUTION_RATIO = MAX_RESERVOIR_DILUTION / ( 1.0 - MAX_RESERVOIR_DILUTION ); +static const F32 RESERVOIR_DILUTION_RATIO = MAX_RESERVOIR_DILUTION / ( 1.0 - MAX_RESERVOIR_DILUTION ); ///< Reservoir dilution ratio. // ********** private function prototypes ********** @@ -81,6 +105,7 @@ static F32 getTargetFillFlowRateLPM( void ); static U32 getFillTimeMS( void ); static void calculateActiveReservoirCycleTime( void ); +static F32 getReservoirRecirculationMaxPercent( void ); static void publishReservoirData( void ); static TREATMENT_RESERVOIR_MGMT_STATE_T handleReservoirMgmtStartState( void ); @@ -97,7 +122,7 @@ * @details Inputs: none * @details Outputs: reservoirsState, timeStartMS, timeDepletionMS, volTotalMl, * volSpentMl, reservoirsPublicationCounter, dilutionLevelPct, dgOpMode, dgSubMode, - * timeReservoirInUseMS, volSpentUFML, activeReservoir, recirculationLevelPct, + * timeReservoirInUse, volSpentUFML, activeReservoir, recirculationLevelPct, * reservoirSwitchStartTimeMS, timeWaitToFillMS, targetFillFlowLPM, ratios * previousDialysateFlowRate * @return none @@ -108,21 +133,22 @@ reservoirsState = TREATMENT_RESERVOIR_MGMT_START_STATE; timeStartMS = getMSTimerCount(); timeDepleteMS = 0; - volSpentML = 0.0; + volSpentML = 0.0F; reservoirPublicationCounter = 0; - dilutionLevelPct = 0.0; + dilutionLevelPct = 0.0F; dgOpMode = DG_MODE_INIT; dgSubMode = 0; - timeReservoirInUseMS = 0; - volSpentUFML = 0.0; + timeReservoirInUse = 0; + volSpentUFML = 0.0F; activeReservoir = DG_RESERVOIR_1; - recirculationLevelPct = 0.0; + recirculationLevelPct = 0.0F; reservoirSwitchStartTimeMS = 0; timeWaitToFillMS = 0; - targetFillFlowLPM = 0.0; + targetFillFlowLPM = 0.0F; previousDialysateFlowMLP = 0; - ratios.acidMixingRatio = 0.0; - ratios.bicarbMixingRatio = 0.0; + previousUFFlowMLP = 0.0F; + ratios.acidMixingRatio = 0.0F; + ratios.bicarbMixingRatio = 0.0F; ratios.timeFillPrepMS = 0; } @@ -143,8 +169,8 @@ * @brief * The execReservoirs function executes the state machine for the treatment * reservoir management during treatment mode. - * @details Inputs: reservoirsStatus - * @details Outputs: reservoirsStatus + * @details Inputs: reservoirsState + * @details Outputs: reservoirsState, timeReservoirInUse, volSpentML * @return none *************************************************************************/ void execReservoirs( void ) @@ -162,13 +188,17 @@ checkReservoirMaxVolume(); calculateActiveReservoirCycleTime(); - // TODO do we need this? Should we not call the reservoir management exec function in saline bolus? - - // Calculate volume used from active reservoir - do not accumulate if saline bolus is in progress - if ( getSalineBolusState() != SALINE_BOLUS_STATE_IN_PROGRESS ) + // Calculate volume used from active reservoir - do not accumulate if not performing dialysis or saline bolus is in progress + if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) { volSpentML += ( flowRateMLPerMS * msSinceLastVolumeCalc ); + + if ( TREATMENT_DIALYSIS_STATE == getTreatmentState()) + { + ++timeReservoirInUse; + } } + // Update the reservoir start time timeStartMS = getMSTimerCount(); @@ -234,11 +264,14 @@ static void checkReservoirDepletionTime( void ) { // Check if the time that the reservoir has been use has exceeded the limit - if ( TRUE == didTimeout( timeReservoirInUseMS, MAX_RESERVOIR_DEPLETION_TIME_MS ) ) + if ( timeReservoirInUse >= RESERVOIR_DEPLETION_INTERVAL ) { -#ifndef SKIP_RESERVOIR_ALARMS - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_ACTIVE_RESERVOIR_DEPLETION_TIME_OUT, calcTimeSince( timeReservoirInUseMS ) ) +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_RESERVOIRS_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) #endif + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_ACTIVE_RESERVOIR_DEPLETION_TIME_OUT, (timeReservoirInUse * TASK_GENERAL_INTERVAL) ) + } } } @@ -280,16 +313,17 @@ { fillFlowRate = TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN; } - else if ( ( dialysateFlow >= DIALYSATE_FLOW_RATE_400_ML_PER_MIN ) && ( dialysateFlow <= DIALYSATE_FLOW_RATE_500_ML_PER_MIN ) ) - { - // fill flow = 10 x dialysate_flow ^ 2 - 7.5 x dialysate_flow + 2.0 - fillFlowRate = pow( dialysateFlow, 2 ) * DIA_FLOW_TO_FILL_FLOW_SECOND_ORDER_COEFF - - dialysateFlow * DIA_FLOW_TO_FILL_FLOW_FIRST_ORDER_COEFF + DIA_FLOW_TO_FILL_FLOW_CONSTANT; - } else if ( dialysateFlow >= DIALYSATE_FLOW_RATE_550_ML_PER_MIN ) { fillFlowRate = TGT_FILL_FLOW_FOR_DIA_FLOW_550_TO_600_ML_PER_MIN; } + else + { + // fill flow = linear interpolation between < 350 MLP and >550MLP + fillFlowRate = TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN + + ( ( dialysateFlow - DIALYSATE_FLOW_RATE_350_ML_PER_MIN ) / (DIALYSATE_FLOW_RATE_550_ML_PER_MIN - dialysateFlow ) ) + * ( TGT_FILL_FLOW_FOR_DIA_FLOW_550_TO_600_ML_PER_MIN - TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN ); + } targetFillFlowLPM = fillFlowRate; @@ -334,7 +368,7 @@ F32 targetUFFlowMLP = getCurrentUFSetRate(); F32 timeDepletionMS = ( (F32)FILL_RESERVOIR_TO_VOLUME_ML / dialysateFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; F32 timeTotalCycleMS = fillTimeMS + RESERVOIR_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS + ratios.timeFillPrepMS; - F32 timeReservoirCycleMS = 0.0; + F32 timeReservoirCycleMS = 0.0F; F32 timeUFDepletionMS = NEARLY_INFINITY; // Check if target UF flow is not zero to consider it in the calculations too @@ -352,11 +386,13 @@ if ( ( previousDialysateFlowMLP != dialysateFlowMLP ) || ( previousUFFlowMLP != targetUFFlowMLP ) ) { DG_CMD_DIALYSATE_HEATING_PARAMS_T params; + params.trimmerTargetTemperature = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); params.timeReservoirWait2SwitchMS = RESERVOIR_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS; params.timeReservoirFillMS = fillTimeMS; params.timeReservoirCycleMS = timeReservoirCycleMS; params.dialysateFlowLPM = ( (F32)dialysateFlowMLP ) / ML_PER_LITER; + params.usePriTargetTempEquation = TRUE; cmdSetDGDialysateHeatingParams( params ); @@ -369,14 +405,51 @@ /*********************************************************************//** * @brief + * The getReservoirRecirculationMaxPercent function returns the reservoir management + * maximum recirculation percentage. + * @details Inputs: TREATMENT_PARAM_DIALYSATE_FLOW + * @details Outputs: none + * @return reservoir management max recirculation percent + *************************************************************************/ +static F32 getReservoirRecirculationMaxPercent( void ) +{ + U32 targetDialysateFlowMLP = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + F32 maxPercent = 0.0F; + + if (RESERVOIR_FLOW_400_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_400_MLP; + } + else if (RESERVOIR_FLOW_450_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_450_MLP; + } + else if (RESERVOIR_FLOW_500_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_500_MLP; + } + else if (RESERVOIR_FLOW_550_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_550_MLP; + } + else // if (RESERVOIR_FLOW_600_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_600_MLP; + } + + return maxPercent; +} + +/*********************************************************************//** + * @brief * The publishReservoirData function publishes reservoirs data during treatment. * @details Inputs: reservoirsPublicationCounter * @details Outputs: reservoirsPublicationCounter * @return none *************************************************************************/ static void publishReservoirData( void ) { - if ( ++reservoirPublicationCounter > RESERVOIR_DATA_PUB_INTERVAL ) + if ( ++reservoirPublicationCounter >= RESERVOIR_DATA_PUB_INTERVAL ) { RESERVOIRS_MANAGEMENT_DATA_T data; @@ -463,7 +536,8 @@ dilutionLevelPct = volSpentUFML / (F32)FILL_RESERVOIR_TO_VOLUME_ML; // Check if the dilution level has exceeded the limit or the spent volume is more than the amount of volume in the reservoir - // If it has, trigger the fill command + // If it has, trigger the fill command. This if should not happen and the predictive dilution level should trigger just in time + // in advance if ( ( dilutionLevelPct >= MAX_RESERVOIR_DILUTION ) || ( volSpentML >= (F32)FILL_RESERVOIR_TO_VOLUME_ML ) ) { if ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) @@ -502,7 +576,14 @@ // Time to wait prior to next fill is depletion time - the whole group of how much time is needed to fill a reservoir + // the time it takes to wait for a reservoir to settle and the extra margin time for ramp up of the RO and drain pumps and // any other extra times. - timeWaitToFillMS = timeDepleteMS - ( getFillTimeMS() + RESERVOIR_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS ); + if ( targetDialysateFlowMLP < RESERVOIR_FLOW_400_MLP ) + { + timeWaitToFillMS = timeDepleteMS - ( getFillTimeMS() + RESERVOIR_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS ); + } + else + { + timeWaitToFillMS = 0; + } // If the wait time has elapsed, trigger a fill command if ( timeWaitToFillMS <= 0 ) @@ -540,11 +621,14 @@ // If the recirculation level has exceeded the max allowed, raise the alarm to stop using the active reservoir as it has been // diluted to much - if ( recirculationLevelPct >= MAX_RESERVOIR_RECIRCULATION ) + if ( recirculationLevelPct >= getReservoirRecirculationMaxPercent() ) { -#ifndef SKIP_RESERVOIR_ALARMS - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_ACTIVE_RESERVOIR_RECIRCULATION_OUT_OF_RANGE, recirculationLevelPct ) +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_RESERVOIRS_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) #endif + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_ACTIVE_RESERVOIR_RECIRCULATION_OUT_OF_RANGE, recirculationLevelPct ) + } } // Check if DG has moved out of the fill mode @@ -573,17 +657,28 @@ static TREATMENT_RESERVOIR_MGMT_STATE_T handleReservoirMgmtWaitForFillSettleState( void ) { TREATMENT_RESERVOIR_MGMT_STATE_T state = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_FILL_SETTLE_STATE; + DG_RESERVOIR_ID_T active = getDGActiveReservoir(); - // Wait for the reservoir to settle and then send the commands to switch the active reservoir - if ( ( TRUE == didTimeout( reservoirSwitchStartTimeMS, RESERVOIR_SETTLE_TIME_MS ) ) && ( volSpentML >= (F32)FILL_RESERVOIR_TO_VOLUME_ML ) ) + // Get the ultra-filtration volume milliliters + // Get the dilution level in percent = spent ultra-filtration volume / target fill volume in milliliters + volSpentUFML = getReservoirUltrafiltrationVol( activeReservoir ); + dilutionLevelPct = volSpentUFML / (F32)FILL_RESERVOIR_TO_VOLUME_ML; + + // Wait for the reservoir to settle and then send the commands to switch the active reservoir TODO - restore #define below + if ( ( TRUE == didTimeout( reservoirSwitchStartTimeMS, 15000 /*RESERVOIR_SETTLE_TIME_MS*/ ) ) && + ( ( dilutionLevelPct >= MAX_RESERVOIR_DILUTION ) || ( volSpentML >= (F32)FILL_RESERVOIR_TO_VOLUME_ML ) || ( getReservoirWeight( active ) > MAX_RESERVOIR_VOL_BEFORE_SWITCH_ML ) ) ) { - DG_RESERVOIR_ID_T inactiveRes = getDGInactiveReservoir(); + DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; + DG_RESERVOIR_ID_T inactiveRes = getDGInactiveReservoir(); + rsrvrCmd.reservoirID = (U32)inactiveRes; + rsrvrCmd.useLastTrimmerHeaterDC = TRUE; + // Signal dialysis sub-mode to capture baseline volume for next reservoir. setStartReservoirVolume( inactiveRes ); // Command DG to switch reservoirs - cmdSetDGActiveReservoir( inactiveRes ); + cmdSetDGActiveReservoir( &rsrvrCmd ); // Signal dialysis sub-mode to switch reservoirs signalReservoirsSwitched(); @@ -618,7 +713,7 @@ setFinalReservoirVolume(); // Switched the active reservoir so reset the reservoir in use timer - timeReservoirInUseMS = getMSTimerCount(); + timeReservoirInUse = 0; // Reset to start state to restart drain, fill, switch process. state = TREATMENT_RESERVOIR_MGMT_START_STATE;