Index: dialin/hd/treatment.py =================================================================== diff -u -r17e48d8bf1a8960537d0615f7118bb8532e1015c -r13a03d199a7b202d61423587ca7c72e00c0df439 --- dialin/hd/treatment.py (.../treatment.py) (revision 17e48d8bf1a8960537d0615f7118bb8532e1015c) +++ dialin/hd/treatment.py (.../treatment.py) (revision 13a03d199a7b202d61423587ca7c72e00c0df439) @@ -18,6 +18,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from ..utils.conversions import integer_to_bytearray, float_to_bytearray class HDTreatment(_AbstractSubSystem): @@ -29,8 +30,43 @@ # treatment message IDs MSG_ID_HD_TREATMENT_TIME_PUBLISHED_DATA = 0x000D - MSG_ID_HD_TREATMENT_STATE_PUBLISHED_DATA = 0X000F + 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 + HD_TREATMENT_PARAMETER_TREATMENT_DURATION = 2 + HD_TREATMENT_PARAMETER_HEPARIN_PRE_STOP_TIME = 3 + HD_TREATMENT_PARAMETER_SALINE_BOLUS_VOLUME = 4 + HD_TREATMENT_PARAMETER_ACID_CONCENTRATE = 5 + HD_TREATMENT_PARAMETER_BICARB_CONCENTRATE = 6 + HD_TREATMENT_PARAMETER_DIALYZER_TYPE = 7 + HD_TREATMENT_PARAMETER_BP_MEAS_INTERVAL = 8 + HD_TREATMENT_PARAMETER_RINSEBACK_FLOW_RATE = 9 + HD_TREATMENT_PARAMETER_ART_PRESSURE_LOW_LIMIT = 10 + HD_TREATMENT_PARAMETER_ART_PRESSURE_HIGH_LIMIT = 11 + HD_TREATMENT_PARAMETER_VEN_PRESSURE_LOW_LIMIT = 12 + HD_TREATMENT_PARAMETER_VEN_PRESSURE_HIGH_LIMIT = 13 + HD_TREATMENT_PARAMETER_HEPARIN_DISPENSE_RATE = 14 + HD_TREATMENT_PARAMETER_HEPARIN_BOLUS_VOLUME = 15 + HD_TREATMENT_PARAMETER_DIALYSATE_TEMPERATURE = 16 + HD_TREATMENT_PARAMETER_UF_VOLUME = 17 + + # Dialyzer Type IDs + DIALYZER_TYPE_NIPRO_ELISIO_H_17 = 0 + DIALYZER_TYPE_NIPRO_ELISIO_H_19 = 1 + DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F160NRE = 2 + DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F180NRE = 3 + + # Acid Concentrate IDs + ACID_CONC_TYPE_FRESENIUS_08_1251_1 = 0 + ACID_CONC_TYPE_FRESENIUS_08_2251_0 = 1 + ACID_CONC_TYPE_FRESENIUS_08_3251_9 = 2 + + # Bicarbonate Concentrate IDs + BICARB_CONC_TYPE_FRESENIUS_CENTRISOL = 0 + # treatment time broadcast message field positions START_POS_TIME_PRES = DenaliMessage.PAYLOAD_START_INDEX END_POS_TIME_PRES = START_POS_TIME_PRES + 4 @@ -172,3 +208,664 @@ self.saline_bolus_in_progress = True else: self.saline_bolus_in_progress = False + + def cmd_set_treatment_param_blood_flow_rate(self, flow): + """ + Constructs and sends the set blood flow rate treatment parameter command. + This will only set the treatment parameter setting. It will not immediately + set the blood pump on with this set point. + Constraints: + Must be logged into HD. + Flow must be positive integer and should be between 100 and 500 mL/min + + @param flow: integer - set blood flow rate (in mL/min) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_BLOOD_FLOW) + flo = integer_to_bytearray(flow) + payload = par + flo + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting blood flow rate") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_flo = str(flow) + print("Blood flow rate parameter set to " + str_flo + " mL/min: " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_treatment_param_dialysate_flow_rate(self, flow): + """ + Constructs and sends the set dialysate flow rate treatment parameter command. + This will only set the treatment parameter setting. It will not immediately + set the dialysate inlet pump on with this set point. + Constraints: + Must be logged into HD. + Flow must be positive integer and should be between 100 and 600 mL/min + + @param flow: integer - set blood flow rate (in mL/min) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_DIALYSATE_FLOW) + flo = integer_to_bytearray(flow) + payload = par + flo + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting dialysate flow rate") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_flo = str(flow) + print("Dialysate flow rate parameter set to " + str_flo + " mL/min: " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_treatment_param_duration(self, duration): + """ + Constructs and sends the set treatment duration parameter command. + Constraints: + Must be logged into HD. + Duration must be positive integer and should be between 60 and 480 min + + @param duration: integer - set treatment duration (in min) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_TREATMENT_DURATION) + dur = integer_to_bytearray(duration) + payload = par + dur + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting treatment duration") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_dur = str(duration) + print("Treatment duration parameter set to " + str_dur + " min: " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_heparin_pre_stop_time(self, pre_stop): + """ + Constructs and sends the set Heparin pre-stop time parameter command. + Constraints: + Must be logged into HD. + Pre-stop time for Heparin must be positive integer and should be between 0 and 120 min + + @param pre_stop: integer - set Heparin pre-stop time (in min) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_HEPARIN_PRE_STOP_TIME) + sto = integer_to_bytearray(pre_stop) + payload = par + sto + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting Heparin pre-stop time") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_sto = str(pre_stop) + print("Heparin pre-stop time parameter set to " + str_sto + " min: " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_saline_bolus_volume(self, volume): + """ + Constructs and sends the set saline bolus volume parameter command. + Constraints: + Must be logged into HD. + Volume must be positive integer and should be between 0 and 300 mL + + @param volume: integer - set saline bolus volume (in mL) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_SALINE_BOLUS_VOLUME) + vol = integer_to_bytearray(volume) + payload = par + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting saline bolus volume") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_vol = str(volume) + print("Saline bolus volume parameter set to " + str_vol + " mL: " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_acid_concentrate(self, acid): + """ + Constructs and sends the set acid concentrate parameter command. + Constraints: + Must be logged into HD. + Acid ID must be positive integer and should be between 0 and 2 (see below) + ACID_CONC_TYPE_FRESENIUS_08_1251_1 = 0 + ACID_CONC_TYPE_FRESENIUS_08_2251_0 = 1 + ACID_CONC_TYPE_FRESENIUS_08_3251_9 = 2 + + @param acid: integer - set acid concentrate type + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_ACID_CONCENTRATE) + acd = integer_to_bytearray(acid) + payload = par + acd + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting acid concentrate parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_acd = str(acid) + print("Acid concentrate parameter set to " + str_acd + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_bicarb_concentrate(self, bicarb): + """ + Constructs and sends the set bicarbonate concentrate parameter command. + Constraints: + Must be logged into HD. + Bicarb ID must be positive integer and should be between 0 and 0 (see below) + BICARB_CONC_TYPE_FRESENIUS_CENTRISOL = 0 + + @param bicarb: integer - set bicarbonate concentrate type + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_BICARB_CONCENTRATE) + bic = integer_to_bytearray(bicarb) + payload = par + bic + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting bicarbonate concentrate parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_bic = str(bicarb) + print("Bicarbonate concentrate parameter set to " + str_bic + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_dialyzer_type(self, dialyzer): + """ + Constructs and sends the set dialyzer type parameter command. + Constraints: + Must be logged into HD. + Dialyzer ID must be positive integer and should be between 0 and 3 (see below) + DIALYZER_TYPE_NIPRO_ELISIO_H_17 = 0 + DIALYZER_TYPE_NIPRO_ELISIO_H_19 = 1 + DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F160NRE = 2 + DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F180NRE = 3 + + @param dialyzer: integer - set dialyzer type + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_DIALYZER_TYPE) + dia = integer_to_bytearray(dialyzer) + payload = par + dia + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting dialyzer type parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_dia = str(dialyzer) + print("Dialyzer type parameter set to " + str_dia + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_bp_measurement_interval(self, intvl): + """ + Constructs and sends the set blood pressure measurement interval parameter command. + Constraints: + Must be logged into HD. + Interval must be positive integer and should be between 0 and 60 min + + @param intvl: integer - set blood pressure measurement interval (in min) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_BP_MEAS_INTERVAL) + bpi = integer_to_bytearray(intvl) + payload = par + bpi + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting BP measurement interval parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_bpi = str(intvl) + print("BP measurement interval parameter set to " + str_bpi + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_rinseback_flow_rate(self, flow): + """ + Constructs and sends the set rinseback flow rate parameter command. + Constraints: + Must be logged into HD. + Flow must be positive integer and should be between 50 and 175 mL/min + + @param flow: integer - set rinseback flow rate (in mL/min) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_RINSEBACK_FLOW_RATE) + flo = integer_to_bytearray(flow) + payload = par + flo + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting rinseback flow rate parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_flo = str(flow) + print("Rinseback flow rate parameter set to " + str_flo + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_arterial_pressure_low_alarm_limit(self, pres): + """ + Constructs and sends the set arterial pressure lower alarm limit parameter command. + Constraints: + Must be logged into HD. + Pressure must be integer and should be between -300 and +200 mmHg + + @param pres: integer - set arterial pressure lower alarm limit (in mmHg) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_ART_PRESSURE_LOW_LIMIT) + pre = integer_to_bytearray(pres) + payload = par + pre + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting arterial pressure lower alarm limit parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_pre = str(pres) + print("Arterial pressure lower alarm limit parameter set to " + str_pre + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_arterial_pressure_high_alarm_limit(self, pres): + """ + Constructs and sends the set arterial pressure upper alarm limit parameter command. + Constraints: + Must be logged into HD. + Pressure must be integer and should be between -300 and +200 mmHg + + @param pres: integer - set arterial pressure upper alarm limit (in mmHg) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_ART_PRESSURE_HIGH_LIMIT) + pre = integer_to_bytearray(pres) + payload = par + pre + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting arterial pressure upper alarm limit parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_pre = str(pres) + print("Arterial pressure upper alarm limit parameter set to " + str_pre + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_venous_pressure_low_alarm_limit(self, pres): + """ + Constructs and sends the set venous pressure lower alarm limit parameter command. + Constraints: + Must be logged into HD. + Pressure must be integer and should be between -100 and +600 mmHg + + @param pres: integer - set venous pressure lower alarm limit (in mmHg) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_VEN_PRESSURE_LOW_LIMIT) + pre = integer_to_bytearray(pres) + payload = par + pre + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting venous pressure lower alarm limit parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_pre = str(pres) + print("Venous pressure lower alarm limit parameter set to " + str_pre + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_venous_pressure_high_alarm_limit(self, pres): + """ + Constructs and sends the set venous pressure upper alarm limit parameter command. + Constraints: + Must be logged into HD. + Pressure must be integer and should be between -100 and +600 mmHg + + @param pres: integer - set venous pressure upper alarm limit (in mmHg) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_VEN_PRESSURE_HIGH_LIMIT) + pre = integer_to_bytearray(pres) + payload = par + pre + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting venous pressure upper alarm limit parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_pre = str(pres) + print("Venous pressure upper alarm limit parameter set to " + str_pre + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_heparin_dispense_rate(self, rate): + """ + Constructs and sends the set Heparin dispense rate parameter command. + Constraints: + Must be logged into HD. + Rate must be floating point value and should be between 0 and 1.0 mL/hr + + @param rate: float - set Heparin dispense rate (in mL/hr) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_HEPARIN_DISPENSE_RATE) + rat = float_to_bytearray(rate) + payload = par + rat + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting Heparin dispense rate parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_rat = str(rate) + print("Heparin dispense rate parameter set to " + str_rat + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_heparin_bolus_volume(self, volume): + """ + Constructs and sends the set Heparin bolus volume parameter command. + Constraints: + Must be logged into HD. + Volume must be floating point value and should be between 0 and 2.0 mL + + @param volume: float - set Heparin bolus volume (in mL) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_HEPARIN_BOLUS_VOLUME) + vol = float_to_bytearray(volume) + payload = par + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting Heparin bolus volume parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_vol = str(volume) + print("Heparin bolus volume parameter set to " + str_vol + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_dialysate_tempeature(self, temp): + """ + Constructs and sends the set dialysate temperature parameter command. + Constraints: + Must be logged into HD. + Temperature must be floating point value and should be between 35.0 and 38.0 deg C + + @param temp: float - set dialysate temperature (in deg C) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_DIALYSATE_TEMPERATURE) + tmp = float_to_bytearray(temp) + payload = par + tmp + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting dialysate temperature parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_tmp = str(temp) + print("Dialysate temperature parameter set to " + str_tmp + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + + def cmd_set_ultrafiltration_volume(self, volume): + """ + Constructs and sends the set ultrafiltration volume parameter command. + Constraints: + Must be logged into HD. + Volume must be floating point value and should be between 0.0 and 8.0L + + @param volume: float - set ultrafiltration volume (in L) + @return: 1 if successful, zero otherwise + """ + + par = integer_to_bytearray(self.HD_TREATMENT_PARAMETER_UF_VOLUME) + vol = float_to_bytearray(volume) + payload = par + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_SET_TREATMENT_PARAMETER, + payload=payload) + + print("setting ultrafiltration volume parameter") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # print(received_message) + str_vol = str(volume) + print("Ultrafiltration volume parameter set to " + str_vol + ": " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False + Index: dialin/hd/ui_proxy.py =================================================================== diff -u -r17e48d8bf1a8960537d0615f7118bb8532e1015c -r13a03d199a7b202d61423587ca7c72e00c0df439 --- dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 17e48d8bf1a8960537d0615f7118bb8532e1015c) +++ dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 13a03d199a7b202d61423587ca7c72e00c0df439) @@ -40,15 +40,30 @@ 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 UF_CMD_PAUSE = 0 UF_CMD_RESUME = 1 + + # UF change option IDs UF_CMD_CHANGE_TIME_TO_ADJUST = 0 UF_CMD_CHANGE_RATE_TO_ADJUST = 1 + + # in-treatment change response codes RESPONSE_REJECTED = 0 RESPONSE_ACCEPTED = 1 + # start treatment command IDs + START_TREATMENT_CMD_INITIATE_TREATMENT_WORKFLOW = 0 + START_TREATMENT_CMD_CANCEL_TREATMENT_WORKFLOW = 1 + START_TREATMENT_CMD_START_TREATMENT = 2 + # HD version message field positions START_POS_MAJOR = DenaliMessage.PAYLOAD_START_INDEX END_POS_MAJOR = START_POS_MAJOR + 1 @@ -152,9 +167,48 @@ 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._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._handler_treatment_param_settings) # initialize variables that will be populated by HD version response self.hd_version = None + # initialize treatment parameters that Dialin user sets + self.blood_flow_rate = 0 + self.dialysate_flow_rate = 0 + self.treatment_duration = 0 + self.heparin_dispense_rate = 0.0 + self.heparin_bolus_volume = 0.0 + self.heparin_pre_stop_time = 0 + self.saline_bolus_volume = 0 + self.acid_concentrate = 0 + self.bicarb_concentrate = 0 + self.dialyzer_type = 0 + self.dialysate_temperature = 0.0 + self.arterial_pressure_low_alarm_limit = 0 + self.arterial_pressure_high_alarm_limit = 0 + self.venous_pressure_low_alarm_limit = 0 + self.venous_pressure_high_alarm_limit = 0 + self.blood_pressure_meas_interval = 0 + self.rinseback_flow_rate = 0 + # initialize variables that will be populated by treatment parameters response message + self.treatment_parameters_valid = False + self.blood_flow_rate_reject_reason = 0 + self.dialysate_flow_rate_reject_reason = 0 + self.treatment_duration_reject_reason = 0 + self.heparin_dispense_rate_reject_reason = 0 + self.heparin_bolus_volume_reject_reason = 0 + self.heparin_pre_stop_time_reject_reason = 0 + self.saline_bolus_volume_reject_reason = 0 + self.acid_concentrate_reject_reason = 0 + self.bicarb_concentrate_reject_reason = 0 + self.dialyzer_type_reject_reason = 0 + self.dialysate_temperature_reject_reason = 0 + self.arterial_pressure_low_alarm_limit_reject_reason = 0 + self.arterial_pressure_high_alarm_limit_reject_reason = 0 + self.venous_pressure_low_alarm_limit_reject_reason = 0 + self.venous_pressure_high_alarm_limit_reject_reason = 0 + self.blood_pressure_meas_interval_reject_reason = 0 + self.rinseback_flow_rate_reject_reason = 0 # initialize variables that will be populated by treatment parameter ranges message self.min_treatment_duration_min = 0 self.max_treatment_duration_min = 0 @@ -393,6 +447,48 @@ "min_dialysate_flow_rate_ml_min", "max_dialysate_flow_rate_ml_min" ]) + def _handler_treatment_param_settings(self, message): + """ + Handler for response from HD regarding validation of treatment parameters. + + @param message: response message from HD regarding validity of provided treatment parameters.\n + U32 Minimum treatment duration setting (in min.). \n + U32 Maximum treatment duration setting (in min.). \n + F32 Minimum ultrafiltration volume (in mL). \n + F32 Maximum ultrafiltration volume (in mL). \n + U32 Minimum dialysate flow rate (in mL/min). \n + U32 Maximum dialysate flow rate (in mL/min). + + @return: none + """ + mintime = struct.unpack('i', bytearray( + message['message'][self.START_POS_MIN_TREAT_TIME:self.END_POS_MIN_TREAT_TIME])) + maxtime = struct.unpack('i', bytearray( + message['message'][self.START_POS_MAX_TREAT_TIME:self.END_POS_MAX_TREAT_TIME])) + minufvol = struct.unpack('f', bytearray( + message['message'][self.START_POS_MIN_UF_VOL:self.END_POS_MIN_UF_VOL])) + maxufvol = struct.unpack('f', bytearray( + message['message'][self.START_POS_MAX_UF_VOL:self.END_POS_MAX_UF_VOL])) + mindialrt = struct.unpack('i', bytearray( + message['message'][self.START_POS_MIN_DIAL_RATE:self.END_POS_MIN_DIAL_RATE])) + maxdialrt = struct.unpack('i', bytearray( + message['message'][self.START_POS_MAX_DIAL_RATE:self.END_POS_MAX_DIAL_RATE])) + + self.min_treatment_duration_min = mintime[0] + self.max_treatment_duration_min = maxtime[0] + self.min_uf_volume_ml = minufvol[0] + self.max_uf_volume_ml = maxufvol[0] + self.min_dialysate_flow_rate_ml_min = mindialrt[0] + self.max_dialysate_flow_rate_ml_min = maxdialrt[0] + + @_publish([ + "min_treatment_duration_min", + "max_treatment_duration_min", + "min_uf_volume_ml", + "max_uf_volume_ml", + "min_dialysate_flow_rate_ml_min", + "max_dialysate_flow_rate_ml_min" + ]) def _handler_treatment_param_ranges(self, message): """ Handler for response from HD regarding valid treatment parameter ranges. @@ -645,7 +741,7 @@ """ Constructs and sends a ui UF change settings command message - @param vol (float): new ultrafiltration volume setting (in L) + @param vol: (float) new ultrafiltration volume setting (in L) @return: none """ @@ -668,8 +764,8 @@ """ Constructs and sends a ui UF change settings command message - @param vol (float): new ultrafiltration volume setting (in L) - @param adj (int): 0 for adjust time, 1 for adjust rate + @param vol: (float) new ultrafiltration volume setting (in L) + @param adj: (int) 0 for adjust time, 1 for adjust rate @return: none """ @@ -695,10 +791,10 @@ """ 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 + @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 """ @@ -718,16 +814,16 @@ return 0 - def cmd_ui_treatment_duration_setting_change_request(self, timeMin=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 - @param timeMin (int): treatment time (in min). + @param time_min: (int) treatment time (in min). @return: none """ - payload = integer_to_bytearray(timeMin) + 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, payload=payload) @@ -739,18 +835,18 @@ return 0 - def cmd_ui_blood_and_dialysate_flow_settings_change_request(self, bloodFlow, dialFlow): + def cmd_ui_blood_and_dialysate_flow_settings_change_request(self, blood_flow, dial_flow): """ Constructs and sends a ui blood & dialysate flow settings change request by user message - @param bloodFlow (int): blood flow rate set point (in mL/min). - @param dialFlow (int): dialysate flow rate set point (in mL/min). + @param blood_flow: (int) blood flow rate set point (in mL/min). + @param dial_flow: (int) dialysate flow rate set point (in mL/min). @return: none """ - bld = integer_to_bytearray(bloodFlow) - dial = integer_to_bytearray(dialFlow) + bld = integer_to_bytearray(blood_flow) + 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, @@ -761,3 +857,120 @@ self.can_interface.send(message, 0) return 0 + + def cmd_ui_start_treatment_request(self, cmnd=START_TREATMENT_CMD_INITIATE_TREATMENT_WORKFLOW): + """ + Constructs and sends a ui start treatment command message + Constraints: + Command must be one of the following: + START_TREATMENT_CMD_INITIATE_TREATMENT_WORKFLOW = 0 + START_TREATMENT_CMD_CANCEL_TREATMENT_WORKFLOW = 1 + START_TREATMENT_CMD_START_TREATMENT = 2 + + @param cmnd: (int) start treatment command code + + @return: none + """ + + 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, + payload=payload) + + print("Sending start treatment command request.") + + self.can_interface.send(message, 0) + + return 0 + + def cmd_ui_confirm_treatment_parameters(self): + """ + Constructs and sends a ui confirm treatment parameters message + + @return: none + """ + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS) + + print("Sending confirm treatment parameters messge.") + + self.can_interface.send(message, 0) + + return 0 + + def set_treatment_parameters(self, bld_flow, dia_flow, duration, hep_rate, hep_bol, hep_stop, sal_bol, + acid, bicarb, dialyzer, dia_temp, art_low, art_high, ven_low, ven_high, + bp_intvl, rb_flow): + """ + Constructs and sends a ui set treatment parameters message + Constraints: + HD must be in treatment parameters mode + + @param bld_flow: (int) blood flow rate (in mL/min) + @param dia_flow: (int) dialysate flow rate (in mL/min) + @param duration: (int) treatment duration (in min) + @param hep_rate: (float) Heparin dispense rate (in mL/hr) + @param hep_bol: (float) Heparin bolus volume (in mL) + @param hep_stop: (int) Heparin pre-stop time (in min) + @param sal_bol: (int) Saline bolus volume (in mL) + @param acid: (int) acid concentrate type + @param bicarb: (int) bicarbonate concentrate type + @param dialyzer: (int) dialyzer type + @param dia_temp: (float) dialysate temperature (in deg C) + @param art_low: (int) arterial pressure low alarm limit (in mmHg) + @param art_high: (int) arterial pressure high alarm limit (in mmHg) + @param ven_low: (int) venous pressure low alarm limit (in mmHg) + @param ven_high: (int) venous pressure high alarm limit (in mmHg) + @param bp_intvl: (int) blood pressure measurement interval (in min) + @param rb_flow: (int) rinseback flow rate (in mL/min) + + @return: none + """ + self.blood_flow_rate = bld_flow + self.dialysate_flow_rate = dia_flow + self.treatment_duration = duration + self.heparin_dispense_rate = hep_rate + self.heparin_bolus_volume = hep_bol + self.heparin_pre_stop_time = hep_stop + self.saline_bolus_volume = sal_bol + self.acid_concentrate = acid + self.bicarb_concentrate = bicarb + self.dialyzer_type = dialyzer + self.dialysate_temperature = dia_temp + self.arterial_pressure_low_alarm_limit = art_low + self.arterial_pressure_high_alarm_limit = art_high + self.venous_pressure_low_alarm_limit = ven_low + self.venous_pressure_high_alarm_limit = ven_high + self.blood_pressure_meas_interval = bp_intvl + self.rinseback_flow_rate = rb_flow + + bld = integer_to_bytearray(bld_flow) + dia = integer_to_bytearray(dia_flow) + dur = integer_to_bytearray(duration) + hdr = float_to_bytearray(hep_rate) + hbv = float_to_bytearray(hep_bol) + hps = integer_to_bytearray(hep_stop) + sal = integer_to_bytearray(sal_bol) + acc = integer_to_bytearray(acid) + bic = integer_to_bytearray(bicarb) + dzr = integer_to_bytearray(dialyzer) + tmp = float_to_bytearray(dia_temp) + apl = integer_to_bytearray(art_low) + aph = integer_to_bytearray(art_high) + vpl = integer_to_bytearray(ven_low) + vph = integer_to_bytearray(ven_high) + bpi = integer_to_bytearray(bp_intvl) + rbf = integer_to_bytearray(rb_flow) + + payload = bld+dia+dur+hdr+hbv+hps+sal+acc+bic+dzr+tmp+apl+aph+vpl+vph+bpi+rbf + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_UI_NEW_TREATMENT_PARAMS, + payload=payload) + + print("Sending treatment parameters to HD.") + + self.can_interface.send(message, 0) + + return 0 Index: tests/set_accels_cal.py =================================================================== diff -u -r4c82155574ae155fcb658f4c81ca852f65b71193 -r13a03d199a7b202d61423587ca7c72e00c0df439 --- tests/set_accels_cal.py (.../set_accels_cal.py) (revision 4c82155574ae155fcb658f4c81ca852f65b71193) +++ tests/set_accels_cal.py (.../set_accels_cal.py) (revision 13a03d199a7b202d61423587ca7c72e00c0df439) @@ -25,37 +25,37 @@ # create an HD object called hd hd = HD() # create an DG object called hd - dg = DG() + #dg = DG() sleep(2) # log in to HD and DG as tester if hd.cmd_log_in_to_hd() == 0: exit(1) - if dg.cmd_log_in_to_dg() == 0: - exit(1) + #if dg.cmd_log_in_to_dg() == 0: + # exit(1) sleep(1) #reset calibrations hd.accel.cmd_set_accel_calibration(0, 0, 0) - dg.accel.cmd_set_accel_calibration(0, 0, 0) + #dg.accel.cmd_set_accel_calibration(0, 0, 0) #wait for new readings after calibration reset sleep(5) #calculate offsets (assuming HD and DG systems are level) hd_offsets = hd.accel.get_accel_vector() - dg_offsets = dg.accel.get_accel_vector() + #dg_offsets = dg.accel.get_accel_vector() hd_offsets.x *= -1.0 hd_offsets.y *= -1.0 hd_offsets.z -= 1.0 hd_offsets.z *= -1.0 - dg_offsets.x *= -1.0 - dg_offsets.y *= -1.0 - dg_offsets.z -= 1.0 - dg_offsets.z *= -1.0 + #dg_offsets.x *= -1.0 + #dg_offsets.y *= -1.0 + #dg_offsets.z -= 1.0 + #dg_offsets.z *= -1.0 #set new offsets hd.accel.cmd_set_accel_calibration(hd_offsets.x, hd_offsets.y, hd_offsets.z) - dg.accel.cmd_set_accel_calibration(dg_offsets.x, dg_offsets.y, dg_offsets.z) + #dg.accel.cmd_set_accel_calibration(dg_offsets.x, dg_offsets.y, dg_offsets.z) exit(0) Index: tests/set_flow_sensors_cal.py =================================================================== diff -u -rd134777c4f35ca58a14720a668c155bed3b0c124 -r13a03d199a7b202d61423587ca7c72e00c0df439 --- tests/set_flow_sensors_cal.py (.../set_flow_sensors_cal.py) (revision d134777c4f35ca58a14720a668c155bed3b0c124) +++ tests/set_flow_sensors_cal.py (.../set_flow_sensors_cal.py) (revision 13a03d199a7b202d61423587ca7c72e00c0df439) @@ -32,5 +32,5 @@ sleep(1) #set calibrations ******** MUST PROVIDE GAIN/OFFSET FOR EACH SENSOR HERE ********* - hd.bloodflow.cmd_set_blood_flow_calibration(1.27, -50.0) - hd.dialysate_inlet_flow.cmd_set_dialysate_flow_calibration(1.14, -3.67) + hd.bloodflow.cmd_set_blood_flow_calibration(0.0, 0.0) + hd.dialysate_inlet_flow.cmd_set_dialysate_flow_calibration(0.0, 0.0) Index: tests/uf_test.py =================================================================== diff -u -r4c82155574ae155fcb658f4c81ca852f65b71193 -r13a03d199a7b202d61423587ca7c72e00c0df439 --- tests/uf_test.py (.../uf_test.py) (revision 4c82155574ae155fcb658f4c81ca852f65b71193) +++ tests/uf_test.py (.../uf_test.py) (revision 13a03d199a7b202d61423587ca7c72e00c0df439) @@ -27,6 +27,9 @@ dg = DG() sleep(2) +# hd.ui.cmd_ui_start_treatment_request() +# exit(0) + # log in to HD and DG as tester # if hd.cmd_log_in_to_hd() == 0: # exit(1)