Index: sources/drydemo/StateController.cpp =================================================================== diff -u -r8aa65ae1bbef5f6121783026efeeb99114c14414 -r6e845078107f7d15a3e471be421d5bce31fc51da --- sources/drydemo/StateController.cpp (.../StateController.cpp) (revision 8aa65ae1bbef5f6121783026efeeb99114c14414) +++ sources/drydemo/StateController.cpp (.../StateController.cpp) (revision 6e845078107f7d15a3e471be421d5bce31fc51da) @@ -15,19 +15,33 @@ connect(&_ApplicationController, SIGNAL(didUnhandledMsgAppController(const QVariantList &)), this , SLOT(doStateControllerUnhandledMsgReceived(const QVariantList &))); - _dryDemo.connectToState("Standby" , this, &StateController::onStandbyStateChange ); - _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 ); + // State machine methods + _dryDemo.connectToState("Standby" , this, &StateController::onStandbyStateChange ); + _dryDemo.connectToState("Pre_Tx" , this, &StateController::onPretreatmentStateChange ); + _dryDemo.connectToState("Blood_Prime" , this, &StateController::onBloodPrimeStateChange ); + _dryDemo.connectToState("Treatment" , this, &StateController::onTreatmentStateChange ); + _dryDemo.connectToState("Treatment_Pause" , this, &StateController::onTreatmentPauseStateChange ); + _dryDemo.connectToState("Treatment_Rinseback" , this, &StateController::onTreatmentRinsebackStateChange ); + _dryDemo.connectToState("Treatment_Recirculate" , this, &StateController::onTreatmentRecriculateStateChange ); + _dryDemo.connectToState("Treatment_End" , this, &StateController::onTreatmentEndStateChange ); + + // Transition to standby commands and events _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_RINSEBACK ] = {"T_SB_2_RB" , static_cast(MODE_TREA)}; + _transitionEventsFromStandby[CMD_RICIRCULATE ] = {"T_SB_2_RC" , static_cast(MODE_TREA)}; + _transitionEventsFromStandby[CMD_END_TX ] = {"T_SB_2_TE" , static_cast(MODE_TREA)}; + // Alarms specs and properties + _alarmTriggerSpecs[ALARM_ID_NO_ALARM ] = {ALARM_PRIORITY_NONE, ALARM_NO_ALARM_PROPERTIES}; + _alarmTriggerSpecs[ALARM_ID_TD_TREATMENT_STOPPED_BY_USER ] = {ALARM_PRIORITY_HIGH, ALARM_STOP_TX_PROPERTIES}; + //connect(&_dryDemo, &QScxmlStateMachine::runningChanged, this, &StateController::onBackToStanbyEvent); // TODO remove } @@ -57,6 +71,8 @@ case ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_RQST: case ID_UI_DURATION_VALIDATE_RQST: case ID_UI_DURATION_CONFIRM_RQST: + case ID_UI_ALARM_USER_ACTION_REQUEST: + case ID_UI_RINSEBACK_CMD_RQST: _treatmentRcvdMessages[receivedMsgID] = msg[1]; break; @@ -100,6 +116,11 @@ case ID_TD_ULTRAFILTRATION_CHANGE_CONFIRM_RESP: case ID_TD_DURATION_VALIDATE_RESP: case ID_TD_DURATION_CONFIRM_RESP: + case ID_ALARM_STATUS_DATA: + case ID_ALARM_CLEARED: + case ID_TD_RINSEBACK_CMD_RESP: + case ID_TD_RINSEBACK_DATA: + case ID_TD_UI_GENERIC_CONFIRMATION_REQUEST: // Do nothing break; } @@ -137,27 +158,6 @@ for (auto item: msgList){ emit _ApplicationController.didActionTransmit(item); } } -void StateController::handleDryDemoMenuRequestMessage() -{ - quint32 msgPayload = extractU32DataFromReceivedMessage(ID_UI_CONFIRMATION_RESULT_RESP, 0); - if (msgPayload != UI_MSG_BB_PAYLOAD_ID) { return; } - - msgPayload = extractU32DataFromReceivedMessage(ID_UI_CONFIRMATION_RESULT_RESP, UI_MSG_BB_STATUS_INDEX); - _treatmentStatus.userCmd = static_cast(msgPayload); - _treatmentRcvdMessages[ID_UI_CONFIRMATION_RESULT_RESP].clear(); -} - -void StateController::handleBackToStandbyEvent(State_Status &status) -{ - if (_treatmentRcvdMessages[ID_UI_CONFIRMATION_RESULT_RESP].isNull()) { return; } - - // Check for the user request message from the dry-demo menu - handleDryDemoMenuRequestMessage(); - _treatmentStatus.stateTransitionEvent = "T_Back_2_SB"; - status = STATE_ON_EXIT; - _treatmentRcvdMessages[ID_UI_CONFIRMATION_RESULT_RESP].clear(); -} - // ----------- State transition methods ---------------- // void StateController::onStandbyStateChange(bool active) { @@ -167,6 +167,8 @@ handleTDOpModeTransitionBroadcastData(MODE_STAN, 0, BC_IMMEDIATELY); setTreatmentParametersToDefault(); resetDryDemoVariables(); + // Clear all the alarms + triggerAnAlarm(ALARM_ID_NO_ALARM); status = STATE_ON_ACTION; qDebug() << "Standby on entry"; }; @@ -337,11 +339,14 @@ void StateController::onTreatmentStateChange(bool active) { - static State_Status status = STATE_ON_ENTRY; + static State_Status status = STATE_ON_ENTRY; static bool hasFlowChngeRequested = false; static QList txStates; + if (_treatmentStatus.requestTreatmentReset) { status = STATE_ON_ENTRY; _treatmentStatus.requestTreatmentReset = false; } + auto onEntry = [=](){ + hasFlowChngeRequested = false; // Start with UF state in dialysis _treatmentStatus.dialysisSubState = DIALYSIS_UF_STATE; _treatmentStatus.txState = TREAT_DIALYSIS_STATE; @@ -391,15 +396,62 @@ handleTreatmentSettingBroadcastData(BC_DELAYED); handleTreatmentTimeChangeValidation(); handleTreatmentTimeChangeConfirm(); - if ((_treatmentStatus.treatmentElapsedTimeMS / MILLISECONDS_PER_SECOND) >= (_treatmentParams.treatmentDurationMin * SECONDS_PER_MINUTE)) { + if ((_treatmentStatus.treatmentElapsedTimeMS / MILLISECONDS_PER_SECOND) > + (_treatmentParams.treatmentDurationMin * SECONDS_PER_MINUTE)) { _treatmentStatus.stateTransitionEvent = "T_Tx_2_TE"; status = STATE_ON_EXIT; } }; auto onExit = [=](){ qDebug() << "Tx in exit"; + status = STATE_ON_ENTRY; + if (_treatmentStatus.userCmd == CMD_END_TX) { + _treatmentStatus.stateTransitionEvent = "T_Tx_2_TP"; + status = STATE_ON_ACTION; + _treatmentStatus.userCmd = CMD_NONE; + } _dryDemo.submitEvent(_treatmentStatus.stateTransitionEvent); + }; + + 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; + } +} + +void StateController::onTreatmentPauseStateChange(bool active) +{ + static State_Status status = STATE_ON_ENTRY; + static QList txStates; + + auto onEntry = [=](){ + triggerAnAlarm(ALARM_ID_TD_TREATMENT_STOPPED_BY_USER); + // Start with UF state in dialysis + _treatmentStatus.dialysisSubState = DIALYSIS_UF_PAUSED_STATE; + _treatmentStatus.txState = TREAT_PAUSED_STATE; + handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_IMMEDIATELY); + txStates = {TREAT_START_STATE, 0, _treatmentStatus.dialysisSubState, 0, 0, 0, 0, 0, 0, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); + txStates = {_treatmentStatus.txState, 0, _treatmentStatus.dialysisSubState, 0, 0, 0, 0, 0, 0, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); + status = STATE_ON_ACTION; + qDebug() << "Tx pause on entry"; + }; + + auto onAction = [=](){ + status = STATE_ON_ACTION; + handleBackToStandbyEvent(status); + handleAlarmUserAction(status); + handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_DELAYED); + txStates = {_treatmentStatus.txState, 0, _treatmentStatus.dialysisSubState, 0, 0, 0, 0, 0, _treatmentStatus.fluidBolusState, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_DELAYED); + }; + + auto onExit = [=](){ + qDebug() << "Tx pasue in exit"; + _dryDemo.submitEvent(_treatmentStatus.stateTransitionEvent); status = STATE_ON_ENTRY; }; @@ -409,7 +461,90 @@ case STATE_ON_EXIT : if (active) onExit (); break; } } +void StateController::onTreatmentRinsebackStateChange(bool active) +{ + static State_Status status = STATE_ON_ENTRY; + static QList txStates; + auto onEntry = [=](){ + // Start with UF state in dialysis + _treatmentStatus.dialysisSubState = DIALYSIS_UF_PAUSED_STATE; + _treatmentStatus.txState = TREAT_RINSEBACK_STATE; + _treatmentStatus.rinsebackStates = RINSEBACK_STOP_INIT_STATE; + handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_IMMEDIATELY); + txStates = {TREAT_START_STATE, 0, _treatmentStatus.dialysisSubState, 0, 0, 0, 0, 0, 0, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); + txStates = {_treatmentStatus.txState, 0, _treatmentStatus.dialysisSubState, 0, 0, _treatmentStatus.rinsebackStates, 0, 0, 0, 0}; + initializeRinseback(); + handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); + handleRinsebackBroadcastData(BC_IMMEDIATELY); + status = STATE_ON_ACTION; + qDebug() << "Tx rinseback on entry"; + }; + + auto onAction = [=](){ + status = STATE_ON_ACTION; + handleBackToStandbyEvent(status); + handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_DELAYED); + txStates = {_treatmentStatus.txState, 0, _treatmentStatus.dialysisSubState, 0, 0, _treatmentStatus.rinsebackStates, 0, 0, 0, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_DELAYED); + handleRinsebackRequestMessage(); + handleRinsebackDelivery(); + handleRinsebackBroadcastData(BC_DELAYED); + handleTDPressureProcessAndBroadcastData(BC_DELAYED); + }; + + auto onExit = [=](){ + qDebug() << "Tx rinseback 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; + } +} +void StateController::onTreatmentRecriculateStateChange(bool active) +{ + static State_Status status = STATE_ON_ENTRY; + static QList txStates; + + auto onEntry = [=](){ + // Start with UF state in dialysis + _treatmentStatus.dialysisSubState = DIALYSIS_UF_STATE; + _treatmentStatus.txState = TREAT_DIALYSIS_STATE; + handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_IMMEDIATELY); + txStates = {TREAT_START_STATE, 0, _treatmentStatus.dialysisSubState, 0, 0, 0, 0, 0, 0, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); + txStates = {_treatmentStatus.txState, 0, _treatmentStatus.dialysisSubState, 0, 0, 0, 0, 0, 0, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_IMMEDIATELY); + status = STATE_ON_ACTION; + qDebug() << "Tx pause on entry"; + }; + + auto onAction = [=](){ + status = STATE_ON_ACTION; + handleBackToStandbyEvent(status); + handleTDOpModeTransitionBroadcastData(MODE_TREA, 0, BC_DELAYED); + txStates = {_treatmentStatus.txState, 0, _treatmentStatus.dialysisSubState, 0, 0, 0, 0, 0, _treatmentStatus.fluidBolusState, 0}; + handleTreatmentStatesBroadcastData(txStates, BC_DELAYED); + }; + + auto onExit = [=](){ + qDebug() << "Tx pasue 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; + } +} + void StateController::onTreatmentEndStateChange(bool active) { static State_Status status = STATE_ON_ENTRY; @@ -448,26 +583,9 @@ // ************* Hepler functions ************* // -void StateController::handleInitiateTreatmentRequestMessage(State_Status &status) -{ - if (_treatmentRcvdMessages[ID_INITIATE_TREATMENT].isNull()){ return; } - - 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; - if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } QVariantList msg; @@ -598,37 +716,6 @@ _isSendListReady = true; } -void StateController::handleUIResponseMessage(const Message_ID_Enum msgID, const quint32 acceptReject, const QVariantList &rejectReasons) -{ - QVariantList resp; - resp.append(static_cast(msgID)); - resp.append(Can_Id::eChlid_TD_UI); - resp.append(acceptReject); - if (rejectReasons.isEmpty()) { - // If the default reject reasons is empty, it means there were no reject reasons or extra payloads so assume none - resp.append(static_cast(REQUEST_REJECT_REASON_NONE)); - qDebug() << "Empty"; - } - else { - for (auto item: rejectReasons) { resp.append(item); } - } - _isSendListReady = false; - _sendMessages.append(resp); - _isSendListReady = true; -} - -void StateController::resetDryDemoVariables() -{ - _treatmentStatus.hasTxParamsBeenInitialized = false; - _treatmentStatus.treatmentElapsedTimeMS = DEF_TX_ELAPSED_TIME_S * MILLISECONDS_PER_SECOND; - _treatmentStatus.stateTransitionEvent = ""; - _treatmentStatus.totalFluidBolusDeliveredML = 0.0; - _treatmentStatus.accumFluidBolusDeliveredML = 0.0; - _treatmentStatus.fluidBolusState = FLUID_BOLUS_IDLE_STATE; - _treatmentStatus.txState = TREAT_START_STATE; - _treatmentStatus.ufVolDeliveredL = 0.0; -} - quint32 StateController::extractU32DataFromReceivedMessage(const Message_ID_Enum msgID, qint32 index) { Types::U32 u32Var; @@ -645,3 +732,6 @@ return f32Var.value; } + + +