Index: sources/drydemo/StateController.cpp =================================================================== diff -u -r756496932decbaae7bb3c9f694afc0402eeb1349 -r6d7f1800f7f56813c0824df509487f527a4026b2 --- sources/drydemo/StateController.cpp (.../StateController.cpp) (revision 756496932decbaae7bb3c9f694afc0402eeb1349) +++ sources/drydemo/StateController.cpp (.../StateController.cpp) (revision 6d7f1800f7f56813c0824df509487f527a4026b2) @@ -19,12 +19,14 @@ _dryDemo.connectToState("Pre_Tx" , this, &StateController::onPretreatmentStateChange ); _dryDemo.connectToState("Blood_Prime" , this, &StateController::onBloodPrimeStateChange ); _dryDemo.connectToState("Treatment" , this, &StateController::onTreatmentStateChange ); + _dryDemo.connectToState("Treatment_End" , this, &StateController::onTreatmentEndStateChange ); - _transitionEventsFromStandby.clear(); + _transitionEventsFromStandby[CMD_STAND_BY ] = {"T_Back_2_SB" , static_cast(MODE_STAN)}; _transitionEventsFromStandby[CMD_PRE_TX ] = {"T_SB_2_Pretx", static_cast(MODE_PRET)}; _transitionEventsFromStandby[CMD_BLOOD_PRIME ] = {"T_SB_2_BP" , static_cast(MODE_TREA)}; _transitionEventsFromStandby[CMD_MAIN_TX ] = {"T_SB_2_Tx" , static_cast(MODE_TREA)}; + _transitionEventsFromStandby[CMD_END_TX ] = {"T_SB_2_TE" , static_cast(MODE_TREA)}; //connect(&_dryDemo, &QScxmlStateMachine::runningChanged, this, &StateController::onBackToStanbyEvent); // TODO remove } @@ -42,9 +44,12 @@ { case ID_INITIATE_TREATMENT: case ID_UI_TREATMENT_PARAMS_TO_VALIDATE: + case ID_UI_FLUID_BOLUS_RQST: case ID_UI_BLOOD_PRIME_CMD_RQST: case ID_UI_CONFIRMATION_RESULT_RESP: case ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_RQST: + case ID_UI_TREATMENT_SET_POINTS_CHANGE_RQST: + case ID_UI_TREATMENT_SET_POINT_DIALYSATE_FLOW_CHANGE_RQST: _treatmentRcvdMessages[receivedMsgID] = msg[1]; break; @@ -77,6 +82,14 @@ case ID_TD_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_RESP: case ID_TD_TREATMENT_SET_POINTS: case ID_TD_TREATMENT_TIME_DATA: + case ID_TD_FLUID_BOLUS_RESP: + case ID_TD_FLUID_BOLUS_DATA: + case ID_TD_PRESSURE_DATA: + case ID_UI_PRESSURE_LIMIT_WIDEN_RQST: + case ID_TD_PRESSURE_LIMIT_WIDEN_RESP: + case ID_TD_TREATMENT_SET_POINTS_CHANGE_RESP: + case ID_DD_GEN_DIALYSATE_MODE_DATA: + case ID_TD_TREATMENT_SET_POINT_DIALYSATE_FLOW_CHANGE_RESP: // Do nothing break; } @@ -149,12 +162,6 @@ } } -void StateController::onBackToStanbyEvent() -{ - // TODO remove - qDebug() << "Active State" << _dryDemo.activeStateNames(); -} - // ----------- State transition methods ---------------- // void StateController::onStandbyStateChange(bool active) { @@ -171,16 +178,9 @@ auto onAction = [=](){ status = STATE_ON_ACTION; + handleBackToStandbyEvent(status); + handleInitiateTreatmentRequestMessage(status); - if (! _treatmentRcvdMessages[ID_INITIATE_TREATMENT].isNull()){ - _treatmentRcvdMessages[ID_INITIATE_TREATMENT].clear(); - - _treatmentStatus.stateTransitionEvent = _transitionEventsFromStandby[CMD_PRE_TX][0].toString(); - - handleUIResponseMessage(ID_TD_RESP_INITIATE_TREATMENT, ACCEPT_VALUE); - status = STATE_ON_EXIT; - } - if (_treatmentStatus.userCmd != CMD_NONE){ if ((_treatmentStatus.userCmd > CMD_STAND_BY) && (_treatmentStatus.userCmd <= CMD_DISINFECTION)) { _treatmentStatus.stateTransitionEvent = _transitionEventsFromStandby[_treatmentStatus.userCmd][0].toString(); @@ -191,8 +191,8 @@ status = STATE_ON_EXIT; } } + // Keep broadcasting the standby state in case the UI and dry-demo got out of sync handleTDOpModeTransitionBroadcastData(MODE_STAN, 0, BC_DELAYED); - handleBackToStandbyEvent(status); }; auto onExit = [=](){ @@ -220,6 +220,9 @@ auto onAction = [=](){ status = STATE_ON_ACTION; + handleBackToStandbyEvent(status); + handleInitiateTreatmentRequestMessage(status); + if (! _treatmentRcvdMessages[ID_UI_ADJUST_DISPOSABLES_CONFIRM_RQST].isNull()){ _treatmentRcvdMessages[ID_UI_ADJUST_DISPOSABLES_CONFIRM_RQST].clear(); handleUIResponseMessage(ID_TD_ADJUST_DISPOSSABLES_CONFIRM_RESP, ACCEPT_VALUE); @@ -236,7 +239,6 @@ status = STATE_ON_EXIT; _treatmentStatus.stateTransitionEvent = "T_Pretx_2_BP"; } - handleBackToStandbyEvent(status); }; auto onExit = [=](){ @@ -258,60 +260,63 @@ static float accumBloodVolML = 0.0; static quint32 currBloodFlowMLPM = BLOOD_PRIME_START_FLOW_MLPM; static bool resume = true; - static quint32 bloodPrimeResume = 1; - static quint32 bloodPrimePause = 2; static float rampStepML = 0.0; static bool hasFlowChngeRequested = false; + static quint32 pauseResumeState = 0; + static QList txStates; auto onEntry = [=](){ handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_IMMEDIATELY); // Clear the blood prime data immediately to prevent residual accumulated volume from a previous run handleBloodPrimeBroadcastData(0.0, 0, 0, BC_IMMEDIATELY); - accumBloodVolML = 0.0; - currBloodFlowMLPM = BLOOD_PRIME_START_FLOW_MLPM; - resume = true; - hasFlowChngeRequested = false; - - quint32 bloodPrimeStateRamp = 1; - QList txStates = {TREAT_BLOOD_PRIME_STATE, bloodPrimeStateRamp, 0, 0, 0, 0, 0, 0, 0, 0}; + accumBloodVolML = 0.0; + currBloodFlowMLPM = BLOOD_PRIME_START_FLOW_MLPM; + resume = true; + hasFlowChngeRequested = false; + _treatmentStatus.txState = TREAT_BLOOD_PRIME_STATE; + txStates = {TREAT_BLOOD_PRIME_STATE, BLOOD_PRIME_RAMP_STATE, 0, 0, 0, 0, 0, 0, 0, 0}; handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); - rampStepML = getBloodPrimeRampStepML(); - qDebug() << "Rmpa" << rampStepML; - status = STATE_ON_ACTION; qDebug() << "Blood prime on entry"; }; auto onAction = [=](){ status = STATE_ON_ACTION; + txStates = {TREAT_BLOOD_PRIME_STATE, pauseResumeState, 0, 0, 0, 0, 0, 0, _treatmentStatus.fluidBolusState, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_DELAYED); + handleBackToStandbyEvent(status); + if (! _treatmentRcvdMessages[ID_UI_BLOOD_PRIME_CMD_RQST].isNull()){ handleUIResponseMessage(ID_TD_BLOOD_PRIME_CMD_RESP, ACCEPT_VALUE); quint32 resumeStatus = extractU32DataFromReceivedMessage(ID_UI_BLOOD_PRIME_CMD_RQST, 0); - resume = (resumeStatus == bloodPrimeResume ? true : false); - quint32 state = (resumeStatus == bloodPrimeResume ? bloodPrimeResume : bloodPrimePause); + resume = (resumeStatus == BLOOD_PRIME_RESUME ? true : false); + pauseResumeState = (resumeStatus == BLOOD_PRIME_RESUME ? BLOOD_PRIME_RESUME : BLOOD_PRIME_PAUSE); - QList txStates = {TREAT_BLOOD_PRIME_STATE, state, 0, 0, 0, 0, 0, 0, 0, 0}; + // Send the results immediately + txStates = {TREAT_BLOOD_PRIME_STATE, BLOOD_PRIME_PAUSE, 0, 0, 0, 0, 0, 0, 0, 0}; handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); _treatmentRcvdMessages[ID_UI_BLOOD_PRIME_CMD_RQST].clear(); } - if (! _treatmentRcvdMessages[ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_RQST].isNull()){ - // TODO do we need to check the range - currBloodFlowMLPM = extractU32DataFromReceivedMessage(ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_RQST, 0); - handleUIResponseMessage(ID_TD_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_RESP, ACCEPT_VALUE); - hasFlowChngeRequested = true; - qDebug() << "FLow" << currBloodFlowMLPM; - - _treatmentRcvdMessages[ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_RQST].clear(); + handleSetPointBloodFlowChange(currBloodFlowMLPM, hasFlowChngeRequested); + handleTDPressureProcessAndBroadcastData(BC_DELAYED); + handleFluidBolusRequestMessage(); + if (_treatmentStatus.fluidBolusState == FLUID_BOLUS_SALINE_IN_PROGRESS_STATE){ + handleFluidBolusFluidDelivery(currBloodFlowMLPM); + handleFluidBolusBroadcastData(BC_DELAYED); + // If fluid bolus is in progress, do not run the blood prime + // TODO remove the return like TREATMENT + return; } + handleFluidBolusBroadcastData(BC_DELAYED); handleBloodPrimeVolML(resume, rampStepML, hasFlowChngeRequested, currBloodFlowMLPM, accumBloodVolML); handleTreatmentSetpointsBroadcastData(currBloodFlowMLPM, _treatmentParams.dialysateFlowRateMLPM, - _treatmentParams.dialysateTemperatureC); + _treatmentParams.dialysateTemperatureC, BC_IMMEDIATELY); if (accumBloodVolML > BLOOD_PRIME_VOLUME_ML) { _treatmentStatus.stateTransitionEvent = "T_BP_2_Tx"; @@ -320,10 +325,6 @@ handleBloodPrimeBroadcastData(accumBloodVolML, 0, 0, BC_IMMEDIATELY); qDebug() << "VOL" << accumBloodVolML; } - - handleBackToStandbyEvent(status); - - //qDebug() << "Blood state" << status; }; auto onExit = [=](){ @@ -342,26 +343,46 @@ void StateController::onTreatmentStateChange(bool active) { static State_Status status = STATE_ON_ENTRY; + static bool hasFlowChngeRequested = false; + static QList txStates; - auto onEntry = [=](){ handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_IMMEDIATELY); - QList txStates = {TREAT_START_STATE, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + txStates = {TREAT_START_STATE, 0, 0, 0, 0, 0, 0, 0, 0, 0}; handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); txStates = {TREAT_DIALYSIS_STATE, 0, 0, 0, 0, 0, 0, 0, 0, 0}; handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); - + handleTreatmentSetpointsBroadcastData(_treatmentParams.bloodFlowRateMLPM, _treatmentParams.dialysateFlowRateMLPM, + _treatmentParams.dialysateTemperatureC, BC_IMMEDIATELY); + handleTreatmentTimeProcessAndBroadcastData(BC_IMMEDIATELY); + handleDDGenDialysateModeBroadcastData(BC_IMMEDIATELY); + // The default elapsed time is 2 hours becasue the default tx duration is 4 hours. If the prescribed is less than 2 hours, 0 the elapsed + if ((_treatmentParams.treatmentDurationMin * SECONDS_PER_MINUTE) < DEF_TX_ELAPSED_TIME_S){ _treatmentStatus.treatmentElapsedTimeMS = 0; } status = STATE_ON_ACTION; - qDebug() << "Tx on entry"; }; auto onAction = [=](){ status = STATE_ON_ACTION; + handleBackToStandbyEvent(status); handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_DELAYED); - QList txStates = {TREAT_DIALYSIS_STATE, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + txStates = {TREAT_DIALYSIS_STATE, 0, 0, 0, 0, 0, 0, 0, _treatmentStatus.fluidBolusState, 0}; handleTreatmentStatesBroadcastData(txStates, BC_DELAYED); - handleBackToStandbyEvent(status); + handleTDPressureProcessAndBroadcastData(BC_DELAYED); + handleFluidBolusRequestMessage(); + if (_treatmentStatus.fluidBolusState == FLUID_BOLUS_SALINE_IN_PROGRESS_STATE){ handleFluidBolusFluidDelivery(_treatmentParams.bloodFlowRateMLPM); } + handleFluidBolusBroadcastData(BC_DELAYED); + handleTreatmentTimeProcessAndBroadcastData(BC_DELAYED); + handleTreatmentPrescriptionEditRequestMessage(); + handleSetPointBloodFlowChange(_treatmentParams.bloodFlowRateMLPM, hasFlowChngeRequested); + handleTreatmentSetpointsBroadcastData(_treatmentParams.bloodFlowRateMLPM, _treatmentParams.dialysateFlowRateMLPM, + _treatmentParams.dialysateTemperatureC, BC_DELAYED); + handleDDGenDialysateModeBroadcastData(BC_DELAYED); + handleSetPointDialysateFlowChange(); + if ((_treatmentStatus.treatmentElapsedTimeMS / MILLISECONDS_PER_SECOND) >= (_treatmentParams.treatmentDurationMin * SECONDS_PER_MINUTE)) { + _treatmentStatus.stateTransitionEvent = "T_Tx_2_TE"; + status = STATE_ON_EXIT; + } }; auto onExit = [=](){ @@ -377,8 +398,63 @@ } } +void StateController::onTreatmentEndStateChange(bool active) +{ + static State_Status status = STATE_ON_ENTRY; + + auto onEntry = [=](){ + status = STATE_ON_ACTION; + qDebug() << "Tx on entry"; + }; + + auto onAction = [=](){ + status = STATE_ON_ACTION; + //handleBackToStandbyEvent(status); + //handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_DELAYED); + //txStates = {TREAT_DIALYSIS_STATE, 0, 0, 0, 0, 0, 0, 0, _treatmentStatus.fluidBolusState, 0}; + //handleTreatmentStatesBroadcastData(txStates, BC_DELAYED); + //handleTDPressureProcessAndBroadcastData(BC_DELAYED); + //handleFluidBolusRequestMessage(); + //if (_treatmentStatus.fluidBolusState == FLUID_BOLUS_SALINE_IN_PROGRESS_STATE){ handleFluidBolusFluidDelivery(_treatmentParams.bloodFlowRateMLPM); } + //handleFluidBolusBroadcastData(BC_DELAYED); + //handleTreatmentTimeProcessAndBroadcastData(BC_DELAYED); + //handleTreatmentPrescriptionEditRequestMessage(); + //handleSetPointBloodFlowChange(_treatmentParams.bloodFlowRateMLPM); + }; + + auto onExit = [=](){ + qDebug() << "Tx in exit"; + _dryDemo.submitEvent(_treatmentStatus.stateTransitionEvent); + status = STATE_ON_ENTRY; + }; + + switch (status) { // TODO macro it later + case STATE_ON_ENTRY : if (active) onEntry (); break; + case STATE_ON_ACTION: if (active) onAction(); break; + case STATE_ON_EXIT : if (active) onExit (); break; + } +} + // ************* Hepler functions ************* // +void StateController::handleInitiateTreatmentRequestMessage(State_Status &status) +{ + if (! _treatmentRcvdMessages[ID_INITIATE_TREATMENT].isNull()){ + + quint32 treatmentStatus = extractU32DataFromReceivedMessage(ID_INITIATE_TREATMENT, 0); + User_Command_ID cmdID = CMD_STAND_BY; + + // The initiate payload message payload. By default assume we are going back to standby + if (treatmentStatus == INITIATE_TREATMENT) { cmdID = CMD_PRE_TX; } + + _treatmentStatus.stateTransitionEvent = _transitionEventsFromStandby[cmdID][0].toString(); + _treatmentRcvdMessages[ID_INITIATE_TREATMENT].clear(); + handleUIResponseMessage(ID_TD_RESP_INITIATE_TREATMENT, ACCEPT_VALUE); + // Set the state to be on exit because the state has to exit + status = STATE_ON_EXIT; + } +} + void StateController::handleTDOpModeTransitionBroadcastData(const TD_OP_MODE mode, const quint32 subMode, const Broadcast_Type BCType) { static quint32 broadcastCounter = 0; @@ -513,13 +589,17 @@ _isSendListReady = true; } -void StateController::handleUIResponseMessage(const Can::Message_ID_Enum msgID, const quint32 acceptReject) +void StateController::handleUIResponseMessage(const Message_ID_Enum msgID, const quint32 acceptReject) { QVariantList resp; resp.append(static_cast(msgID)); resp.append(Can_Id::eChlid_TD_UI); resp.append(acceptReject); resp.append(0); + + // If the messages is fluid bolus, response exceptionally has another payload which is the target fluid blous + if (msgID == ID_TD_FLUID_BOLUS_RESP) { resp.append(_treatmentParams.fluidBlousVolumeML); } + _isSendListReady = false; _sendMessages.append(resp); _isSendListReady = true; @@ -528,9 +608,13 @@ void StateController::resetDryDemoVariables() { _treatmentStatus.hasTxParamsBeenInitialized = false; - _treatmentStatus.treatmentElapsedTimeS = DEF_TX_ELAPSED_TIME_S; - _treatmentStatus.remainingTreatmentTimeS = DEF_TX_PARAM_PRESCRIBED_DUR_S - _treatmentStatus.treatmentElapsedTimeS; + _treatmentStatus.treatmentElapsedTimeMS = DEF_TX_ELAPSED_TIME_S * MILLISECONDS_PER_SECOND; + _treatmentStatus.remainingTreatmentTimeS = DEF_TX_PARAM_PRESCRIBED_DUR_S - (_treatmentStatus.treatmentElapsedTimeMS / MILLISECONDS_PER_SECOND); _treatmentStatus.stateTransitionEvent = ""; + _treatmentStatus.totalFluidBolusDeliveredML = 0.0; + _treatmentStatus.accumFluidBolusDeliveredML = 0.0; + _treatmentStatus.fluidBolusState = FLUID_BOLUS_IDLE_STATE; + _treatmentStatus.txState = TREAT_START_STATE; } quint32 StateController::extractU32DataFromReceivedMessage(const Message_ID_Enum msgID, qint32 index)