#pragma once #include #include #include "main.h" #include "MessageGlobals.h" #include "drydemoxmlstates.h" #define _StateController StateController::I() // TODO check illegal state transition class StateController : public QObject { Q_OBJECT SINGLETON(StateController) public: void init(); // TODO move these in slots void quit(); public slots: void doStateControllerUnhandledMsgReceived(const QVariantList &msg); protected: void timerEvent(QTimerEvent *) override; private: // General defines #define UI_MSG_BB_STATUS_INDEX 4 #define UI_MSG_BB_PAYLOAD_ID 0x63 #define SECONDS_PER_MINUTE 60 #define MINUTES_PER_HOUR 60 #define MILLISECONDS_PER_SECOND 1000 #define MILLILITERS_PER_LITER 1000 #define ACCEPT_VALUE 1 #define REJECT_VALUE 0 #define START_TX_FROM_MSG_38 1 #define CONFIRM_CMD_ACCEPT_CLOSE 3 // Timer event defines #define DEFAULT_TIMEOUT_S 10 #define QOBJECT_TIMER_TIMEOUT_MS 100 #define PROGRESS_TIME_BC_INTERVAL_MS 1000 #define NUM_OF_COUNTS_TIMER_BC_EMIT (PROGRESS_TIME_BC_INTERVAL_MS / QOBJECT_TIMER_TIMEOUT_MS) #define NUM_OF_COUNTS_TO_BC_MSG 3 // Treatment params #define MIN_DIAL_RATE_MLPM 100 #define MAX_DIAL_RATE_MLPM 600 #define MIN_TX_TIME_MINS (1 * MINUTES_PER_HOUR) #define MAX_TX_TIME_MINS (8 * MINUTES_PER_HOUR) #define MIN_UF_VOL_L 0.0 #define MAX_UF_VOL_L 8.0 #define MAX_UF_VOL_ML (MAX_UF_VOL_L * MILLILITERS_PER_LITER) #define MIN_UF_RATE_MLPM 0.0 #define MAX_UF_RATE_MLPM (2000.0 / MINUTES_PER_HOUR) #define DEF_TX_ELAPSED_TIME_S (2 * MINUTES_PER_HOUR) * SECONDS_PER_MINUTE #define DEF_TX_PARAM_PRESCRIBED_DUR_MIN ((4 * MINUTES_PER_HOUR) + 30) #define DEF_TX_PARAM_PRESCRIBED_DUR_S DEF_TX_PARAM_PRESCRIBED_DUR_MIN * SECONDS_PER_MINUTE #define DEF_TX_PARAM_UF_VOLUME_L 2.0 #define DEF_TX_PARAM_BLOOD_FLOW_RATE_MLPM 400 #define DEF_TX_PARAM_DIAL_FLOW_RATE_MLPM 600 #define DEF_TX_PARAM_SALINE_BOLUS_VOL_ML 200 #define DEF_TX_PARAM_RINSEBACK_FLOW_RATE_MLPM 250 #define DEF_TX_PARAM_ART_PRES_LIMIT_WIN_MMHG 120 #define DEF_TX_PARAM_VEN_PRES_LIMIT_WIN_MMHG 100 #define DEF_TX_PARAM_VEN_PRES_LIMIT_ASYM_WIN_MMHG 20 #define DEF_TX_PARAM_DIA_TEMPERATURE_C 37.0 // Treatment defines #define BLOOD_PRIME_VOLUME_ML (106.6 + 40) #define FLOW_INTEGRATOR (1.0 / (SECONDS_PER_MINUTE * (MILLISECONDS_PER_SECOND /QOBJECT_TIMER_TIMEOUT_MS))) #define MAX_DIALYSATE_VOLUME_ML 150000 // Treatment substates #define BLOOD_RPIME_SUB_STATE 1 #define DIALYSIS_SUB_STATE 2 #define RINSEBACK_SUBSTATE 4 #define TX_END_SUB_STATE 6 // Rinseback defines #define RINSEBACK_MIN_FLOW_RATE_MLPM 100 #define RINSEBACK_MAX_RLOW_RATE_MLPM 300 #define RINSEBACK_ADJ_FLOW_RATE_MLPM 25 #define RINSEBACK_BACK_MAX_TIME_S (5 * SECONDS_PER_MINUTE) #define RINSEBACK_END_TREATMENT_SIGNAL 999 #define RINSEBACK_STOP_INIT_STATE 0 #define RINSEBACK_RUN_STATE 1 #define RINSEBACK_PAUSE_STATE 2 #define RINSEBACK_STOP_STATE 3 enum User_Command_ID { CMD_NONE = -1, CMD_STAND_BY = 0, CMD_TX_PARAMS = 1, CMD_WATER_SAMPLE = 2, CMD_CONSUMABLES = 3, CMD_DISPOSABLES = 4, CMD_SYSTEM_PRIME = 5, CMD_BP_HR = 6, CMD_ULTRAFILTRATION = 7, CMD_CONNECTION = 8, CMD_START_TX = 9, CMD_END_TX = 10, CMD_DISINFECTION = 11, NUM_OF_USER_CMDS, }; enum State_Status { STATE_ON_ENTRY = 0, STATE_ON_ACTION, STATE_ON_EXIT, }; enum Rinseback_Rqst { RINSEBACK_START_RB = 0, RINSEBACK_ACCEL_FLOW = 1, RINSEABCK_DECEL_FLOW = 2, RINSEBACK_PAUSE_RB = 3, RINSEBACK_RESUME_RB = 4, RINSEBACK_END_RB = 5, RINSEBACK_SALINE_BOLUS = 6, RINSEBACK_END_TX = 8, RINSEBACK_BACK = 9, }; struct Pre_Treatment_Params { bool hasTxParamsBeenInitialized; quint32 bloodFlowRateMLPM; quint32 dialysateFlowRateMLPM; quint32 txDurationMins; quint32 salineBolusVolML; quint32 acidConc; quint32 bicarbConc; quint32 dialyzerType; quint32 heparinType; quint32 bloodMeasurementInveralMin; quint32 rinsebackFlowRateMLPM; qint32 areterialPresLimitWindowMMHG; qint32 venousPresLimitWindowMMHG; qint32 venousPresLimitAsymWindowMMHG; float heparinDispenseRateMLHR; float heparinBolusVolML; float dialysateTemperatureC; }; // New state machine stuff struct Treatment_Variables { quint32 broadcastIntervalCount; quint32 treatmentElapsedTimeS; quint32 remainingTreatmentTimeS; quint32 prescribedTreatmentTimeS; // UF variables float txParamsUFVolL; float prescribedMaxUFVolML; float prescribedUFRate; float refUFVolumeML; float measUFVolumeML; }; QHash_transitionEventsFromIdle; QList _broadcastMessages; QList _sendMessages; QHash _treatmentRcvdMessages; bool _isBroadcastListReady; // TODO use a mutex bool _isSendListReady; // Todo use a mutex Treatment_Variables _treatmentVars; Pre_Treatment_Params _treatmentParams; bool _hasUserConfirmedToProceed; drydemoXMLstates _dryDemo; void sendMessages(bool isBroadcast); void setTreatmentParams(bool isFromUI, const QVariant &payload); void prepareOcclusionBroadcastData(); void prepareTreatmentTimeBroadcastData(); void prepareBloodFlowBroadcastData(quint32 flowMLPM); void prepareDialysateFlowBroadcastData(); void prepareDialysateOutFlowBroadcastData(); void prepareTreatmentParamsRangesBroadcastData(); void prepareHDModeTransitionBroadcastData(Can::HD_OP_MODE mode, quint32 subMode); void prepareStatesBroadcastData(Can::Message_ID_Enum msgID, const QList &preTxStates); void prepareBloodPrimeBroadcastData(float accumulatedVolML); void prepareRinsebackBroadcastData(const QList &volsML, const QList &payload); void prepareTreatmentTimeChangeResponse(quint32 accept, quint32 txDurS, float maxUFvolML); void handleTreatmentTimeChangeRequest(const QVariant &payload); qint32 handleMsgBBPayload(const QVariant &payload); void prepareMsgBA(quint32 cmd, quint32 acceptType); bool hasPreTxTimerElapsed(Can::Message_ID_Enum msgID, Can::Can_Id canChan, quint32 &timerCountDownS, quint32 defaultTimeoutS); void handleUltrafiltrationValidation(const QVariant &payload); void handleRinsebackSubstate(const QVariant &payload, float &accumVolML, quint32 &txState, quint32 &rbState, quint32 &rbFlowMLPM); bool isTreatmenStartRequested(const QVariant &payload); // State handlers void onIdleStateChange(bool active); void onTreatmentParamsStateChange(bool active); void onWaterSampleStateChange(bool active); void onConsumablesStateChange(bool active); void onDisposablesStateChange(bool active); void onSystemPrimeStateChange(bool active); void onBPHRStateChange(bool active); void onUltrafiltrationStateChange(bool active); void onConnectionStateChange(bool active); void onStartTreatmentStateChange(bool active); void onTreatmentBloodPrimeStateChange(bool active); void onTreatmentTreatmentStateChange(bool active); void onEndTreatmentStateChange(bool active); void onDisinfectStateChange(bool active); };