#include "StateController.h" #include "ApplicationController.h" #include "types.h" void StateController::initializeRinseback() { _treatmentStatus.rinsebackFlowMLPM = DEF_TX_PARAM_RINSEBACK_FLOW_RATE_MLPM; _treatmentStatus.rinsebackAccumVolML = 0.0; _treatmentStatus.rinsebackAdditionalVolML = _treatmentParams.rinsebackVolumeML; _treatmentStatus.isRinsebackComplete = false; _treatmentStatus.rinsebackTimerCounter = 0; _treatmentStatus.rinsebackAdditionalTimerCounter = 0; _treatmentStatus.rinsebackTgtVolPlusAddVolML = _treatmentParams.rinsebackVolumeML; } void StateController::handleRinsebackRequestMessage() { if (_treatmentRcvdMessages[ID_UI_RINSEBACK_CMD_RQST].isNull()) { return; } QVariantList reason; quint32 acceptReject = REJECT_VALUE; quint32 rinsebackCmd = extractU32DataFromReceivedMessage(ID_UI_RINSEBACK_CMD_RQST, 0); if (_treatmentStatus.activeAlarm != ALARM_ID_NO_ALARM) { reason.append(REQUEST_REJECT_REASON_ALARM_IS_ACTIVE); handleUIResponseMessage(ID_TD_RINSEBACK_CMD_RESP, acceptReject, reason); _treatmentRcvdMessages[ID_UI_RINSEBACK_CMD_RQST].clear(); return; } switch (rinsebackCmd) { case REQUESTED_USER_ACTION_RINSEBACK_CONFIRM_START: if (_treatmentSubStates.rinsebackState == RINSEBACK_STOP_INIT_STATE) { acceptReject = ACCEPT_VALUE; _treatmentSubStates.rinsebackState = RINSEBACK_RUN_STATE; } else { reason.append(REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE); } break; case REQUESTED_USER_ACTION_RINSEBACK_INCREASE_RATE: if ((_treatmentStatus.rinsebackFlowMLPM + RINSEBACK_ADJ_FLOW_RATE_MLPM) <= RINSEBACK_MAX_RLOW_RATE_MLPM) { if (_treatmentSubStates.rinsebackState == RINSEBACK_RUN_STATE) { acceptReject = ACCEPT_VALUE; _treatmentStatus.rinsebackFlowMLPM += RINSEBACK_ADJ_FLOW_RATE_MLPM; } else { reason.append(REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE); } } else { reason.append(REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE); } break; case REQUESTED_USER_ACTION_RINSEBACK_DECREASE_RATE: if ((_treatmentStatus.rinsebackFlowMLPM - RINSEBACK_ADJ_FLOW_RATE_MLPM) >= RINSEBACK_MIN_FLOW_RATE_MLPM) { if (_treatmentSubStates.rinsebackState == RINSEBACK_RUN_STATE) { acceptReject = ACCEPT_VALUE; _treatmentStatus.rinsebackFlowMLPM -= RINSEBACK_ADJ_FLOW_RATE_MLPM; } else { reason.append(REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE); } } else { reason.append(REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE); } break; case REQUESTED_USER_ACTION_RINSEBACK_PAUSE: if (_treatmentSubStates.rinsebackState == RINSEBACK_RUN_STATE) { acceptReject = ACCEPT_VALUE; _treatmentSubStates.rinsebackState = RINSEBACK_PAUSED_STATE; } else { reason.append(REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE); } break; case REQUESTED_USER_ACTION_RINSEBACK_RESUME: if (_treatmentSubStates.rinsebackState == RINSEBACK_PAUSED_STATE) { acceptReject = ACCEPT_VALUE; _treatmentSubStates.rinsebackState = RINSEBACK_RUN_STATE; } else { reason.append(REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE); } break; case REQUESTED_USER_ACTION_RINSEBACK_ADDITIONAL: if (_treatmentSubStates.rinsebackState == RINSEBACK_STOP_STATE) { acceptReject = ACCEPT_VALUE; _treatmentSubStates.rinsebackState = RINSEBACK_RUN_ADDITIONAL_STATE; } else { reason.append(REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE); } break; case REQUESTED_USER_ACTION_RINSEBACK_CONFIRM_RECIRCULATE: if(_treatmentStatus.isTreatmentComplete) { reason.append(REQUEST_REJECT_REASON_TREATMENT_IS_COMPLETED); } else if (_treatmentSubStates.rinsebackState != RINSEBACK_STOP_STATE) { reason.append(REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE); } // TODO implement recirc allowed too else { _treatmentStatus.hasRecircBeenRequested = true; } break; case REQUESTED_USER_ACTION_RINSEBACK_END_TREATMENT: handleSendUIConfirmationMessage(GENERIC_CONFIRM_ID_TREATMENT_END, GENERIC_CONFIRM_CMD_REQUEST_OPEN); break; default: // Do nothing break; } handleUIResponseMessage(ID_TD_RINSEBACK_CMD_RESP, acceptReject, reason); _treatmentRcvdMessages[ID_UI_RINSEBACK_CMD_RQST].clear(); } void StateController::handleRinsebackDelivery() { _treatmentStatus.rinsebackTimerCounter++; // TODO should we alarm if we timedout? switch (_treatmentSubStates.rinsebackState) { case RINSEBACK_RUN_STATE: _treatmentStatus.rinsebackAccumVolML += _treatmentStatus.rinsebackFlowMLPM * RINSEBACK_FLOW_INTEGRATOR; _treatmentStatus.rinsebackTimerCounter = 0; if (_treatmentStatus.rinsebackAccumVolML >= _treatmentParams.rinsebackVolumeML) { _treatmentSubStates.rinsebackState = RINSEBACK_STOP_STATE; _treatmentStatus.rinsebackTgtVolPlusAddVolML = _treatmentStatus.rinsebackAccumVolML; } break; case RINSEBACK_STOP_STATE: if ((_treatmentStatus.rinsebackTimerCounter * QOBJECT_TIMER_TIMEOUT_MS < RINSEBACK_BACK_MAX_TIME_MS) || (_treatmentStatus.rinsebackAccumVolML >= _treatmentParams.rinsebackVolumeML)) { _treatmentStatus.rinsebackAdditionalTimerCounter = 0; _treatmentStatus.rinsebackAdditionalVolML = 0.0; _treatmentStatus.rinsebackTgtVolPlusAddVolML += RINSEBACK_ADDITION_VOL_ML; } break; case RINSEBACK_RUN_ADDITIONAL_STATE: _treatmentStatus.rinsebackAdditionalTimerCounter++; _treatmentStatus.rinsebackTimerCounter = 0; _treatmentStatus.rinsebackAccumVolML += _treatmentStatus.rinsebackFlowMLPM * RINSEBACK_FLOW_INTEGRATOR; _treatmentStatus.rinsebackAdditionalVolML += _treatmentStatus.rinsebackFlowMLPM * RINSEBACK_FLOW_INTEGRATOR; if (_treatmentStatus.rinsebackAdditionalVolML >= RINSEBACK_ADDITION_VOL_ML) { _treatmentSubStates.rinsebackState = RINSEBACK_STOP_STATE; } // TODO add alarm? if (_treatmentStatus.rinsebackAdditionalTimerCounter * QOBJECT_TIMER_TIMEOUT_MS > RINSEBACK_MAX_ADDITION_TIME_MS) { _treatmentSubStates.rinsebackState = RINSEBACK_STOP_STATE; } break; default: // Do nothing break; } } void StateController::handleRinsebackBroadcastData(const Broadcast_Type BCType) { static quint32 broadcastCounter = 47; if ((++broadcastCounter % NUM_OF_COUNTS_TIMER_BC_EMIT != 0) && (BCType == BC_DELAYED)) { return; } quint32 rinsebackTimeoutS = RINSEBACK_BACK_MAX_TIME_MS / MILLISECONDS_PER_SECOND; quint32 rinsebackTimerCounterMS = _treatmentStatus.rinsebackTimerCounter * QOBJECT_TIMER_TIMEOUT_MS; quint32 countdownS = (rinsebackTimerCounterMS <= RINSEBACK_BACK_MAX_TIME_MS ? RINSEBACK_BACK_MAX_TIME_MS - rinsebackTimerCounterMS : 0) / MILLISECONDS_PER_SECOND; bool isRecircAllowed = true; if (_treatmentStatus.isRinsebackComplete || (_treatmentStatus.rinsebackTimerCounter == 0)) { countdownS = 0; rinsebackTimeoutS = 0; } QVariantList msg; msg.append(static_cast(ID_TD_RINSEBACK_DATA)); msg.append(Can_Id::eChlid_TD_Sync); msg.append(_treatmentStatus.rinsebackAdditionalVolML); msg.append(_treatmentStatus.rinsebackAccumVolML); msg.append(_treatmentStatus.rinsebackFlowMLPM); msg.append(rinsebackTimeoutS); msg.append(countdownS); msg.append(static_cast(_treatmentStatus.isRinsebackComplete)); msg.append(static_cast(isRecircAllowed)); // Is recirculation allowed? TODO check this _isBroadcastListReady = false; _broadcastMessages.append(msg); _isBroadcastListReady = true; }