Index: dialin/ui/hd_simulator.py =================================================================== diff -u -r8b04f496c0387a253f4b8dfd243d85852aad8153 -r683c2d895d5d41048447be1e35db604ebe4b466e --- dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision 8b04f496c0387a253f4b8dfd243d85852aad8153) +++ dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision 683c2d895d5d41048447be1e35db604ebe4b466e) @@ -127,11 +127,14 @@ self.rinsebackVelocity_ml_per_sec = 100.0 / 60.0 # param self.rinsebackVelocity_max_ml_per_sec = 150.0 / 60.0 # fixed R self.rinsebackVelocity_min_ml_per_sec = 50.0 / 60.0 # fixed R - self.hep_rate_ml_per_hr = 0 # setting - self.hep_bolus_ml = 0 # setting - self.hep_stop_min = 0 # setting - self.hep_out_ml = 0 # status - self.hep_bolus_out_ml = 0 # status + self.heparin_rate_ml_per_hr = 0 # setting + self.heparin_bolus_ml = 0 # setting + self.heparin_stop_min = 0 # setting + self.heparin_out_ml = 0 # status + self.heparin_pause = False # setting + self.heparin_state = HeparinStates.HEPARIN_STATE_STOPPED # status + self.saline_state = SalineBolusStates.SALINE_BOLUS_STATE_IDLE.value # status + self.uf_state = TreatmentStates.TREATMENT_DIALYSIS_STATE.value # status self.demo_treatment_params = DenaliData() @@ -322,16 +325,28 @@ self.uf_rate_l_per_sec = 0 self.salineVolume_ml = 0.0 # status self.salineVolCum_ml = 0.0 # status + self.dialysate_flow_set_point_ml_per_min = params.data_int[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_FLOW_RATE_ML_MIN.value] + self.blood_flow_set_point_ml_per_min = params.data_int[TreatmentParameters.TREATMENT_PARAM_BLOOD_FLOW_RATE_ML_MIN.value] + # rsp_id = MsgIds.MSG_ID_HD_PRESSURE_LIMITS_CHANGE_RESPONSE + self.cmd_send_treatment_adjust_pressures_limit_response( accepted=EResponse.Accepted, + reason=RequestRejectReasons.REQUEST_REJECT_REASON_NONE.value, + arterial_low=self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_ARTERIAL_PRESSURE_LOW_LIMIT_MMHG.value], + arterial_high=self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_ARTERIAL_PRESSURE_HIGH_LIMIT_MMHG.value], + venous_low=self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_VENOUS_PRESSURE_LOW_LIMIT_MMHG.value], + venous_high=self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_VENOUS_PRESSURE_HIGH_LIMIT_MMHG.value] ) # Rinseback self.rinseback_volume_set_ml = 80 + 120 # TBD! 80 + should be based on dialyzer blood volume? self.rinsebackVelocity_ml_per_sec = params.data_int[TreatmentParameters.TREATMENT_PARAM_RINSEBACK_FLOW_RATE_ML_MIN.value] / 60.0 self.rinseback_volume_out_ml = 0 # reset status self.rinseback_volume_all_ml = 0 # Heparin - self.hep_stop_min = params.data_int[TreatmentParameters.TREATMENT_PARAM_HEPARIN_PRESTOP_MIN.value] - self.hep_rate_ml_per_hr = params.data_float[TreatmentParameters.TREATMENT_PARAM_HEPARIN_DISPENSE_RATE_ML_HR.value] - self.hep_bolus_ml = params.data_float[TreatmentParameters.TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME_ML.value] - self.hep_out_ml = 0 # reset status + self.heparin_stop_min = params.data_int[TreatmentParameters.TREATMENT_PARAM_HEPARIN_PRESTOP_MIN.value] + self.heparin_rate_ml_per_hr = params.data_float[TreatmentParameters.TREATMENT_PARAM_HEPARIN_DISPENSE_RATE_ML_HR.value] + self.heparin_rate_ml_per_s = self.heparin_rate_ml_per_hr / 3600.0 + self.heparin_bolus_ml = params.data_float[TreatmentParameters.TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME_ML.value] + self.heparin_out_ml = 0 # reset status + self.heparin_pause = False # setting + self.heparin_expected_ml = ((self.treatment_time_sec / 60.0) - self.heparin_stop_min) / 60.0 * self.heparin_rate_ml_per_hr + self.heparin_bolus_ml # 'Secret' speed setting: 10x heparin bolus volume, when heparinStopTime=430 and heparinRate is OFF # if math.isclose(sto, 430) and math.isclose(hdr, 0) and (hbv > 0.199): # self.demoSpeed = int(hbv * 10 + 0.5) @@ -488,6 +503,7 @@ self.demoSelection = 20 # Start Treatment self.demoCount = 0 # immediately + # DIALYSIS --------------------------------------------------- elif msg_id == MsgIds.MSG_ID_USER_TREATMENT_TIME_CHANGE_REQUEST.value: # _22 x16 rsp_id = MsgIds.MSG_ID_USER_TREATMENT_TIME_CHANGE_RESPONSE if params.data_int[0] is not None: @@ -511,6 +527,15 @@ else: self.demoSelection = 33 # Bolus Stop request + elif msg_id == MsgIds.MSG_ID_UI_HEPARIN_PAUSE_RESUME_REQUEST.value: # _.. x4B + rsp_id = MsgIds.MSG_ID_HD_HEPARIN_PAUSE_RESUME_RESPONSE + rsp_payload = integer_to_bytearray(EResponse.Accepted) + rsp_payload += integer_to_bytearray(RequestRejectReasons.REQUEST_REJECT_REASON_NONE.value) + if params.data_int[0] != EResponse.Accepted: + self.heparin_pause = True # Heparin Pause + else: + self.heparin_pause = False # Heparin Resume + elif msg_id == MsgIds.MSG_ID_UI_PRESSURE_LIMITS_CHANGE_REQUEST.value: # _70 x46 rsp_id = MsgIds.MSG_ID_HD_PRESSURE_LIMITS_CHANGE_RESPONSE rsp_payload = integer_to_bytearray(EResponse.Accepted) @@ -529,6 +554,21 @@ rsp_payload += integer_to_bytearray(params.data_int[2]) rsp_payload += integer_to_bytearray(params.data_int[3]) + elif msg_id == MsgIds.MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_REQUEST.value: # _70 x46 + rsp_id = MsgIds.MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_RESPONSE + rsp_payload = integer_to_bytearray(EResponse.Accepted) + rsp_payload += integer_to_bytearray(RequestRejectReasons.REQUEST_REJECT_REASON_NONE.value) + # apply new settings + self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_BLOOD_FLOW_RATE_ML_MIN.value] =\ + params.data_int[0] + self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_FLOW_RATE_ML_MIN.value] =\ + params.data_int[1] + self.dialysate_flow_set_point_ml_per_min = params.data_int[1] + self.blood_flow_set_point_ml_per_min = params.data_int[0] + rsp_payload += integer_to_bytearray(params.data_int[1]) # reply with as set + rsp_payload += integer_to_bytearray(params.data_int[0]) + + # RINSEBACK ------------------------- elif msg_id == MsgIds.MSG_ID_UI_RINSEBACK_CMD.value: # _82 x52 rsp_id = MsgIds.MSG_ID_HD_RINSEBACK_CMD_RESPONSE rsp_payload = integer_to_bytearray(EResponse.Accepted) @@ -548,9 +588,9 @@ self.demoSelection = 41 elif params.data_int[0] == 6: # TBD!! Additional + # TreatmentRinsebackStates.RINSEBACK_RUN_ADDITIONAL_STATE.value #TBD!! # 4 Additional rinseback volume (10 mL) state of the rinseback sub-mode state machine self.rinseback_volume_set_ml += 10.0 # ++10 mL (R) - TreatmentRinsebackStates.RINSEBACK_RUN_ADDITIONAL_STATE.value #TBD!! # 4 Additional rinseback volume (10 mL) state of the rinseback sub-mode state machine - self.demoSelection = 41 + self.demoSelection = 45 elif params.data_int[0] == 5 or\ params.data_int[0] == 8: # TBD!! need real ID consts: "END" 8 = Disconnect without further rinseback 5 = "End" during rinseback @@ -572,7 +612,7 @@ reason = RequestRejectReasons.REQUEST_REJECT_REASON_NONE.value, # int, blood_flow_rate= self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_BLOOD_FLOW_RATE_ML_MIN.value], # int dialysate_flow_rate = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_FLOW_RATE_ML_MIN.value], # int - treatment_duration = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_TREATMENT_DURATION_MIN.value], # int + treatment_duration = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_TREATMENT_DURATION_MIN.value] * 60, # int actual_treatment_duration = int(tx_time_s), # int acid_concentrate_type = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_ACID_CONCENTRATE.value], # int bicarbonate_concentrate_type = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_BICARB_CONCENTRATE.value], # int @@ -586,19 +626,19 @@ treatment_end_date_time = int(self.treatment_stop_time_s), # int average_blood_flow = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_BLOOD_FLOW_RATE_ML_MIN.value], # float average_dialysate_flow = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_FLOW_RATE_ML_MIN.value], # float - dialysate_volume_used = (self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_FLOW_RATE_ML_MIN.value] * tx_time_s), # float + dialysate_volume_used = (self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_FLOW_RATE_ML_MIN.value] * tx_time_s / 60.0), # float average_dialysate_temp = self.demo_treatment_params.data_float[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_TEMPERATURE_C.value], # float origin_uf_volume = self.uf_volume_set_l, # float target_uf_volume = self.uf_volume_set_l, # float actual_uf_volume = self.uf_volume_out_l, # float origin_uf_rate = self.uf_volume_set_l / self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_TREATMENT_DURATION_MIN.value], # float target_uf_rate = self.uf_volume_set_l / self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_TREATMENT_DURATION_MIN.value], # float - actual_uf_rate = self.uf_volume_out_l / tx_time_s, # float + actual_uf_rate = self.uf_volume_out_l / tx_time_s * 60.0, # float saline_bolus_volume = int(self.salineVolCum_ml), # int - heparin_bolus_volume = self.hep_out_ml, # float - heparin_dispense_rate = self.hep_rate_ml_per_hr, # float + heparin_bolus_volume = self.heparin_out_ml, # float + heparin_dispense_rate = self.heparin_rate_ml_per_hr, # float heparin_pre_stop = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_HEPARIN_PRESTOP_MIN.value], # int - heparin_delivered_volume = self.hep_out_ml, # float + heparin_delivered_volume = self.heparin_out_ml, # float heparin_type = self.demo_treatment_params.data_int[TreatmentParameters.TREATMENT_PARAM_HEPARIN_TYPE.value], # int average_arterial_pressure = self.arterial_pressure_mid_mmHg, # float average_venous_pressure = self.venous_pressure_mid_mmHg, # float @@ -887,18 +927,27 @@ self.treatment_start_time_s = time() self.cmd_set_treatment_time(sec_total=self.treatment_time_sec, sec_elapsed=0, sec_remain=self.treatment_time_sec) + self.heparin_out_ml = self.heparin_bolus_ml + if self.heparin_bolus_ml > 0: + self.heparin_state = HeparinStates.HEPARIN_STATE_INITIAL_BOLUS # Initial heparin bolus delivery in progress + else: + self.heparin_state = HeparinStates.HEPARIN_STATE_STOPPED # Heparin delivery stopped by alarm or not yet started + self.uf_state = TreatmentDialysisStates.DIALYSIS_START_STATE # 0 Treatment Submode + self.demoCount = self.demoSpeed - 1 self.demoGroupCount = self.treatment_time_sec #TBD!! replace with user setting self.demoGroupCounter = 0 self.demoSelection = 29 # start dialysis elif self.demoSelection == 29: # Enter/Return to normal UF Dialysis rsp_id = MsgIds.MSG_ID_TREATMENT_STATE + self.uf_state = TreatmentDialysisStates.DIALYSIS_UF_STATE # 1 UF state + self.saline_state = SalineBolusStates.SALINE_BOLUS_STATE_IDLE # 2 Saline bolus state rsp_payload = struct.pack("<10i", TreatmentStates.TREATMENT_DIALYSIS_STATE.value, # 0 Treatment Submode - TreatmentDialysisStates.DIALYSIS_UF_STATE.value, # 1 UF state - SalineBolusStates.SALINE_BOLUS_STATE_IDLE.value, # 2 Saline bolus state - 0, # 3 Hep state + self.uf_state.value, # 1 UF state + self.saline_state.value, # 2 Saline bolus state + self.heparin_state.value, # 3 Hep state 0, # 4 Rinseback state 0, # 5 Recirc state 0, # 6 Blood Prime state @@ -911,6 +960,8 @@ elif self.demoSelection >= 30 and self.demoSelection < 40 : # Dialysis Data Update ---------------- self.blood_stop_time_s = time() # reset timer self.treatment_stop_time_s = self.blood_stop_time_s + prev_heparin_state = self.heparin_state + prev_saline_state = self.saline_state # MSG_ID_BLOOD_FLOW_DATA self.blood_flow_measured_ml_per_min += (random() - 0.5) * 10 # TBD! replace magic numbers @@ -933,7 +984,6 @@ mc_current=0.0, pwm=0.0) - # MSG_ID_PRESSURE_OCCLUSION_DATA self.arterial_pressure_mmHg += (random() - 0.5) * 10 # TBD! replace magic wander numbers if self.arterial_pressure_mmHg > (self.arterial_pressure_mid_mmHg + 30): @@ -946,7 +996,6 @@ blood_pump_occlusion=0, dialysate_inlet_pump_occlusion=0, dialysate_outlet_pump_occlusion=0) - # MSG_ID_RTC_EPOCH # tbd! @@ -976,6 +1025,19 @@ self.demoGroupCounter -= 1 # TBD! effectively freeze countdown MAYBE? + # MSG_ID_HD_HEPARIN_DATA_BROADCAST + if ctr_remain_sec < (self.heparin_stop_min * 60.0): + self.heparin_state = HeparinStates.HEPARIN_STATE_COMPLETED + else: + if self.heparin_pause == False: + self.heparin_out_ml += self.heparin_rate_ml_per_s * self.demoSpeed + self.heparin_state = HeparinStates.HEPARIN_STATE_DISPENSING + else: + self.heparin_state = HeparinStates.HEPARIN_STATE_PAUSED + + self.heparin_expected_ml = (ctr_remain_sec - (self.heparin_stop_min * 60.0)) * self.heparin_rate_ml_per_s + self.heparin_out_ml + self.cmd_set_treatment_heparin_data(cumulative=self.heparin_out_ml, required=self.heparin_expected_ml) + # sub selections within Dialysis Data Update if self.demoSelection == 30: # Standard UF Dialysis . . . . . . . . . . self.demoGroupCounter += 1 # TBD! effectively unfreeze countdown MAYBE? @@ -985,19 +1047,8 @@ self.demoSelection = 40 elif self.demoSelection == 31: # Saline Bolus . . . . . . . . . . . . . - rsp_id = MsgIds.MSG_ID_TREATMENT_STATE - rsp_payload = struct.pack("<10i", - TreatmentStates.TREATMENT_DIALYSIS_STATE.value, # 0 Treatment Submode - TreatmentDialysisStates.DIALYSIS_SALINE_BOLUS_STATE.value, # 1 UF state - SalineBolusStates.SALINE_BOLUS_STATE_IN_PROGRESS.value, # 2 Saline bolus state - 0, # 3 Hep state - 0, # 4 Rinseback state - 0, # 5 Recirc state - 0, # 6 Blood Prime state - 0, # 7 End state - 0, # 8 Stop state - 0, # 9 Dialysis state - ) + self.uf_state = TreatmentDialysisStates.DIALYSIS_SALINE_BOLUS_STATE + self.saline_state = SalineBolusStates.SALINE_BOLUS_STATE_IN_PROGRESS # 2 Saline bolus state self.demoSelection = 32 self.salineVolume_ml = 0.0 # reset @@ -1019,8 +1070,26 @@ elif self.demoSelection == 33: # Saline Bolus delivery # TBD!! need to explicitly stop anything?? - self.demoSelection = 29 # Return to dialysis + self.saline_state = SalineBolusStates.SALINE_BOLUS_STATE_IDLE # Return to dialysis + self.uf_state = TreatmentDialysisStates.DIALYSIS_UF_STATE + self.demoSelection = 30 + if (prev_heparin_state != self.heparin_state) or \ + (prev_saline_state != self.saline_state): + rsp_id = MsgIds.MSG_ID_TREATMENT_STATE + rsp_payload = struct.pack("<10i", + TreatmentStates.TREATMENT_DIALYSIS_STATE.value, # 0 Treatment Submode + self.uf_state.value, # 1 UF state + self.saline_state.value, # 2 Saline bolus state + self.heparin_state.value, # 3 Hep state + 0, # 4 Rinseback state + 0, # 5 Recirc state + 0, # 6 Blood Prime state + 0, # 7 End state + 0, # 8 Stop state + 0, # 9 Dialysis state + ) + ## RINSEBACK GROUP ------------------------------------------------- elif (self.demoSelection >= 40) and (self.demoSelection < 50): set_rinseback_state = None @@ -1054,6 +1123,10 @@ set_rinseback_state = TreatmentRinsebackStates.RINSEBACK_PAUSED_STATE self.demoSelection = 49 + elif self.demoSelection == 45: # Additional Rinseback + set_rinseback_state = TreatmentRinsebackStates.RINSEBACK_RUN_ADDITIONAL_STATE + self.demoSelection = 42 + elif self.demoSelection == 49: # Rinseback wait for user pass