Index: dialin/common/msg_ids.py =================================================================== diff -u -ra1ee274cb5cab5f83deae1c39efef89ee81289df -rd6a2e3e1821b5c78f81ad71b10f0809eff1181ae --- dialin/common/msg_ids.py (.../msg_ids.py) (revision a1ee274cb5cab5f83deae1c39efef89ee81289df) +++ dialin/common/msg_ids.py (.../msg_ids.py) (revision d6a2e3e1821b5c78f81ad71b10f0809eff1181ae) @@ -278,10 +278,30 @@ MSG_ID_HD_SYRINGE_PUMP_ADC_READ_COUNTER_OVERRIDE = 0X805C MSG_ID_HD_BUBBLES_DATA_SEND_INTERVAL_OVERRIDE = 0X805D MSG_ID_HD_BUBBLE_STATUS_OVERRIDE = 0X805E + MSG_ID_HD_BLOOD_PRIME_VOLUME_OVERRIDE = 0X805F MSG_ID_HD_BUBBLE_SELF_TEST_REQUEST = 0X8060 MSG_ID_HD_BLOOD_PRIME_SAFETY_VOLUME_OVERRIDE = 0X8061 - MSG_ID_HD_SWITCHES_STATUS_OVERRIDE = 0X8062 - MSG_ID_HD_SWITCHES_PUBLISH_INTERVAL_OVERRIDE = 0X8063 + MSG_ID_HD_SWITCHES_STATUS_OVERRIDE = 0x8062 + MSG_ID_HD_SWITCHES_PUBLISH_INTERVAL_OVERRIDE = 0x8063 + MSG_ID_HD_BATTERY_REMAINING_PERCENT_OVERRIDE = 0x8064 + MSG_ID_HD_TEMPERATURES_VALUE_OVERRIDE = 0x8065 + MSG_ID_HD_TEMPERATURES_PUBLISH_INTERVAL_OVERRIDE = 0x8066 + MSG_ID_HD_FANS_PUBLISH_INTERVAL_OVERRIDE = 0x8067 + MSG_ID_HD_FANS_RPM_OVERRIDE = 0x8068 + MSG_ID_HD_RINSEBACK_VOLUME_OVERRIDE = 0x8069 + MSG_ID_HD_RINSEBACK_SAFETY_VOLUME_OVERRIDE = 0x806A + MSG_ID_HD_ALARM_STATUS_PUBLISH_INTERVAL_OVERRIDE = 0x806B + MSG_ID_HD_TREATMENT_TIME_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x806C + MSG_ID_HD_TREATMENT_RANGES_PUBLISH_INTERVAL_OVERRIDE = 0x806D + MSG_ID_HD_TREATMENT_STOP_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x806E + MSG_ID_HD_BLOOD_PRIME_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x806F + MSG_ID_HD_RINSEBACK_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x8070 + MSG_ID_HD_STANDBY_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x8071 + MSG_ID_HD_OP_MODE_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x8072 + MSG_ID_HD_PRE_TREATMENT_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x8073 + MSG_ID_HD_TREATMENT_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x8074 + MSG_ID_HD_POST_TREATMENT_DATA_PUBLISH_INTERVAL_OVERRIDE = 0x8075 + MSG_ID_DG_TESTER_LOGIN_REQUEST = 0XA000 MSG_ID_DG_ALARM_STATE_OVERRIDE = 0XA001 MSG_ID_DG_WATCHDOG_TASK_CHECKIN_OVERRIDE = 0XA002 @@ -311,7 +331,7 @@ MSG_ID_DRAIN_PUMP_SET_DELTA_PRESSURE_OVERRIDE = 0XA01C MSG_ID_DG_SWITCHES_STATUS_OVERRIDE = 0XA01D MSG_ID_DG_SWITCHES_PUBLISH_INTERVAL_OVERRIDE = 0XA01E - MSG_ID___AVAILABLE_14 = 0XA01F + MSG_ID_DG_OP_MODE_PUBLISH_INTERVAL_OVERRIDE = 0XA01F MSG_ID___AVAILABLE_15 = 0XA020 MSG_ID___AVAILABLE_16 = 0XA021 MSG_ID_DG_SOFTWARE_RESET_REQUEST = 0XA022 Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -rc19568936f7925714a39b7951eae672ab91769a4 -rd6a2e3e1821b5c78f81ad71b10f0809eff1181ae --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision c19568936f7925714a39b7951eae672ab91769a4) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision d6a2e3e1821b5c78f81ad71b10f0809eff1181ae) @@ -17,6 +17,7 @@ from .alarms import DGAlarms from .concentrate_pumps import ConcentratePumps from .conductivity_sensors import ConductivitySensors +from .constants import RESET, NO_RESET from .drain_pump import DGDrainPump from .fluid_leak import DGFluidLeak from .fans import Fans @@ -367,3 +368,45 @@ self.can_interface.send(message, 0) self.logger.debug("Sent request to DG to reset...") self.dg_set_logged_in_status(False) + + def cmd_dg_op_mode_broadcast_interval_override(self, ms:int=250, reset:int=NO_RESET) -> int: + """ + Constructs and sends the DG op mode broadcast interval override command + Constraints: + Must be logged into DG. + Given interval must be non-zero and a multiple of the DG general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=MsgIds.MSG_ID_DG_OP_MODE_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override DG op. mode broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("DG op. mode broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False Index: dialin/hd/alarms.py =================================================================== diff -u -ra1ee274cb5cab5f83deae1c39efef89ee81289df -rd6a2e3e1821b5c78f81ad71b10f0809eff1181ae --- dialin/hd/alarms.py (.../alarms.py) (revision a1ee274cb5cab5f83deae1c39efef89ee81289df) +++ dialin/hd/alarms.py (.../alarms.py) (revision d6a2e3e1821b5c78f81ad71b10f0809eff1181ae) @@ -611,6 +611,48 @@ self.logger.debug("Timeout!!!!") return False + def cmd_alarm_status_broadcast_interval_override(self, ms:int=250, reset:int=NO_RESET): + """ + Constructs and sends the alarm status broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_ALARM_STATUS_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override alarm status broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Alarm status broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + def cmd_alarm_audio_volume_override(self, volume:int=5, reset:int=NO_RESET): """ Constructs and sends the alarm audio volume override command Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -rc19568936f7925714a39b7951eae672ab91769a4 -rd6a2e3e1821b5c78f81ad71b10f0809eff1181ae --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision c19568936f7925714a39b7951eae672ab91769a4) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision d6a2e3e1821b5c78f81ad71b10f0809eff1181ae) @@ -43,7 +43,8 @@ from ..utils.conversions import integer_to_bytearray from ..utils.base import _AbstractSubSystem, _publish, _LogManager -from .constants import NO_RESET +from ..utils.checks import check_broadcast_interval_override_ms +from .constants import RESET, NO_RESET from ..common.msg_defs import MsgIds, MsgFieldPositions from ..common.hd_defs import HDOpModes @@ -320,3 +321,214 @@ self.can_interface.send(message, 0) self.logger.debug("Sent request to HD to reset...") self.hd_set_logged_in_status(False) + + def cmd_op_mode_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the HD operation mode broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_OP_MODE_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override operation mode data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Operation mode data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_standby_mode_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the standby mode broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_STANDBY_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override standby mode data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Standby mode data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_pre_treatment_mode_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the pre-treatment mode broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_PRE_TREATMENT_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override pre-treatment mode broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Pre-treatment mode data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_treatment_mode_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the treatment mode broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_TREATMENT_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override treatment mode data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Treatment mode data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_post_treatment_mode_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the post-treatment mode broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_POST_TREATMENT_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override post-treatment mode data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Post-treatment mode data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + Index: dialin/hd/treatment.py =================================================================== diff -u -r2b80b3c2a26012faf121aeb6be0b3f983061be1c -rd6a2e3e1821b5c78f81ad71b10f0809eff1181ae --- dialin/hd/treatment.py (.../treatment.py) (revision 2b80b3c2a26012faf121aeb6be0b3f983061be1c) +++ dialin/hd/treatment.py (.../treatment.py) (revision d6a2e3e1821b5c78f81ad71b10f0809eff1181ae) @@ -20,6 +20,8 @@ from ..common.msg_defs import MsgIds, MsgFieldPositions from logging import Logger from ..utils.conversions import integer_to_bytearray, float_to_bytearray +from ..utils.checks import check_broadcast_interval_override_ms +from .constants import RESET, NO_RESET class HDTreatment(_AbstractSubSystem): @@ -118,19 +120,22 @@ self.blood_prime_state = 0 self.treatment_end_state = 0 self.treatment_stop_state = 0 + self.dialysis_state = 0 # saline bolus status self.saline_bolus_max_vol = 0 self.saline_bolus_cum_vol = 0.0 self.saline_bolus_bol_vol = 0.0 # blood prime status self.blood_prime_tgt_vol = 0.0 self.blood_prime_cum_vol = 0.0 + self.blood_prime_ind_cum_vol = 0.0 # rinseback status self.rinseback_tgt_vol = 0.0 self.rinseback_cum_vol = 0.0 self.rinseback_cur_rate = 0 self.rinseback_timeout_secs = 0 self.rinseback_countdown_secs = 0 + self.rinseback_safety_cum_vol = 0.0 # re-circulation status self.recirc_timeout_secs = 0 self.recirc_countdown_secs = 0 @@ -161,52 +166,84 @@ def get_treatment_state(self): """ - Gets the treatment state + Gets the current treatment state - @return: The treatment state + @return: The current treatment state ID """ return self.treatment_state - def get_treatment_uf_state(self): + def get_treatment_UF_state(self): """ - Gets the treatment uf state + Gets the current treatment ultrafiltration state - @return: The treatment uf state + @return: The current treatment ultrafiltration state ID """ return self.treatment_uf_state - def get_saline_bolus_state(self): + def get_treatment_saline_bolus_state(self): """ - Gets the current saline bolus state + Gets the current treatment saline bolus state - @return: The saline bolus state + @return: The current treatment saline bolus state ID """ return self.saline_bolus_state - def get_heparin_state(self): + def get_treatment_heparin_state(self): """ - Gets the current Heparin state + Gets the current treatment Heparin state - @return: The Heparin state + @return: The current treatment Heparin state ID """ return self.heparin_state - def get_rinseback_state(self): + def get_treatment_rinseback_state(self): """ - Gets the current rinseback state + Gets the current treatment rinseback state - @return: The rinseback state + @return: The current treatment rinseback state ID """ return self.rinseback_state - def get_treatment_recirc_state(self): + def get_treatment_recirculate_state(self): """ Gets the current treatment recirculate state - @return: The treatment recirculate state + @return: The current treatment recirculate state ID """ return self.treatment_recirculate_state + def get_treatment_blood_prime_state(self): + """ + Gets the current treatment blood prime state + + @return: The current treatment blood prime state ID + """ + return self.blood_prime_state + + def get_treatment_end_state(self): + """ + Gets the current treatment end state + + @return: The current treatment end state ID + """ + return self.treatment_end_state + + def get_treatment_stop_state(self): + """ + Gets the current treatment stop state + + @return: The current treatment stop state ID + """ + return self.treatment_stop_state + + def get_dialysis_state(self): + """ + Gets the current treatment dialysis state + + @return: The current treatment dialysis state ID + """ + return self.dialysis_state + def get_saline_bolus_max_volume(self): """ Returns maximum volume (in mL) saline that can be delivered to a patient @@ -231,7 +268,70 @@ """ return self.saline_bolus_bol_vol + def get_blood_prime_target_volume(self): + """ + Returns blood prime target volume (in mL) + @return: The blood prime target volume + """ + return self.blood_prime_tgt_vol + + def get_blood_prime_volume_delivered(self): + """ + Returns blood prime volume (in mL) delivered + + @return: The blood prime volume delivered + """ + return self.blood_prime_cum_vol + + def get_blood_prime_safety_volume_delivered(self): + """ + Returns blood prime safety volume (in mL) delivered + + @return: The blood prime safety volume delivered + """ + return self.blood_prime_ind_cum_vol + + def get_rinseback_target_volume(self): + """ + Returns rinseback target volume (in mL) + + @return: The rinseback target volume + """ + return self.rinseback_tgt_vol + + def get_rinseback_volume_delivered(self): + """ + Returns rinseback volume (in mL) delivered + + @return: The rinseback volume delivered + """ + return self.rinseback_cum_vol + + def get_rinseback_safety_volume_delivered(self): + """ + Returns rinseback safety volume (in mL) delivered + + @return: The rinseback safety volume delivered + """ + return self.rinseback_safety_cum_vol + + def get_rinseback_timeout(self): + """ + Returns rinseback timeout period (in seconds) + + @return: The rinseback timeout period + """ + return self.rinseback_timeout_secs + + def get_rinseback_timeout_countdown(self): + """ + Returns rinseback timeout countdown (in seconds) + + @return: The rinseback timeout countdown + """ + return self.rinseback_countdown_secs + @_publish([ "treatment_time_prescribed", "treatment_time_elapsed", @@ -266,7 +366,8 @@ "treatment_recirculate_state", "blood_prime_state", "treatment_end_state", - "treatment_stop_state" + "treatment_stop_state", + "dialysis_state" ]) def _handler_treatment_state_sync(self, message): """ @@ -295,6 +396,8 @@ message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8])) txs = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_9:MsgFieldPositions.END_POS_FIELD_9])) + dia = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_10:MsgFieldPositions.END_POS_FIELD_10])) self.treatment_state = tst[0] self.treatment_uf_state = ufs[0] @@ -305,6 +408,7 @@ self.blood_prime_state = bpr[0] self.treatment_end_state = txe[0] self.treatment_stop_state = txs[0] + self.dialysis_state = dia[0] @_publish([ "saline_bolus_max_vol", @@ -357,16 +461,20 @@ message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4])) cdn = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5])) + rsv = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6])) self.rinseback_tgt_vol = tgt[0] self.rinseback_cum_vol = cum[0] self.rinseback_cur_rate = rat[0] self.rinseback_timeout_secs = tmo[0] self.rinseback_countdown_secs = cdn[0] + self.rinseback_safety_cum_vol = rsv[0] @_publish([ "blood_prime_tgt_vol", - "blood_prime_cum_vol" + "blood_prime_cum_vol", + "blood_prime_ind_cum_vol" ]) def _handler_blood_prime_data_sync(self, message): """ @@ -381,9 +489,12 @@ message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) cum = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) + ind = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3])) self.blood_prime_tgt_vol = tgt[0] self.blood_prime_cum_vol = cum[0] + self.blood_prime_ind_cum_vol = ind[0] @_publish([ "recirc_timeout_secs", @@ -1095,3 +1206,350 @@ else: self.logger.debug("Timeout!!!!") return False + + def cmd_blood_prime_volume_delivered_override(self, volume: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends the blood prime volume delivered override command + Constraints: + Must be logged into HD. + + @param volume: float - volume (in mL) of blood delivered during blood prime (must be positive) + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + vol = float_to_bytearray(volume) + payload = rst + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_BLOOD_PRIME_VOLUME_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD blood prime volume delivered (in mL).") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + self.logger.debug("Blood prime volume delivered overridden to " + str(volume) + " 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: + self.logger.debug("Timeout!!!!") + return False + + def cmd_blood_prime_safety_volume_delivered_override(self, volume: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends the blood prime safety volume delivered override command + Constraints: + Must be logged into HD. + + @param volume: float - safety volume (in mL) of blood delivered during blood prime (must be positive) + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + vol = float_to_bytearray(volume) + payload = rst + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_BLOOD_PRIME_SAFETY_VOLUME_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD blood prime safety volume delivered (in mL).") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + self.logger.debug("Blood prime safety volume delivered overridden to " + str(volume) + " 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: + self.logger.debug("Timeout!!!!") + return False + + def cmd_rinseback_volume_delivered_override(self, volume: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends the rinseback volume delivered override command + Constraints: + Must be logged into HD. + + @param volume: float - volume (in mL) of blood returned during rinseback (must be positive) + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + vol = float_to_bytearray(volume) + payload = rst + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_RINSEBACK_VOLUME_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD rinseback volume delivered (in mL).") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + self.logger.debug("Rinseback volume delivered overridden to " + str(volume) + " 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: + self.logger.debug("Timeout!!!!") + return False + + def cmd_rinseback_safety_volume_delivered_override(self, volume: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends the rinseback safety volume delivered override command + Constraints: + Must be logged into HD. + + @param volume: float - safety volume (in mL) of blood returned during rinseback (must be positive) + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + vol = float_to_bytearray(volume) + payload = rst + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_RINSEBACK_SAFETY_VOLUME_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD rinseback safety volume delivered (in mL).") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + self.logger.debug("Rinseback safety volume delivered overridden to " + str(volume) + " 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: + self.logger.debug("Timeout!!!!") + return False + + def cmd_blood_prime_submode_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the treatment blood prime sub-mode broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_BLOOD_PRIME_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override treatment blood prime sub-mode data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Treatment blood prime sub-mode data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_treatment_stop_submode_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the treatment stop sub-mode broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_TREATMENT_STOP_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override treatment stop sub-mode data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Treatment stop sub-mode data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_rinseback_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the treatment rinseback sub-mode broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_RINSEBACK_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override treatment rinseback sub-mode data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Treatment rinseback sub-mode data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_treatment_param_ranges_broadcast_interval_override(self, ms: int = 60000, reset: int = NO_RESET): + """ + Constructs and sends the treatment parameter ranges broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_TREATMENT_RANGES_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override treatment parameter ranges data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Treatment parameter ranges data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_treatment_time_broadcast_interval_override(self, ms: int = 250, reset: int = NO_RESET): + """ + Constructs and sends the treatment time data broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_TREATMENT_TIME_DATA_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override treatment time data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Treatment time data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False +