Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -rb99fd6c434ba1f927e46f3ab80fec1239d63f28f -r0bce81180c0ba2b25f5d501ed6aa6b2f9a8b2500 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision b99fd6c434ba1f927e46f3ab80fec1239d63f28f) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 0bce81180c0ba2b25f5d501ed6aa6b2f9a8b2500) @@ -30,6 +30,7 @@ #include "ModeTreatment.h" #include "ModeTreatmentParams.h" #include "OperationModes.h" +#include "RTC.h" #include "Switches.h" #include "SyringePump.h" #include "SystemComm.h" @@ -46,7 +47,7 @@ // ********** private definitions ********** #define DISINFECTS_DATA_PUB_INTERVAL ( 1 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Disinfects data publish interval in counts. -#define SERVICE_TIME_INTERVAL_MS ( 6 * 30 * SECONDS_IN_A_DAY * MS_PER_SECOND ) ///< HD/DG 6-month service interval in milliseconds. +#define DISINFECTS_TIME_INTERVAL_S ( 2 * SECONDS_IN_A_DAY ) ///< HD/DG 2-day service interval in seconds. // ********** private data ********** @@ -62,6 +63,8 @@ /// Interval (in task intervals) at which to publish standby mode data to CAN bus. static OVERRIDE_U32_T standbyModePublishInterval = { DISINFECTS_DATA_PUB_INTERVAL, DISINFECTS_DATA_PUB_INTERVAL, DISINFECTS_DATA_PUB_INTERVAL, 0 }; +static const U32 SERVICE_TIME_INTERVAL_S = (U32)( 365 * 0.5 * SECONDS_IN_A_DAY ); ///< HD/DG 6-month service interval in seconds. + // ********** private function prototypes ********** static HD_STANDBY_STATE_T handleStandbyModeStartState( void ); @@ -80,6 +83,8 @@ static HD_STANDBY_STATE_T handleStandbyModeWaitForDGChemDisinfectStartState( void ); static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectInProgressState( void ); +static BOOL isDGDisinfectValid( void ); +static BOOL haveHDDGServicesBeenExpired( void ); static void publishDisinfectData( void ); /*********************************************************************//** @@ -138,6 +143,10 @@ setValvePosition( VBA, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( VBV, VALVE_POSITION_A_INSERT_EJECT ); + // Request DG service record and usage information from DG + sendDGServiceRequestToDG(); + sendDGUsageInfoRequestToDG(); + return currentStandbyState; } @@ -157,7 +166,7 @@ switch ( currentStandbyState ) { case STANDBY_START_STATE: - currentStandbyState = handleStandbyModeStartState();; + currentStandbyState = handleStandbyModeStartState(); break; case STANDBY_WAIT_FOR_TREATMENT_STATE: @@ -500,7 +509,7 @@ *************************************************************************/ static HD_STANDBY_STATE_T handleStandbyModeWaitForTreatmentState( void ) { - HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_TREATMENT_STATE; + HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_TREATMENT_STATE; DG_OP_MODE_T dgOperationMode = getDGOpMode(); // If DG is filling while we are in standby mode, abort the fill @@ -515,17 +524,30 @@ cmdStopDG(); } - // If treatment start is requested by user, initiate treatment workflow (transition to treatment params mode). TODO - check required conditions before allowing treatment start, reject if necessary. + // If treatment start is requested by user, initiate treatment workflow (transition to treatment params mode). if ( TRUE == treatStartReqReceived ) { - // Initialize treatment modes before starting a new treatment - initTreatParamsMode(); - initPreTreatmentMode(); - initTreatmentMode(); - initPostTreatmentMode(); - // Start treatment workflow with treatment parameters mode - requestNewOperationMode( MODE_TPAR ); - treatStartReqReceived = FALSE; + BOOL startTreatment = TRUE; + +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SERVICE_AND_DISINFECT_CHECK ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + startTreatment = isDGDisinfectValid(); + startTreatment = haveHDDGServicesBeenExpired(); + } + + if ( TRUE == startTreatment ) + { + // Initialize treatment modes before starting a new treatment + initTreatParamsMode(); + initPreTreatmentMode(); + initTreatmentMode(); + initPostTreatmentMode(); + // Start treatment workflow with treatment parameters mode + requestNewOperationMode( MODE_TPAR ); + treatStartReqReceived = FALSE; + } } return state; @@ -797,6 +819,85 @@ /*********************************************************************//** * @brief + * The isDGDisinfectValid function checks whether the DG disinfects is + * acceptable to start another treatment. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if the disinfect is valid otherwise, FALSE + ***********************************************************************/ +static BOOL isDGDisinfectValid( void ) +{ + BOOL status = TRUE; + DG_SERVICE_AND_USAGE_DATA_T data; + + getHDVersionDGServiceAndUsageData( &data ); + + if ( TRUE == data.isDGUsageInfoAviable ) + { + if ( TRUE == data.dgUsageInfo.isDisinfected ) + { + U32 chemDisElapsedTimeS = getRTCTimestamp() - data.dgUsageInfo.lastChemicalDisDateEpoch; + BOOL hasChemDisBeenExpired = ( chemDisElapsedTimeS > DISINFECTS_TIME_INTERVAL_S ? TRUE : FALSE ); + U32 heatDisElapsedTimeS = getRTCTimestamp() - data.dgUsageInfo.lastHeatDisDateEpoch; + BOOL hasHeatDisBeenExpired = ( heatDisElapsedTimeS > DISINFECTS_TIME_INTERVAL_S ? TRUE : FALSE ); + + if ( ( TRUE == hasChemDisBeenExpired ) && ( TRUE == hasHeatDisBeenExpired ) ) + { + status = FALSE; + activateAlarmNoData( ALARM_ID_DG_DISINFECT_HAS_BEEN_EXPIRED ); + } + } + else + { + status = FALSE; + activateAlarmNoData( ALARM_ID_DG_DISINFECT_HAS_BEEN_EXPIRED ); + } + } + + return status; +} + +/*********************************************************************//** + * @brief + * The haveHDDGServicesBeenExpired function checks whether the last DG/HD + * service time is still within the interval or not. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if the service time is still valid otherwise, FALSE + ***********************************************************************/ +static BOOL haveHDDGServicesBeenExpired( void ) +{ + BOOL status = TRUE; + DG_SERVICE_AND_USAGE_DATA_T dgData; + HD_SERVICE_RECORD_T hdServiceRecord; + + getHDVersionDGServiceAndUsageData( &dgData ); + getNVRecord2Driver( GET_SRV_RECORD, (U08*)&hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ), 0, ALARM_ID_NO_ALARM ); + + if ( TRUE == dgData.isDGServiceRecordAvailable ) + { + U32 dgSrvcElapsedTimeS = getRTCTimestamp() - dgData.dgServiceRecord.lastServiceDateEpoch; + BOOL hasDGSrvcBeenExpired = ( dgSrvcElapsedTimeS > SERVICE_TIME_INTERVAL_S ? TRUE : FALSE ); + U32 hdSrvcElapsedTimeS = getRTCTimestamp() - hdServiceRecord.lastServiceEpochDate; + BOOL hasHDSrvcBeenExpied = ( hdSrvcElapsedTimeS > SERVICE_TIME_INTERVAL_S ? TRUE : FALSE ); + + if ( TRUE == hasDGSrvcBeenExpired ) + { + status = FALSE; + activateAlarmNoData( ALARM_ID_DG_SERIVCE_TIME_INTERVAL_HAS_ELAPSED ); + } + if ( TRUE == hasHDSrvcBeenExpied ) + { + status = FALSE; + activateAlarmNoData( ALARM_ID_HD_SERVICE_TIME_INTERVAL_HAS_ELAPSED ); + } + } + + return status; +} + +/*********************************************************************//** + * @brief * The publishDisinfectData function publishes disinfects data at * the set interval. * @details Inputs: dataPublishCounter