Index: dialin/common/msg_defs.py =================================================================== diff -u -r80501868a8f9a2c145945bbebb486fb3a32edfb2 -r396fbc8690270d160c2b223a0a3802d913c1be95 --- dialin/common/msg_defs.py (.../msg_defs.py) (revision 80501868a8f9a2c145945bbebb486fb3a32edfb2) +++ dialin/common/msg_defs.py (.../msg_defs.py) (revision 396fbc8690270d160c2b223a0a3802d913c1be95) @@ -60,9 +60,13 @@ MSG_ID_DG_HEAT_DISINFECT_DATA = 0x37 # DG heat disinfection publish data MSG_ID_UI_START_TREATMENT = 0x38 # UI user request to initiate a treatment MSG_ID_HD_START_TREATMENT_RESPONSE = 0x39 # HD response to user request to initiate a treatment + MSG_ID_HD_VALVES_DATA = 0x3A # HD broadcast of valves data + MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS = 0x3B # UI user confirmation of treatment parameters + MSG_ID_UI_TREATMENT_END_REQUEST = 0x3C # UI user treatment end request + MSG_ID_HD_TREATMENT_END_RESPONSE = 0x3D # HD response to user request to end treatment + MSG_ID_HD_AIR_TRAP_DATA = 0x3E # HD broadcast of air trap data + MSG_ID_USER_UF_PAUSE_RESUME_RESPONSE = 0x3F # HD response to user request to pause or resume UF - MSG_ID_CAN_ERROR_COUNT = 0x999 # test code in support of EMC testing - # service/test CAN messages MSG_ID_FIRST_TESTER_MESSAGE = 0x8000 # First HD test message ID MSG_ID_TESTER_LOGIN_REQUEST = MSG_ID_FIRST_TESTER_MESSAGE # HD tester log-in Index: dialin/hd/treatment.py =================================================================== diff -u -r10bd08a612562df62c94e3d304f17ba24f4275a6 -r396fbc8690270d160c2b223a0a3802d913c1be95 --- dialin/hd/treatment.py (.../treatment.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) +++ dialin/hd/treatment.py (.../treatment.py) (revision 396fbc8690270d160c2b223a0a3802d913c1be95) @@ -18,6 +18,7 @@ DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish from ..utils.conversions import integer_to_bytearray, float_to_bytearray +from ..common.msg_defs import MsgIds from logging import Logger @@ -28,11 +29,6 @@ """ - # treatment message IDs - MSG_ID_HD_TREATMENT_TIME_PUBLISHED_DATA = 0x000D - MSG_ID_HD_TREATMENT_STATE_PUBLISHED_DATA = 0x000F - MSG_ID_HD_SET_TREATMENT_PARAMETER = 0x802D - # Treatment Parameter IDs HD_TREATMENT_PARAMETER_BLOOD_FLOW = 0 HD_TREATMENT_PARAMETER_DIALYSATE_FLOW = 1 @@ -67,6 +63,19 @@ # Bicarbonate Concentrate IDs BICARB_CONC_TYPE_FRESENIUS_CENTRISOL = 0 + # UF states + UF_START_STATE = 0 # Start state of the ultrafiltration state machine + UF_PAUSED_STATE = 1 # Paused state of the ultrafiltration state machine + UF_RUNNING_STATE = 2 # Running state of the ultrafiltration state machine + UF_OFF_STATE = 3 # Completed/off state of the ultrafiltration state machine + UF_COMPLETED_STATE = 4 # Completed state of ultrafiltration state machine + + # Saline bolus states + SALINE_BOLUS_STATE_IDLE = 0 # No saline bolus delivery is in progress + SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP = 1 # Wait for pumps to stop before starting bolus + SALINE_BOLUS_STATE_IN_PROGRESS = 2 # A saline bolus delivery is in progress + SALINE_BOLUS_STATE_MAX_DELIVERED = 3 # Maximum saline bolus volume reached + # treatment time broadcast message field positions START_POS_TIME_PRES = DenaliMessage.PAYLOAD_START_INDEX END_POS_TIME_PRES = START_POS_TIME_PRES + 4 @@ -83,6 +92,24 @@ START_POS_SALINE_BOLUS_IN_PROGRESS = END_POS_UF_STATE END_POS_SALINE_BOLUS_IN_PROGRESS = START_POS_SALINE_BOLUS_IN_PROGRESS + 4 + # Generic response msg field byte positions + START_POS_FIELD_1 = DenaliMessage.PAYLOAD_START_INDEX + END_POS_FIELD_1 = START_POS_FIELD_1 + 4 + START_POS_FIELD_2 = END_POS_FIELD_1 + END_POS_FIELD_2 = START_POS_FIELD_2 + 4 + START_POS_FIELD_3 = END_POS_FIELD_2 + END_POS_FIELD_3 = START_POS_FIELD_3 + 4 + START_POS_FIELD_4 = END_POS_FIELD_3 + END_POS_FIELD_4 = START_POS_FIELD_4 + 4 + START_POS_FIELD_5 = END_POS_FIELD_4 + END_POS_FIELD_5 = START_POS_FIELD_5 + 4 + START_POS_FIELD_6 = END_POS_FIELD_5 + END_POS_FIELD_6 = START_POS_FIELD_6 + 4 + START_POS_FIELD_7 = END_POS_FIELD_6 + END_POS_FIELD_7 = START_POS_FIELD_7 + 4 + START_POS_FIELD_8 = END_POS_FIELD_7 + END_POS_FIELD_8 = START_POS_FIELD_8 + 4 + def __init__(self, can_interface, logger: Logger): """ HDTreatment constructor @@ -94,19 +121,25 @@ if self.can_interface is not None: channel_id = DenaliChannels.hd_sync_broadcast_ch_id - msg_id = self.MSG_ID_HD_TREATMENT_TIME_PUBLISHED_DATA + msg_id = MsgIds.MSG_ID_HD_TREATMENT_TIME_PUBLISHED_DATA self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_treatment_time_sync) - msg_id = self.MSG_ID_HD_TREATMENT_STATE_PUBLISHED_DATA + msg_id = MsgIds.MSG_ID_HD_TREATMENT_STATE_PUBLISHED_DATA self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_treatment_state_sync) + msg_id = MsgIds.MSG_ID_SALINE_BOLUS_DATA + self.can_interface.register_receiving_publication_function(channel_id, msg_id, + self._handler_saline_bolus_data_sync) self.treatment_time_prescribed = 0 self.treatment_time_elapsed = 0 self.treatment_time_remaining = 0 self.treatment_state = 0 self.treatment_uf_state = 0 - self.saline_bolus_in_progress = False + self.saline_bolus_state = 0 + self.saline_bolus_max_vol = 0 + self.saline_bolus_cum_vol = 0.0 + self.saline_bolus_bol_vol = 0.0 def get_treatment_time_prescribed(self): """ @@ -148,14 +181,39 @@ """ return self.treatment_uf_state - def get_saline_bolus_in_progress(self): + def get_saline_bolus_state(self): """ - Returns whether saline bolus is in progress + Returns whether saline bolus state - @return: True if saline bolus is in progress, False otherwise + @return: The saline bolus state """ - return self.saline_bolus_in_progress + return self.saline_bolus_state + def get_saline_bolus_max_volume(self): + """ + Returns maximum volume (in mL) saline that can be delivered to a patient + + @return: The maximum saline bolus volume + """ + return self.saline_bolus_max_vol + + def get_saline_bolus_cumulative_volume_delivered(self): + """ + Returns cumulative volume (in mL) of saline delivered + + @return: The cumulative saline volume delivered + """ + return self.saline_bolus_cum_vol + + def get_saline_bolus_volume_delivered(self): + """ + Returns bolus volume (in mL) of saline delivered + + @return: The bolus saline volume delivered + """ + return self.saline_bolus_bol_vol + + @_publish([ "treatment_time_prescribed", "treatment_time_elapsed", @@ -204,11 +262,33 @@ self.treatment_state = tst[0] self.treatment_uf_state = ufs[0] - if bol[0] == 1: - self.saline_bolus_in_progress = True - else: - self.saline_bolus_in_progress = False + self.saline_bolus_state = bol[0] + @_publish([ + "saline_bolus_max_vol", + "saline_bolus_cum_vol", + "saline_bolus_bol_vol" + ]) + def _handler_saline_bolus_data_sync(self, message): + """ + Handles published saline bolus data messages. Saline bolus data are captured + for reference. + + @param message: published saline bolus data message + @return: none + """ + + mxm = struct.unpack('i', bytearray( + message['message'][self.START_POS_FIELD_1:self.END_POS_FIELD_1])) + cum = struct.unpack('f', bytearray( + message['message'][self.START_POS_FIELD_2:self.END_POS_FIELD_2])) + bol = struct.unpack('f', bytearray( + message['message'][self.START_POS_FIELD_3:self.END_POS_FIELD_3])) + + self.saline_bolus_max_vol = mxm[0] + self.saline_bolus_cum_vol = cum[0] + self.saline_bolus_bol_vol = bol[0] + def cmd_set_treatment_param_blood_flow_rate(self, flow): """ Constructs and sends the set blood flow rate treatment parameter command. @@ -227,7 +307,7 @@ payload = par + flo message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting blood flow rate") @@ -265,7 +345,7 @@ payload = par + flo message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting dialysate flow rate") @@ -301,7 +381,7 @@ payload = par + dur message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting treatment duration") @@ -337,7 +417,7 @@ payload = par + sto message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting Heparin pre-stop time") @@ -373,7 +453,7 @@ payload = par + vol message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting saline bolus volume") @@ -412,7 +492,7 @@ payload = par + acd message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting acid concentrate parameter") @@ -449,7 +529,7 @@ payload = par + bic message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting bicarbonate concentrate parameter") @@ -489,7 +569,7 @@ payload = par + dia message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting dialyzer type parameter") @@ -525,7 +605,7 @@ payload = par + bpi message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting BP measurement interval parameter") @@ -561,7 +641,7 @@ payload = par + flo message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting rinseback flow rate parameter") @@ -597,7 +677,7 @@ payload = par + pre message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting arterial pressure lower alarm limit parameter") @@ -633,7 +713,7 @@ payload = par + pre message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting arterial pressure upper alarm limit parameter") @@ -669,7 +749,7 @@ payload = par + pre message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting venous pressure lower alarm limit parameter") @@ -705,7 +785,7 @@ payload = par + pre message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting venous pressure upper alarm limit parameter") @@ -741,7 +821,7 @@ payload = par + rat message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting Heparin dispense rate parameter") @@ -777,7 +857,7 @@ payload = par + vol message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting Heparin bolus volume parameter") @@ -813,7 +893,7 @@ payload = par + tmp message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting dialysate temperature parameter") @@ -849,7 +929,7 @@ payload = par + vol message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + message_id=MsgIds.MSG_ID_HD_SET_TREATMENT_PARAMETER, payload=payload) print("setting ultrafiltration volume parameter") Index: dialin/hd/ui_proxy.py =================================================================== diff -u -r10bd08a612562df62c94e3d304f17ba24f4275a6 -r396fbc8690270d160c2b223a0a3802d913c1be95 --- dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) +++ dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 396fbc8690270d160c2b223a0a3802d913c1be95) @@ -18,6 +18,7 @@ from ..utils.conversions import integer_to_bytearray, float_to_bytearray import struct from ..utils.base import _AbstractSubSystem, _publish +from ..common.msg_defs import MsgIds from collections import OrderedDict from logging import Logger @@ -27,25 +28,6 @@ Hemodialysis Delivery (HD) Dialin API sub-class for ui commands. """ - # ui message IDs - MSG_ID_UI_CHECKIN_WITH_HD = 0x0007 - MSG_ID_HD_UF_PAUSE_RESUME_REQUEST = 0x0010 - MSG_ID_HD_TREATMENT_PARAMS_RANGES = 0x001A - MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER = 0x0011 - MSG_ID_UF_SETTINGS_CHANGE_RESPONSE_FROM_HD = 0x0013 - MSG_ID_UF_SETTINGS_CHANGE_CONFIRMED_BY_USER = 0x0015 - MSG_ID_TREATMENT_DURATION_SETTING_CHANGE_REQUEST = 0x0016 - MSG_ID_TREATMENT_DURATION_SETTING_CHANGE_RESPONSE_FROM_HD = 0x001B - MSG_ID_BLOOD_DIALYSATE_FLOW_SETTING_CHANGE_REQUEST_BY_USER = 0x0017 - MSG_ID_BLOOD_DIALYSATE_FLOW_SETTING_CHANGE_RESPONSE_FROM_HD = 0x0018 - MSG_ID_UI_REQUEST_HD_VERSION = 0x001C - MSG_ID_UI_HD_VERSION_RESPONSE = 0x001D - MSG_ID_UF_SETTINGS_CHANGE_CONFIRM_RESPONSE_FROM_HD = 0x002E - MSG_ID_UI_NEW_TREATMENT_PARAMS = 0x35 - MSG_ID_HD_NEW_TREATMENT_PARAMS_RESPONSE = 0x36 - MSG_ID_UI_START_TREATMENT = 0x38 - MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS = 0x3B - LITER_TO_ML_CONVERSION_FACTOR = 1000.0 # UF pause/resume command IDs @@ -82,6 +64,12 @@ REQUEST_REJECT_REASON_UF_NOT_IN_PROGESS = 14 REQUEST_REJECT_REASON_UF_NOT_PAUSED = 15 REQUEST_REJECT_REASON_SALINE_BOLUS_IN_PROGRESS = 16 + REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE = 17 + REQUEST_REJECT_REASON_HEPARIN_PRESTOP_EXCEEDS_DURATION = 18 + REQUEST_REJECT_REASON_ARTERIAL_PRESSURE_LOW_VS_HIGH = 19 + REQUEST_REJECT_REASON_VENOUS_PRESSURE_LOW_VS_HIGH = 20 + REQUEST_REJECT_REASON_SALINE_MAX_VOLUME_REACHED = 21 + REQUEST_REJECT_REASON_SALINE_BOLUS_NOT_IN_PROGRESS = 22 # HD version message field positions START_POS_MAJOR = DenaliMessage.PAYLOAD_START_INDEX @@ -167,6 +155,24 @@ START_POS_BLD_DIAL_CHG_RSP_DIAL_RATE = END_POS_BLD_DIAL_CHG_RSP_BLD_RATE END_POS_BLD_DIAL_CHG_RSP_DIAL_RATE = START_POS_BLD_DIAL_CHG_RSP_DIAL_RATE + 4 + # Generic response msg field byte positions + START_POS_FIELD_1 = DenaliMessage.PAYLOAD_START_INDEX + END_POS_FIELD_1 = START_POS_FIELD_1 + 4 + START_POS_FIELD_2 = END_POS_FIELD_1 + END_POS_FIELD_2 = START_POS_FIELD_2 + 4 + START_POS_FIELD_3 = END_POS_FIELD_2 + END_POS_FIELD_3 = START_POS_FIELD_3 + 4 + START_POS_FIELD_4 = END_POS_FIELD_3 + END_POS_FIELD_4 = START_POS_FIELD_4 + 4 + START_POS_FIELD_5 = END_POS_FIELD_4 + END_POS_FIELD_5 = START_POS_FIELD_5 + 4 + START_POS_FIELD_6 = END_POS_FIELD_5 + END_POS_FIELD_6 = START_POS_FIELD_6 + 4 + START_POS_FIELD_7 = END_POS_FIELD_6 + END_POS_FIELD_7 = START_POS_FIELD_7 + 4 + START_POS_FIELD_8 = END_POS_FIELD_7 + END_POS_FIELD_8 = START_POS_FIELD_8 + 4 + def __init__(self, can_interface, logger: Logger): """ @@ -181,23 +187,25 @@ if self.can_interface is not None: channel_id = DenaliChannels.hd_to_ui_ch_id self.can_interface.register_receiving_publication_function(channel_id, - self.MSG_ID_UF_SETTINGS_CHANGE_RESPONSE_FROM_HD, + MsgIds.MSG_ID_USER_UF_SETTINGS_CHANGE_RESPONSE, self._handler_uf_change_response) self.can_interface.register_receiving_publication_function(channel_id, - self.MSG_ID_UF_SETTINGS_CHANGE_CONFIRM_RESPONSE_FROM_HD, + MsgIds.MSG_ID_USER_UF_SETTINGS_CHANGE_CONFIRMATION_RESPONSE, self._handler_uf_change_confirm_response) self.can_interface.register_receiving_publication_function(channel_id, - self.MSG_ID_TREATMENT_DURATION_SETTING_CHANGE_RESPONSE_FROM_HD, + MsgIds.MSG_ID_USER_TREATMENT_TIME_CHANGE_RESPONSE, self._handler_treatment_duration_change_response) self.can_interface.register_receiving_publication_function(channel_id, - self.MSG_ID_BLOOD_DIALYSATE_FLOW_SETTING_CHANGE_RESPONSE_FROM_HD, + MsgIds.MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_RESPONSE, self._handler_blood_and_dialysate_change_response) - self.can_interface.register_receiving_publication_function(channel_id, self.MSG_ID_HD_TREATMENT_PARAMS_RANGES, + self.can_interface.register_receiving_publication_function(channel_id, MsgIds.MSG_ID_TREATMENT_PARAM_CHANGE_RANGES, self._handler_treatment_param_ranges) - self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_ui_ch_id, self.MSG_ID_UI_HD_VERSION_RESPONSE, + self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_ui_ch_id, MsgIds.MSG_ID_HD_VERSION, self._handler_hd_version) - self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_ui_ch_id, self.MSG_ID_HD_NEW_TREATMENT_PARAMS_RESPONSE, + self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_ui_ch_id, MsgIds.MSG_ID_HD_NEW_TREATMENT_PARAMS_RESPONSE, self._handler_treatment_param_settings) + self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_ui_ch_id, MsgIds.MSG_ID_USER_SALINE_BOLUS_RESPONSE, + self._handler_saline_bolus_response) # initialize variables that will be populated by HD version response self.hd_version = None @@ -265,6 +273,10 @@ self.blood_and_dialysate_flow_rate_change_reject_reason = 0 self.target_blood_flow_rate = 0 self.target_dialysate_flow_rate = 0 + # initialize variables that will be populated by response to saline bolus request + self.saline_bolus_request_succeeded = False + self.saline_bolus_request_reject_reason = 0 + self.saline_bolus_request_bolus_volume = 0 self.reject_reasons = OrderedDict() for attr in dir(self): @@ -624,6 +636,22 @@ """ return self.dialysate_temperature_reject_reason + def get_saline_bolus_reject_reason(self): + """ + Gets the reject reason code for the saline bolus request + + @return: The reject reason code for saline bolus request + """ + return self.saline_bolus_request_reject_reason + + def get_saline_bolus_volume(self): + """ + Gets the HD f/w saline bolus volume (in mL) + + @return: The saline bolus volume (in mL) + """ + return self.saline_bolus_request_bolus_volume + @_publish([ "hd_version" "fpga_version" @@ -814,6 +842,36 @@ self.max_dialysate_flow_rate_ml_min = maxdialrt[0] @_publish([ + "saline_bolus_request_succeeded", + "saline_bolus_request_reject_reason", + "saline_bolus_request_bolus_volume" + ]) + def _handler_saline_bolus_response(self, message): + """ + Handler for response from HD regarding saline bolus request. + + @param message: response message from HD regarding saline bolus request.\n + BOOL Accepted \n + U32 Reject reason (if not accepted) \n + U32 Saline bolus volume (mL) + + @return: none + """ + rsp = struct.unpack('i', bytearray( + message['message'][self.START_POS_FIELD_1:self.END_POS_FIELD_1])) + rea = struct.unpack('i', bytearray( + message['message'][self.START_POS_FIELD_2:self.END_POS_FIELD_2])) + vol = struct.unpack('i', bytearray( + message['message'][self.START_POS_FIELD_3:self.END_POS_FIELD_3])) + + if rsp[0] == 1: + self.saline_bolus_request_succeeded = True + else: + self.saline_bolus_request_succeeded = False + self.saline_bolus_request_reject_reason = rea[0] + self.saline_bolus_request_bolus_volume = vol[0] + + @_publish([ "duration_change_succeeded", "duration_change_reject_reason", "duration_change_time_min", @@ -985,7 +1043,7 @@ """ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_UI_CHECKIN_WITH_HD) + message_id=MsgIds.MSG_ID_UI_CHECK_IN) self.logger.debug("Sending ui checkin w/ HD") @@ -1000,7 +1058,7 @@ """ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_UI_REQUEST_HD_VERSION) + message_id=MsgIds.MSG_ID_REQUEST_FW_VERSIONS) self.logger.debug("Sending ui request for version to HD") @@ -1017,7 +1075,7 @@ payload = integer_to_bytearray(cmd) message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_UF_PAUSE_RESUME_REQUEST, + message_id=MsgIds.MSG_ID_USER_UF_PAUSE_RESUME_REQUEST, payload=payload) if cmd == self.UF_CMD_PAUSE: @@ -1044,7 +1102,7 @@ # build command message volume = float_to_bytearray(vol * self.LITER_TO_ML_CONVERSION_FACTOR) message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER, + message_id=MsgIds.MSG_ID_USER_UF_SETTINGS_CHANGE_REQUEST, payload=volume) self.logger.debug("Sending UF settings change request.") @@ -1071,7 +1129,7 @@ adjust = integer_to_bytearray(adj) payload = volume + adjust message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER, + message_id=MsgIds.MSG_ID_USER_CONFIRM_UF_SETTINGS_CHANGE, payload=payload) self.logger.debug("Sending UF settings change request.") @@ -1080,32 +1138,6 @@ return 0 - def cmd_ui_uf_change_settings_confirmed_by_user(self, response=RESPONSE_REJECTED, vol=0.0, tm=0, rate=0.0): - """ - Constructs and sends a ui UF change settings confirmed by user message - - @param response: (int) 0 for rejected, 1 for confirmed - @param vol: (float): volume (in L) that was confirmed - @param tm: (int) treatment time (in min) that was confirmed - @param rate: (float) ultrafiltration rate (in mL/min) that was confirmed - @return: None - """ - - resp = integer_to_bytearray(response) - volume = float_to_bytearray(vol * self.LITER_TO_ML_CONVERSION_FACTOR) - mins = integer_to_bytearray(tm) - ufrate = float_to_bytearray(rate) - payload = resp + volume + mins + ufrate - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_UF_SETTINGS_CHANGE_CONFIRMED_BY_USER, - payload=payload) - - self.logger.debug("Sending UF settings change confirmation.") - - self.can_interface.send(message, 0) - - return 0 - def cmd_ui_treatment_duration_setting_change_request(self, time_min=0): """ Constructs and sends a ui UF change settings confirmed by user message @@ -1117,7 +1149,7 @@ payload = integer_to_bytearray(time_min) message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_TREATMENT_DURATION_SETTING_CHANGE_REQUEST, + message_id=MsgIds.MSG_ID_USER_TREATMENT_TIME_CHANGE_REQUEST, payload=payload) self.logger.debug("Sending treatment duration setting change request.") @@ -1141,7 +1173,7 @@ dial = integer_to_bytearray(dial_flow) payload = bld + dial message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_BLOOD_DIALYSATE_FLOW_SETTING_CHANGE_REQUEST_BY_USER, + message_id=MsgIds.MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_REQUEST, payload=payload) self.logger.debug("Sending blood & dialysate flow rate settings change request.") @@ -1167,7 +1199,7 @@ cmd = integer_to_bytearray(cmnd) payload = cmd message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_UI_START_TREATMENT, + message_id=MsgIds.MSG_ID_UI_START_TREATMENT, payload=payload) self.logger.debug("Sending start treatment command request.") @@ -1242,7 +1274,7 @@ payload = bld+dia+dur+hps+sal+acc+bic+dzr+bpi+rbf+apl+aph+vpl+vph+hdr+hbv+tmp message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_UI_NEW_TREATMENT_PARAMS, + message_id=MsgIds.MSG_ID_UI_NEW_TREATMENT_PARAMS, payload=payload) self.logger.debug("Sending treatment parameters to HD.") @@ -1259,10 +1291,43 @@ """ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS) + message_id=MsgIds.MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS) self.logger.debug("Sending confirm treatment parameters messge.") self.can_interface.send(message, 0) return 0 + + + def cmd_ui_request_saline_bolus(self, start=False): + """ + Constructs and sends a ui request for a saline bolus message + Constraints: + HD must be in treatment mode, dialysis sub-mode. + Will not succeed if saline bolus already in progress. + Will not succeed if max. saline volume has already been reached. + + @param start: (bool) True if we're requesting bolus start, False if bolus abort + + @return: none + """ + + if start: + sta = integer_to_bytearray(1) + str = "start" + else: + sta = integer_to_bytearray(0) + str = "abort" + + payload = sta + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_USER_SALINE_BOLUS_REQUEST, + payload=payload) + + + self.logger.debug("Sending request to " + str + " a saline bolus.") + + self.can_interface.send(message, 0) + + return 0 Index: tests/test_saline_bolus.py =================================================================== diff -u --- tests/test_saline_bolus.py (revision 0) +++ tests/test_saline_bolus.py (revision 396fbc8690270d160c2b223a0a3802d913c1be95) @@ -0,0 +1,55 @@ +########################################################################### +# +# Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_saline_bolus.py +# +# @date 30-Sep-2020 +# @author S. Nash +# +# @brief This script sets monitors saline bolus data and response parameters +# as well as testing saline bolus requests and aborts. +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from time import sleep + +if __name__ == "__main__": + # create an HD object called hd + hd = HD() + sleep(2) + + # log in to HD as tester +# if hd.cmd_log_in_to_hd() == 0: +# exit(1) +# sleep(1) + + for x in range(100): + sleep(1) + hdmod = hd.hd_operation_mode + hdsub = hd.hd_operation_sub_mode + ufmod = hd.treatment.get_treatment_uf_state() + sbmod = hd.treatment.get_saline_bolus_state() + mxvol = hd.treatment.get_saline_bolus_max_volume() + cmvol = hd.treatment.get_saline_bolus_cumulative_volume_delivered() + bovol = hd.treatment.get_saline_bolus_volume_delivered() + print(hdmod, hdsub, ufmod, sbmod, mxvol, cmvol, bovol) + + hd.ui.cmd_ui_request_saline_bolus(True) + + for x in range(100): + sleep(1) + hdmod = hd.hd_operation_mode + hdsub = hd.hd_operation_sub_mode + ufmod = hd.treatment.get_treatment_uf_state() + sbmod = hd.treatment.get_saline_bolus_state() + mxvol = hd.treatment.get_saline_bolus_max_volume() + cmvol = hd.treatment.get_saline_bolus_cumulative_volume_delivered() + bovol = hd.treatment.get_saline_bolus_volume_delivered() + print(hdmod, hdsub, ufmod, sbmod, mxvol, cmvol, bovol)