Index: dialin/dg/accelerometer.py =================================================================== diff -u -r10b117b1e65980a9c1a93a4c718c33fe2976f1e4 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/dg/accelerometer.py (.../accelerometer.py) (revision 10b117b1e65980a9c1a93a4c718c33fe2976f1e4) +++ dialin/dg/accelerometer.py (.../accelerometer.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -21,8 +21,8 @@ from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET, NO_RESET from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger - class DGAccelerometer(_AbstractSubSystem): """ Hemodialysis Delivery (DG) Dialin API sub-class for accelerometer related commands. @@ -71,13 +71,14 @@ START_POS_TILT_Z = END_POS_TILT_Y END_POS_TILT_Z = START_POS_TILT_Z + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HDAccelerometer constructor """ super().__init__() self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id @@ -160,7 +161,7 @@ message_id=self.MSG_ID_DG_ACCEL_OVERRIDE, payload=payload) - print("override DG accelerometer axis magnitude") + self.logger.debug("override DG accelerometer axis magnitude") # Send message received_message = self.can_interface.send(message) @@ -171,12 +172,12 @@ str_res = "reset back to normal. " else: str_res = str(mag) + " g. " - print("Accelerometer axis " + str(axis) + " overridden to " + str_res + + self.logger.debug("Accelerometer axis " + str(axis) + " 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_accel_max_vector_override(self, mag, axis, reset=NO_RESET): @@ -200,7 +201,7 @@ message_id=self.MSG_ID_DG_ACCEL_MAX_OVERRIDE, payload=payload) - print("override DG accelerometer axis maximum magnitude") + self.logger.debug("override DG accelerometer axis maximum magnitude") # Send message received_message = self.can_interface.send(message) @@ -211,12 +212,12 @@ str_res = "reset back to normal. " else: str_res = str(mag) + " g. " - print("Accelerometer max. axis " + str(axis) + " overridden to " + str_res + + self.logger.debug("Accelerometer max. axis " + str(axis) + " 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_accel_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -239,7 +240,7 @@ message_id=self.MSG_ID_DG_ACCEL_SEND_INTERVAL_OVERRIDE, payload=payload) - print("override DG accelerometer broadcast interval") + self.logger.debug("override DG accelerometer broadcast interval") # Send message received_message = self.can_interface.send(message) @@ -250,12 +251,12 @@ str_res = "reset back to normal: " else: str_res = str(ms) + " ms: " - print("Accelerometer broadcast interval overridden to " + str_res + + self.logger.debug("Accelerometer 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_set_accel_calibration(self, x_offset, y_offset, z_offset): @@ -277,20 +278,20 @@ message_id=self.MSG_ID_DG_ACCEL_SET_CALIBRATION, payload=payload) - print("Setting DG accelerometer axis calibration offsets") + self.logger.debug("Setting DG accelerometer axis calibration offsets") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - print(received_message) + self.logger.debug(received_message) # str_res = str(flow) - print("DG accelerometer calibration axis offsets set to : " + str(x_offset) + ", " + str(y_offset) + ", " + + self.logger.debug("DG accelerometer calibration axis offsets set to : " + str(x_offset) + ", " + str(y_offset) + ", " + str(z_offset) + ". " + 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!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -rf40bfedd0bef6a8b37ef61e0749f908dd97c5095 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision f40bfedd0bef6a8b37ef61e0749f908dd97c5095) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -14,6 +14,7 @@ # ############################################################################ import struct +from .accelerometer import DGAccelerometer from .drain_pump import DGDrainPump from .hd_proxy import DGHDProxy from .load_cells import DGLoadCells @@ -138,6 +139,7 @@ self.dg_operation_sub_mode = 0 # Create command groups + self.accel = DGAccelerometer(self.can_interface, self.logger) self.hd_proxy = DGHDProxy(self.can_interface, self.logger) self.load_cells = DGLoadCells(self.can_interface, self.logger) self.pressures = DGPressures(self.can_interface, self.logger) @@ -165,14 +167,6 @@ """ return self.fpga_version - def get_version(self): - """ - Gets the DG fpga version - - @return: The fpga version - """ - return self.dg_version - def get_operation_mode(self): """ Gets the operation mode @@ -202,14 +196,10 @@ @return: None if unsuccessful, the version string if unpacked successfully """ - major = struct.unpack('B', bytearray( - message['message'][self.START_POS_MAJOR:self.END_POS_MAJOR])) - minor = struct.unpack('B', bytearray( - message['message'][self.START_POS_MINOR:self.END_POS_MINOR])) - micro = struct.unpack('B', bytearray( - message['message'][self.START_POS_MICRO:self.END_POS_MICRO])) - build = struct.unpack('H', bytearray( - message['message'][self.START_POS_BUILD:self.END_POS_BUILD])) + major = struct.unpack('B', bytearray(message['message'][self.START_POS_MAJOR:self.END_POS_MAJOR])) + minor = struct.unpack('B', bytearray(message['message'][self.START_POS_MINOR:self.END_POS_MINOR])) + micro = struct.unpack('B', bytearray(message['message'][self.START_POS_MICRO:self.END_POS_MICRO])) + build = struct.unpack('H', bytearray(message['message'][self.START_POS_BUILD:self.END_POS_BUILD])) fpga_id = struct.unpack('B', bytearray( message['message'][self.START_POS_FPGA_ID:self.END_POS_FPGA_ID])) @@ -291,7 +281,6 @@ Constructs and sends an DG safety shutdown override command via CAN bus. \returns response message if received, False if no response received - @param msg: byte array - properly formatted DG message to insert @return: 1 if successful, zero otherwise """ Index: dialin/dg/hd_proxy.py =================================================================== diff -u -r2cfc646e14640e82c5f6989a572737ce8256caa5 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 2cfc646e14640e82c5f6989a572737ce8256caa5) +++ dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,23 +1,23 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 hd_proxy.py +# @file hd_proxy.py # -# @date 14-Apr-2020 -# @author S. Nash +# @author (last) Peter Lucia +# @date (last) 29-Jun-2020 +# @author (original) Sean +# @date (original) 15-Apr-2020 # -# @brief -# -# ############################################################################ from ..utils.conversions import integer_to_bytearray from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGHDProxy(_AbstractSubSystem): @@ -39,13 +39,14 @@ RESERVOIR1 = 0 RESERVOIR2 = 1 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ @param can_interface: Denali CAN Messenger object """ super().__init__() self.can_interface = can_interface + self.logger = logger def cmd_switch_reservoirs(self, reservoirID=RESERVOIR1): """ @@ -69,7 +70,7 @@ message_id=self.MSG_ID_HD_SWITCH_RESERVOIRS_CMD, payload=payload) - print("switch reservoirs cmd sent to DG") + self.logger.debug("switch reservoirs cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -79,7 +80,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_fill(self, volume=1500): @@ -100,7 +101,7 @@ message_id=self.MSG_ID_HD_FILL_CMD, payload=payload) - print("fill cmd sent to DG") + self.logger.debug("fill cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -110,7 +111,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_drain(self, volume=200): @@ -131,7 +132,7 @@ message_id=self.MSG_ID_HD_DRAIN_CMD, payload=payload) - print("drain cmd sent to DG") + self.logger.debug("drain cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -141,7 +142,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_start_stop_dg(self, start=True): @@ -167,7 +168,7 @@ message_id=self.MSG_ID_HD_START_STOP_DG_CMD, payload=payload) - print(str+"DG cmd sent to DG") + self.logger.debug(str+"DG cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -177,7 +178,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_start_stop_trimmer_heater(self, start=True): @@ -200,7 +201,7 @@ message_id=self.MSG_ID_HD_START_STOP_DG_TRIMMER_HEATER, payload=payload) - print(str+"DG trimmer heater cmd sent to DG") + self.logger.debug(str+"DG trimmer heater cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -210,7 +211,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_start_heat_disinfection(self): Index: dialin/dg/heaters.py =================================================================== diff -u -r900f99812cee2e022fbbd46cd916b08a1397dda7 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/dg/heaters.py (.../heaters.py) (revision 900f99812cee2e022fbbd46cd916b08a1397dda7) +++ dialin/dg/heaters.py (.../heaters.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -180,7 +180,3 @@ else: self.logger.debug("Timeout!!!!") return False - - - - Index: dialin/dg/ro_pump.py =================================================================== diff -u -r2cfc646e14640e82c5f6989a572737ce8256caa5 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/dg/ro_pump.py (.../ro_pump.py) (revision 2cfc646e14640e82c5f6989a572737ce8256caa5) +++ dialin/dg/ro_pump.py (.../ro_pump.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,25 +1,25 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 ro_pump.py +# @file ro_pump.py # -# @date 14-Apr-2020 -# @author S. Nash +# @author (last) Dara Navaei +# @date (last) 01-Jul-2020 +# @author (original) Sean +# @date (original) 14-Apr-2020 # -# @brief -# -# ############################################################################ import struct from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET, NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGROPump(_AbstractSubSystem): @@ -50,14 +50,14 @@ RAMP_UP_STATE = 0 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ DGROPump constructor """ super().__init__() - self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id @@ -152,25 +152,25 @@ message_id=self.MSG_ID_RO_PUMP_SET_PT_OVERRIDE, payload=payload) - print("override RO pump pressure set point") + self.logger.debug("override RO pump pressure set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(pressure) - print( + self.logger.debug( "RO pump pressure set point overridden to " + str_res + " PSI: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_ro_flow_rate_override(self, flow, reset=NO_RESET): @@ -192,25 +192,25 @@ message_id=self.MSG_ID_RO_PUMP_SET_PT_OVERRIDE, payload=payload) - print("override RO pump pressure set point") + self.logger.debug("override RO pump pressure set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(flo) - print( + self.logger.debug( "RO flow rate overridden to " + str_res + " L/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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_ro_pump_data_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -233,24 +233,24 @@ message_id=self.MSG_ID_DG_RO_PUMP_BROADCAST_INTERVAL_OVERRIDE, payload=payload) - print("override RO pump data broadcast interval") + self.logger.debug("override RO pump data broadcast interval") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(mis) - print( + self.logger.debug( "RO pump data broadcast interval overridden to " + str_res + " ms: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/hd/accelerometer.py =================================================================== diff -u -r10b117b1e65980a9c1a93a4c718c33fe2976f1e4 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/accelerometer.py (.../accelerometer.py) (revision 10b117b1e65980a9c1a93a4c718c33fe2976f1e4) +++ dialin/hd/accelerometer.py (.../accelerometer.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -21,8 +21,8 @@ from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET, NO_RESET from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger - class HDAccelerometer(_AbstractSubSystem): """ Hemodialysis Delivery (HD) Dialin API sub-class for accelerometer related commands. @@ -71,13 +71,14 @@ START_POS_TILT_Z = END_POS_TILT_Y END_POS_TILT_Z = START_POS_TILT_Z + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HDAccelerometer constructor """ super().__init__() self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.hd_sync_broadcast_ch_id @@ -160,7 +161,7 @@ message_id=self.MSG_ID_HD_ACCEL_OVERRIDE, payload=payload) - print("override HD accelerometer axis magnitude") + self.logger.debug("override HD accelerometer axis magnitude") # Send message received_message = self.can_interface.send(message) @@ -171,12 +172,12 @@ str_res = "reset back to normal. " else: str_res = str(mag) + " g. " - print("Accelerometer axis " + str(axis) + " overridden to " + str_res + + self.logger.debug("Accelerometer axis " + str(axis) + " 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_accel_max_vector_override(self, mag, axis, reset=NO_RESET): @@ -200,7 +201,7 @@ message_id=self.MSG_ID_HD_ACCEL_MAX_OVERRIDE, payload=payload) - print("override HD accelerometer axis maximum magnitude") + self.logger.debug("override HD accelerometer axis maximum magnitude") # Send message received_message = self.can_interface.send(message) @@ -211,12 +212,12 @@ str_res = "reset back to normal. " else: str_res = str(mag) + " g. " - print("Accelerometer max. axis " + str(axis) + " overridden to " + str_res + + self.logger.debug("Accelerometer max. axis " + str(axis) + " 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_accel_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -239,7 +240,7 @@ message_id=self.MSG_ID_HD_ACCEL_SEND_INTERVAL_OVERRIDE, payload=payload) - print("override HD accelerometer broadcast interval") + self.logger.debug("override HD accelerometer broadcast interval") # Send message received_message = self.can_interface.send(message) @@ -250,12 +251,12 @@ str_res = "reset back to normal: " else: str_res = str(ms) + " ms: " - print("Accelerometer broadcast interval overridden to " + str_res + + self.logger.debug("Accelerometer 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_set_accel_calibration(self, x_offset, y_offset, z_offset): @@ -277,20 +278,20 @@ message_id=self.MSG_ID_HD_ACCEL_SET_CALIBRATION, payload=payload) - print("Setting HD accelerometer axis calibration offsets") + self.logger.debug("Setting HD accelerometer axis calibration offsets") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - print(received_message) + self.logger.debug(received_message) # str_res = str(flow) - print("HD accelerometer calibration axis offsets set to : " + str(x_offset) + ", " + str(y_offset) + ", " + + self.logger.debug("HD accelerometer calibration axis offsets set to : " + str(x_offset) + ", " + str(y_offset) + ", " + str(z_offset) + ". " + 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!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/hd/alarms.py =================================================================== diff -u -r50e6e3b5859850f154cbd59976f0f94565efcddc -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/alarms.py (.../alarms.py) (revision 50e6e3b5859850f154cbd59976f0f94565efcddc) +++ dialin/hd/alarms.py (.../alarms.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,17 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 alarms.py +# @file alarms.py # -# @date 2-Apr-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 20-Jul-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# ############################################################################ from ..protocols.CAN import (DenaliMessage, DenaliChannels) @@ -20,6 +20,8 @@ from .constants import RESET, NO_RESET from collections import OrderedDict import struct +from logging import Logger +from ..common.alarm_defs import AlarmList class HDAlarms(_AbstractSubSystem): @@ -127,12 +129,13 @@ ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH = 58 ALARM_ID_INLET_WATER_TEMPERATURE_OUT_OF_RANGE = 59 - def __init__(self, can_interface): + def __init__(self, can_interface, logger: Logger): """ @param can_interface: Denali Can Messenger object """ super().__init__() self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.hd_alarm_broadcast_ch_id @@ -160,10 +163,10 @@ self.alarm_states = [False] * 500 self.ids = OrderedDict() - for attr in dir(self): - if not callable(getattr(self, attr)) and attr.startswith("ALARM_ID"): - self.ids[attr] = getattr(self, attr) - self.ids = OrderedDict(sorted(self.ids.items(), key=lambda key: key[1])) + for attr in dir(AlarmList): + if not callable(getattr(AlarmList, attr)) and attr.startswith("ALARM_ID"): + self.ids[attr] = getattr(AlarmList, attr) + self.ids = OrderedDict(sorted(self.ids.items(), key=lambda key: key[1].value)) def get_alarm_states(self): """ @@ -173,19 +176,6 @@ """ return self.alarm_states - def get_alarms_state(self): - """ - Gets the alarms state - - None = 0 \n - Low = 1 \n - Medium = 2 \n - High = 3 \n - - @return: The alarms state - """ - return self.alarms_state - def get_alarms_top(self): """ Gets the top alarm @@ -214,6 +204,26 @@ """ Gets the alarms flags + Extract each flag from the flags int using bit-masking. E.g. + + System Fault = result & 1 + Stop = result & 2 + No Clear = result & 4 + No Resume = result & 8 + No Rinseback = result & 16 + No End Treatment = result & 32 + No New Treatment = result & 64 + Bypass Dialyzer = result & 128 + Alarms to Escalate = result & 256 + Alarms Silenced = result & 512 + TBD = result & 1024 + TBD = result & 2048 + TBD = result & 4096 + TBD = result & 8192 + TBD = result & 16384 + TBD = result & 32768 + TBD = result & 65536 + @return: (int) The alarms flags value """ return self.alarms_flags @@ -304,7 +314,7 @@ # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: @@ -335,24 +345,24 @@ message_id=self.MSG_ID_HD_ALARM_TIME_OVERRIDE, payload=payload) - print("override alarm time since activated") + self.logger.debug("override alarm time since activated") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(time_ms) - print("Alarm time since activated overridden to " + str_res + " ms: " + str( + self.logger.debug("Alarm time since activated overridden to " + str_res + " ms: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_alarm_lamp_pattern_override(self, pattern, reset=NO_RESET): @@ -383,14 +393,14 @@ message_id=self.MSG_ID_HD_ALARM_LAMP_OVERRIDE, payload=payload) - print("Override Alarm Lamp Pattern") + self.logger.debug("Override Alarm Lamp Pattern") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - print(received_message) + self.logger.debug(received_message) if reset == RESET: str_pat = "reset back to normal" elif pattern == self.HD_ALARM_LAMP_PATTERN_OFF: @@ -407,19 +417,20 @@ str_pat = "low" else: str_pat = "manual" - print("Alarm lamp pattern overridden to " + str_pat + ":" + + self.logger.debug("Alarm lamp pattern overridden to " + str_pat + ":" + 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!!!!") + self.logger.debug("Timeout!!!!") return False def get_current_alarms_state(self): """ Gets the current alarms state. + None, Low, Medium, or High - @return: the current alarms state in text form. + @return: (str) the current alarms state in text form. """ result = "" if self.alarms_state == self.HD_ALARM_STATE_NONE: Index: dialin/hd/blood_flow.py =================================================================== diff -u -rd134777c4f35ca58a14720a668c155bed3b0c124 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/blood_flow.py (.../blood_flow.py) (revision d134777c4f35ca58a14720a668c155bed3b0c124) +++ dialin/hd/blood_flow.py (.../blood_flow.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,18 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 bloodflow.py +# @file blood_flow.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 22-Jun-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# -# ############################################################################ from ..protocols.CAN import (DenaliMessage, DenaliChannels) @@ -21,6 +20,7 @@ from .constants import PUMP_CONTROL_MODE_CLOSED_LOOP, PUMP_CONTROL_MODE_OPEN_LOOP from ..utils.base import _AbstractSubSystem, _publish import struct +from logging import Logger class HDBloodFlow(_AbstractSubSystem): @@ -58,13 +58,13 @@ START_POS_PWM_DC = END_POS_MEAS_MC_CURR END_POS_PWM_DC = START_POS_PWM_DC + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HD_BloodFlow constructor """ super().__init__() - self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.hd_sync_broadcast_ch_id @@ -114,17 +114,17 @@ def get_measured_blood_pump_mc_speed(self): """ - Gets the measured blood pump mc speed + Gets the measured blood pump motor controller speed - @return: The measured blood pump mc speed + @return: The measured blood pump motor controller speed """ return self.measured_blood_pump_mc_speed def get_measured_blood_pump_mc_current(self): """ - Gets the measured blood pump mc current + Gets the measured blood pump motor controller current - @return: the measured blood pump mc current + @return: the measured blood pump motor controller current """ return self.measured_blood_pump_mc_current @@ -197,14 +197,14 @@ message_id=self.MSG_ID_HD_BLOOD_FLOW_SET_RATE_OVERRIDE, payload=payload) - print("override blood flow set point") + self.logger.debug("override blood flow set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: @@ -213,13 +213,13 @@ str_mode = " (open loop): " else: str_mode = " (closed loop): " - print( + self.logger.debug( "Blood flow set point overridden to " + str_res + " mL/min" + str_mode + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_blood_flow_measured_override(self, flow, reset=NO_RESET): @@ -241,24 +241,24 @@ message_id=self.MSG_ID_HD_BLOOD_FLOW_MEAS_RATE_OVERRIDE, payload=payload) - print("override measured blood flow") + self.logger.debug("override measured blood flow") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(flow) - print("Blood flow (measured)) overridden to " + str_res + " mL/min: " + + self.logger.debug("Blood flow (measured)) overridden to " + str_res + " 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_blood_pump_mc_measured_speed_override(self, speed, reset=NO_RESET): @@ -281,29 +281,29 @@ message_id=self.MSG_ID_HD_BLOOD_PUMP_MC_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured blood pump motor controller speed") + self.logger.debug("override measured blood pump motor controller speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Blood pump MC speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Blood pump MC speed (measured) overridden to " + str_res + " RPM: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False - def cmd_blood_pump_measured_current_override(self, curr, reset=NO_RESET): + def cmd_measured_blood_pump_mc_current_override(self, curr, reset=NO_RESET): """ - Constructs and sends the measured blood pump motor current override command + Constructs and sends the measured blood pump motor controller current override command Constraints: Must be logged into HD. @@ -320,24 +320,24 @@ message_id=self.MSG_ID_HD_BLOOD_PUMP_MC_MEAS_CURRENT_OVERRIDE, payload=payload) - print("override measured blood pump motor controller current") + self.logger.debug("override measured blood pump motor controller current") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(curr) - print("Blood pump MC current (measured) overridden to " + str_res + " mA: " + + self.logger.debug("Blood pump MC current (measured) overridden to " + str_res + " mA: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_blood_pump_measured_speed_override(self, speed, reset=NO_RESET): @@ -360,27 +360,27 @@ message_id=self.MSG_ID_HD_BLOOD_PUMP_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured blood pump speed") + self.logger.debug("override measured blood pump speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Blood pump speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Blood pump speed (measured) overridden to " + str_res + " RPM: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False - def cmd_blood_pump_rotor_measured_speed_override(self, speed, reset=NO_RESET): + def cmd_blood_pump_measured_rotor_speed_override(self, speed, reset=NO_RESET): """ Constructs and sends the measured blood pump rotor speed override \n command. @@ -400,24 +400,24 @@ message_id=self.MSG_ID_HD_BLOOD_PUMP_ROTOR_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured blood pump rotor speed") + self.logger.debug("override measured blood pump rotor speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Blood pump rotor speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Blood pump rotor speed (measured) overridden to " + str_res + " RPM: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_blood_flow_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -440,24 +440,24 @@ message_id=self.MSG_ID_HD_BLOOD_FLOW_PUBLISH_INTERVAL_OVERRIDE, payload=payload) - print("override blood flow broadcast interval") + self.logger.debug("override blood flow broadcast interval") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal: " else: str_res = str(ms) + " ms: " - print("Blood flow broadcast interval overridden to " + str_res + + self.logger.debug("Blood flow 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_set_blood_flow_calibration(self, gain, offset): Index: dialin/hd/constants.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/constants.py (.../constants.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/constants.py (.../constants.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -16,5 +16,9 @@ RESET = 1 NO_RESET = 0 + BUTTON_PRESSED = 1 BUTTON_RELEASED = 0 + +PUMP_CONTROL_MODE_CLOSED_LOOP = 0 +PUMP_CONTROL_MODE_OPEN_LOOP = 1 Index: dialin/hd/dialysate_inlet_flow.py =================================================================== diff -u -rd134777c4f35ca58a14720a668c155bed3b0c124 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/dialysate_inlet_flow.py (.../dialysate_inlet_flow.py) (revision d134777c4f35ca58a14720a668c155bed3b0c124) +++ dialin/hd/dialysate_inlet_flow.py (.../dialysate_inlet_flow.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,18 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 dialysate_inlet_flow.py +# @file dialysate_inlet_flow.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 22-Jun-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# -# ############################################################################ import struct from ..protocols.CAN import (DenaliMessage, @@ -21,6 +20,7 @@ from .constants import RESET, NO_RESET from .constants import PUMP_CONTROL_MODE_CLOSED_LOOP, PUMP_CONTROL_MODE_OPEN_LOOP from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDDialysateInletFlow(_AbstractSubSystem): """ @@ -57,13 +57,14 @@ START_POS_PWM_DC = END_POS_MEAS_MC_CURR END_POS_PWM_DC = START_POS_PWM_DC + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HD_DialysateFlow constructor """ super().__init__() self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.hd_sync_broadcast_ch_id @@ -197,14 +198,14 @@ message_id=self.MSG_ID_HD_DIAL_IN_FLOW_SET_RATE_OVERRIDE, payload=payload) - print("override dialysate flow set point") + self.logger.debug("override dialysate flow set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: @@ -213,13 +214,13 @@ str_mode = " (open loop): " else: str_mode = " (closed loop): " - print( + self.logger.debug( "Dialysate flow set point overridden to " + str_res + " mL/min" + str_mode + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_flow_measured_override(self, flow, reset=NO_RESET): @@ -241,24 +242,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_FLOW_MEAS_RATE_OVERRIDE, payload=payload) - print("override measured dialysate flow") + self.logger.debug("override measured dialysate flow") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(flow) - print("Dialysate flow (measured)) overridden to " + str_res + " mL/min: " + + self.logger.debug("Dialysate flow (measured)) overridden to " + str_res + " 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_pump_mc_measured_speed_override(self, speed, reset=NO_RESET): @@ -281,24 +282,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_PUMP_MC_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump motor controller speed") + self.logger.debug("override measured dialysate inlet pump motor controller speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Dialysate pump MC speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Dialysate pump MC speed (measured) overridden to " + str_res + " RPM: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_pump_measured_current_override(self, curr, reset=NO_RESET): @@ -320,24 +321,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_PUMP_MC_MEAS_CURRENT_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump motor controller current") + self.logger.debug("override measured dialysate inlet pump motor controller current") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(curr) - print("Dialysate inlet pump MC current (measured) overridden to " + str_res + " mA: " + + self.logger.debug("Dialysate inlet pump MC current (measured) overridden to " + str_res + " mA: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_pump_measured_speed_override(self, speed, reset=NO_RESET): @@ -360,24 +361,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_PUMP_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump speed") + self.logger.debug("override measured dialysate inlet pump speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Dialysate inlet pump speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Dialysate inlet pump speed (measured) overridden to " + str_res + " RPM: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_pump_rotor_measured_speed_override(self, speed, reset=NO_RESET): @@ -400,24 +401,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_PUMP_ROTOR_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump rotor speed") + self.logger.debug("override measured dialysate inlet pump rotor speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Dialysate inlet pump rotor speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Dialysate inlet pump rotor speed (measured) overridden to " + str_res + " RPM: " + 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!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_flow_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -440,7 +441,7 @@ message_id=self.MSG_ID_HD_DIAL_IN_FLOW_PUBLISH_INTERVAL_OVERRIDE, payload=payload) - print("override dialysate inlet flow broadcast interval") + self.logger.debug("override dialysate inlet flow broadcast interval") # Send message received_message = self.can_interface.send(message) @@ -451,12 +452,12 @@ str_res = "reset back to normal: " else: str_res = str(ms) + " ms: " - print("Dialysate inlet flow broadcast interval overridden to " + str_res + + self.logger.debug("Dialysate inlet flow 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_set_dialysate_flow_calibration(self, gain, offset): Index: dialin/hd/dialysate_outlet_flow.py =================================================================== diff -u -rd134777c4f35ca58a14720a668c155bed3b0c124 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/dialysate_outlet_flow.py (.../dialysate_outlet_flow.py) (revision d134777c4f35ca58a14720a668c155bed3b0c124) +++ dialin/hd/dialysate_outlet_flow.py (.../dialysate_outlet_flow.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,18 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 dialysate_outlet_flow.py +# @file dialysate_outlet_flow.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 22-Jun-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# -# ############################################################################ import struct from ..protocols.CAN import (DenaliMessage, @@ -21,6 +20,7 @@ from .constants import RESET, NO_RESET from .constants import PUMP_CONTROL_MODE_CLOSED_LOOP, PUMP_CONTROL_MODE_OPEN_LOOP from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDDialysateOutletFlow(_AbstractSubSystem): @@ -57,12 +57,13 @@ START_POS_PWM_DC = END_POS_MEAS_MC_CURR END_POS_PWM_DC = START_POS_PWM_DC + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HDDialysateFlow constructor """ super().__init__() self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.hd_sync_broadcast_ch_id @@ -239,25 +240,25 @@ message_id=self.MSG_ID_HD_DIAL_OUT_UF_REF_VOLUME_OVERRIDE, payload=payload) - print("override UF reference volume with " + str(refvol) + "mL.") + self.logger.debug("override UF reference volume with " + str(refvol) + "mL.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(refvol) + " mL. " - print( + self.logger.debug( "UF reference volume " + 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_measured_uf_volume_override(self, measvol, reset=NO_RESET): @@ -279,24 +280,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_UF_MEAS_VOLUME_OVERRIDE, payload=payload) - print("override measured UF volume with " + str(measvol) + " mL.") + self.logger.debug("override measured UF volume with " + str(measvol) + " mL.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(measvol) + " mL. " - print("UF measured volume " + str_res + + self.logger.debug("UF measured volume " + 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_mc_measured_speed_override(self, speed, reset=NO_RESET): @@ -319,24 +320,24 @@ message_id=self.measured_dialysate_outlet_pump_mc_speed, payload=payload) - print("override measured dialysate outlet pump motor controller speed to " + str(spd) + " RPM.") + self.logger.debug("override measured dialysate outlet pump motor controller speed to " + str(spd) + " RPM.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate outlet pump MC speed (measured) " + str_res + + self.logger.debug("Dialysate outlet pump MC speed (measured) " + 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_measured_current_override(self, curr, reset=NO_RESET): @@ -358,24 +359,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_MC_MEAS_CURRENT_OVERRIDE, payload=payload) - print("override measured dialysate outlet pump motor controller current") + self.logger.debug("override measured dialysate outlet pump motor controller current") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(curr) + " mA. " - print("Dialysate outlet pump MC current (measured) " + str_res + + self.logger.debug("Dialysate outlet pump MC current (measured) " + 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_measured_speed_override(self, speed, reset=NO_RESET): @@ -398,24 +399,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate outlet pump speed to " + str(speed) + " RPM.") + self.logger.debug("override measured dialysate outlet pump speed to " + str(speed) + " RPM.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate outlet pump speed (measured) " + str_res + + self.logger.debug("Dialysate outlet pump speed (measured) " + 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_rotor_measured_speed_override(self, speed, reset=NO_RESET): @@ -438,24 +439,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_ROTOR_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate outlet pump rotor speed to " + str(speed) + " RPM.") + self.logger.debug("override measured dialysate outlet pump rotor speed to " + str(speed) + " RPM.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate outlet pump rotor speed (measured) " + str_res + + self.logger.debug("Dialysate outlet pump rotor speed (measured) " + 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_flow_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -478,24 +479,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_FLOW_PUBLISH_INTERVAL_OVERRIDE, payload=payload) - print("override dialysate outlet flow broadcast interval to " + str(ms) + " ms.") + self.logger.debug("override dialysate outlet flow broadcast interval to " + str(ms) + " ms.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(ms) + " ms. " - print("Dialysate outlet flow broadcast interval " + str_res + + self.logger.debug("Dialysate outlet flow broadcast interval " + 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_load_cell_weight_override(self, weight, sensor, reset=NO_RESET): @@ -526,24 +527,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_LOAD_CELL_WEIGHT_OVERRIDE, payload=payload) - print("override measured load cell weight to " + str(weight) + " grams for load cell # " + str(sensor)) + self.logger.debug("override measured load cell weight to " + str(weight) + " grams for load cell # " + str(sensor)) # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(weight) + " grams. " - print("Load cell # " + str(sensor) + " " + str_res + + self.logger.debug("Load cell # " + str(sensor) + " " + 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_set_load_cell_weights(self, r1p, r1b, r2p, r2b): @@ -567,7 +568,7 @@ message_id=self.MSG_ID_HD_LOAD_CELL_READINGS, payload=payload) - print("measured load cell weights set.") + self.logger.debug("measured load cell weights set.") # Send message self.can_interface.send(message, 0) Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -r6f6b6c076ce638b404534b2bf04cb3f986ee6b26 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 6f6b6c076ce638b404534b2bf04cb3f986ee6b26) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,18 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 hemodialysis_device.py +# @file hemodialysis_device.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 20-Jul-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief This class provides the basic interface to communicate with -# the HD board. -# ############################################################################ import struct from .accelerometer import HDAccelerometer @@ -29,10 +28,11 @@ from ..protocols.CAN import (DenaliMessage, DenaliCanMessenger, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish -from .constants import NO_RESET from ..utils.conversions import integer_to_bytearray +from ..utils.base import _AbstractSubSystem, _publish, _LogManager +from .constants import NO_RESET + class HD(_AbstractSubSystem): """ Hemodialysis Device (HD) Dialin object API. It provides the basic interface to communicate with @@ -43,6 +43,7 @@ MSG_ID_HD_OPERATION_MODE_BROADCAST = 0x0025 MSG_ID_LOGIN_TO_HD = 0x8000 MSG_ID_HD_SAFETY_SHUTDOWN_OVERRIDE = 0x8026 + MSG_ID_POWEROFF_NOTIFY = 0x0020 # broadcast message field positions START_POS_HD_OP_MODE = DenaliMessage.PAYLOAD_START_INDEX @@ -66,19 +67,27 @@ def __init__(self, can_interface="can0", log_level=None): """ - HD constructor using can bus + HD object provides test/service commands for the HD sub-system. + >> hd_object = HD('can0') + >> hd_object = HD(can_interface='can0', log_level="DEBUG") + + Possible log levels: + ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "CAN_ONLY", "PRINT_ONLY"] + @param can_interface: (str) CANBus interface name, e.g. "can0" - @return: HD object provides test/service commands for the HD sub-system. + @param log_level: (str) Logging level, defaults to None - >> hd_object = HD(can_interface='can0') - >> hd_object = HD('can0') """ super().__init__() + self._log_manager = _LogManager(log_level=log_level, log_filepath=self.__class__.__name__+".log") + self.logger = self._log_manager.logger # Create listener - self.can_interface = DenaliCanMessenger(can_interface=can_interface, log_level=log_level) + self.can_interface = DenaliCanMessenger(can_interface=can_interface, + logger=self.logger, + log_can=self._log_manager.log_level == "CAN_ONLY") self.can_interface.start() # register handler for HD operation mode broadcast messages @@ -93,17 +102,17 @@ self.hd_operation_sub_mode = 0 # Create command groups - self.accel = HDAccelerometer(self.can_interface) - self.alarms = HDAlarms(self.can_interface) - self.buttons = HDButtons(self.can_interface) - self.ui = HDUIProxy(self.can_interface) - self.rtc = HDRTC(self.can_interface) - self.watchdog = HDWatchdog(self.can_interface) - self.bloodflow = HDBloodFlow(self.can_interface) - self.dialysate_inlet_flow = HDDialysateInletFlow(self.can_interface) - self.dialysate_outlet_flow = HDDialysateOutletFlow(self.can_interface) - self.treatment = HDTreatment(self.can_interface) - self.pressure_occlusion = HDPressureOcclusion(self.can_interface) + self.accel = HDAccelerometer(self.can_interface, self.logger) + self.alarms = HDAlarms(self.can_interface, self.logger) + self.buttons = HDButtons(self.can_interface, self.logger) + self.ui = HDUIProxy(self.can_interface, self.logger) + self.rtc = HDRTC(self.can_interface, self.logger) + self.watchdog = HDWatchdog(self.can_interface, self.logger) + self.bloodflow = HDBloodFlow(self.can_interface, self.logger) + self.dialysate_inlet_flow = HDDialysateInletFlow(self.can_interface, self.logger) + self.dialysate_outlet_flow = HDDialysateOutletFlow(self.can_interface, self.logger) + self.treatment = HDTreatment(self.can_interface, self.logger) + self.pressure_occlusion = HDPressureOcclusion(self.can_interface, self.logger) def get_operation_mode(self): """ @@ -142,19 +151,19 @@ message_id=self.MSG_ID_LOGIN_TO_HD, payload=list(map(int, map(ord, self.HD_LOGIN_PASSWORD)))) - print("Logging in...") + self.logger.debug("Logging in...") # Send message received_message = self.can_interface.send(message) if received_message is not None: if received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] == 1: - print("Success: Logged In") + self.logger.debug("Success: Logged In") else: - print("Failure: Log In Failed.") + self.logger.debug("Failure: Log In Failed.") return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Login Timeout!!!!") + self.logger.debug("Login Timeout!!!!") return False def cmd_hd_safety_shutdown_override(self, active=True, reset=NO_RESET): @@ -183,17 +192,17 @@ message_id=self.MSG_ID_HD_SAFETY_SHUTDOWN_OVERRIDE, payload=payload) - print("overriding HD safety shutdown") + self.logger.debug("overriding HD safety shutdown") # Send message received_message = self.can_interface.send(message) if received_message is not None: if received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] == 1: - print("Safety shutdown signal overridden") + self.logger.debug("Safety shutdown signal overridden") else: - print("Safety shutdown signal override failed.") + self.logger.debug("Safety shutdown signal override failed.") return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/hd/treatment.py =================================================================== diff -u -r8d1f61499650e23dac6f857e48daad42180db949 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/treatment.py (.../treatment.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) +++ dialin/hd/treatment.py (.../treatment.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -17,6 +17,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from ..utils.conversions import integer_to_bytearray, float_to_bytearray from logging import Logger @@ -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,663 @@ 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 -r615811771f562ec677f10f1c91bb15733fc7b209 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 615811771f562ec677f10f1c91bb15733fc7b209) +++ dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,24 +1,25 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 ui.py +# @file ui_proxy.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 20-Jul-2020 +# @author (original) Sean +# @date (original) 15-Apr-2020 # -# @brief -# -# ############################################################################ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.conversions import integer_to_bytearray, float_to_bytearray import struct from ..utils.base import _AbstractSubSystem, _publish +from collections import OrderedDict +from logging import Logger class HDUIProxy(_AbstractSubSystem): @@ -64,6 +65,24 @@ START_TREATMENT_CMD_CANCEL_TREATMENT_WORKFLOW = 1 START_TREATMENT_CMD_START_TREATMENT = 2 + REQUEST_REJECT_REASON_NONE = 0 + REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE = 1 + REQUEST_REJECT_REASON_TIMEOUT_WAITING_FOR_USER_CONFIRM = 2 + REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE = 3 + REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE = 4 + REQUEST_REJECT_REASON_TREATMENT_TOO_CLOSE_TO_FINISHED = 5 + REQUEST_REJECT_REASON_TREATMENT_TIME_OUT_OF_RANGE = 6 + REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT = 7 + REQUEST_REJECT_REASON_BLOOD_FLOW_OUT_OF_RANGE = 8 + REQUEST_REJECT_REASON_DIAL_FLOW_OUT_OF_RANGE = 9 + REQUEST_REJECT_REASON_DIAL_VOLUME_OUT_OF_RANGE = 10 + REQUEST_REJECT_REASON_UF_VOLUME_OUT_OF_RANGE = 11 + REQUEST_REJECT_REASON_UF_RATE_OUT_OF_RANGE = 12 + REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_MINIMUM = 13 + REQUEST_REJECT_REASON_UF_NOT_IN_PROGESS = 14 + REQUEST_REJECT_REASON_UF_NOT_PAUSED = 15 + REQUEST_REJECT_REASON_SALINE_BOLUS_IN_PROGRESS = 16 + # HD version message field positions START_POS_MAJOR = DenaliMessage.PAYLOAD_START_INDEX END_POS_MAJOR = START_POS_MAJOR + 1 @@ -74,6 +93,16 @@ START_POS_BUILD = END_POS_MICRO END_POS_BUILD = START_POS_BUILD + 2 + # FPGA + START_POS_FPGA_ID = END_POS_BUILD + END_POS_FPGA_ID = START_POS_FPGA_ID + 1 + START_POS_FPGA_MAJOR = END_POS_FPGA_ID + END_POS_FPGA_MAJOR = START_POS_FPGA_MAJOR + 1 + START_POS_FPGA_MINOR = END_POS_FPGA_MAJOR + END_POS_FPGA_MINOR = START_POS_FPGA_MINOR + 1 + START_POS_FPGA_LAB = END_POS_FPGA_MINOR + END_POS_FPGA_LAB = START_POS_FPGA_LAB + 1 + # HD update on valid treatment parameter ranges message field positions START_POS_MIN_TREAT_TIME = DenaliMessage.PAYLOAD_START_INDEX END_POS_MIN_TREAT_TIME = START_POS_MIN_TREAT_TIME + 4 @@ -138,15 +167,15 @@ 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 - def __init__(self, can_interface): + def __init__(self, can_interface, logger: Logger): """ @param can_interface: the denali can interface object """ super().__init__() - self.can_interface = can_interface + self.logger = logger # register function to handle HD response to UF change requests if self.can_interface is not None: @@ -156,7 +185,7 @@ self._handler_uf_change_response) self.can_interface.register_receiving_publication_function(channel_id, self.MSG_ID_UF_SETTINGS_CHANGE_CONFIRM_RESPONSE_FROM_HD, - self.handler_uf_change_confirm_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, self._handler_treatment_duration_change_response) @@ -172,6 +201,7 @@ # initialize variables that will be populated by HD version response self.hd_version = None + self.fpga_version = None # initialize treatment parameters that Dialin user sets self.blood_flow_rate = 0 self.dialysate_flow_rate = 0 @@ -236,6 +266,12 @@ self.target_blood_flow_rate = 0 self.target_dialysate_flow_rate = 0 + self.reject_reasons = OrderedDict() + for attr in dir(self): + if not callable(getattr(self, attr)) and attr.startswith("REQUEST_REJECT"): + self.reject_reasons[attr] = getattr(self, attr) + self.reject_reasons = OrderedDict(sorted(self.reject_reasons.items(), key=lambda key: key[1])) + def get_hd_version(self): """ Gets the hd version @@ -244,6 +280,14 @@ """ return self.hd_version + def get_fpga_version(self): + """ + Gets the fpga version + + @return: the fpga version + """ + return self.fpga_version + def get_min_treatment_duration_min(self): """ Gets the min treatment duration @@ -308,6 +352,14 @@ """ return self.duration_change_reject_reason + def get_reject_reasons(self): + """ + Gets all possible reject reasons + + @return: OrderedDict(), {"": ... } + """ + return self.reject_reasons + def get_duration_change_time_min(self): """ Gets the duration change time @@ -328,7 +380,7 @@ """ Gets the uf change succeeded status - @return: The uf change succeeded status + @return: True if succeeded, False otherwise """ return self.uf_change_succeeded @@ -574,6 +626,7 @@ @_publish([ "hd_version" + "fpga_version" ]) def _handler_hd_version(self, message): """ @@ -596,11 +649,23 @@ build = struct.unpack('H', bytearray( message['message'][self.START_POS_BUILD:self.END_POS_BUILD])) - if len(major) > 0 and len(minor) > 0 and len(micro) > 0 and len(build) > 0: + fpga_id = struct.unpack('B', bytearray( + message['message'][self.START_POS_FPGA_ID:self.END_POS_FPGA_ID])) + fpga_major = struct.unpack('B', bytearray( + message['message'][self.START_POS_FPGA_MAJOR:self.END_POS_FPGA_MAJOR])) + fpga_minor = struct.unpack('B', bytearray( + message['message'][self.START_POS_FPGA_MINOR:self.END_POS_FPGA_MINOR])) + fpga_lab = struct.unpack('B', bytearray( + message['message'][self.START_POS_FPGA_LAB:self.END_POS_FPGA_LAB])) + + if all([len(each) > 0 for each in [major, minor, micro, build]]): self.hd_version = f"v{major[0]}.{minor[0]}.{micro[0]}-{build[0]}" - print(self.hd_version) - return self.hd_version + self.logger.debug(f"HD VERSION: {self.hd_version}") + if all([len(each) > 0 for each in [fpga_major, fpga_minor, fpga_id, fpga_lab]]): + self.fpga_version = f"ID: {fpga_id[0]} v{fpga_major[0]}.{fpga_minor[0]}.{fpga_lab[0]}" + self.logger.debug(f"HD FPGA VERSION: {self.fpga_version}") + @_publish([ "treatment_parameters_valid", "blood_flow_rate_reject_reason", @@ -873,18 +938,23 @@ self.uf_old_rate_ml_min = ort[0] - def handler_uf_change_confirm_response(self, message): + @_publish(["uf_change_succeeded", + "uf_change_reject_reason", + "uf_change_volume_ml", + "uf_change_time_min", + "uf_change_rate_ml_min"]) + def _handler_uf_change_confirm_response(self, message): """ Handler for response from HD regarding UF change confirmation. - \param message: response message from HD regarding confirmed ultrafiltration settings change.\n + @param message: response message from HD regarding confirmed ultrafiltration settings change.\n BOOL Accepted \n U32 RejectReason (if not accepted) F32 UF Volume (mL) - converted to Liters \n U32 treatment Time (min) \n F32 UF Rate (mL/min) \n - \returns none + @return: None """ rsp = struct.unpack('i', bytearray( message['message'][self.START_POS_UF_CNF_RSP_RESP:self.END_POS_UF_CNF_RSP_RESP])) @@ -917,7 +987,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, message_id=self.MSG_ID_UI_CHECKIN_WITH_HD) - print("Sending ui checkin w/ HD") + self.logger.debug("Sending ui checkin w/ HD") self.can_interface.send(message, 0) @@ -932,7 +1002,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, message_id=self.MSG_ID_UI_REQUEST_HD_VERSION) - print("Sending ui request for version to HD") + self.logger.debug("Sending ui request for version to HD") self.can_interface.send(message, 0) @@ -954,7 +1024,7 @@ str_cmd = "pause" else: str_cmd = "resume" - print("Sending UF " + str_cmd + " command.") + self.logger.debug("Sending UF " + str_cmd + " command.") self.can_interface.send(message, 0) @@ -977,7 +1047,7 @@ message_id=self.MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER, payload=volume) - print("Sending UF settings change request.") + self.logger.debug("Sending UF settings change request.") self.can_interface.send(message, 0) @@ -1004,7 +1074,7 @@ message_id=self.MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER, payload=payload) - print("Sending UF settings change request.") + self.logger.debug("Sending UF settings change request.") self.can_interface.send(message, 0) @@ -1015,11 +1085,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 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 + @return: None """ resp = integer_to_bytearray(response) @@ -1031,7 +1100,7 @@ message_id=self.MSG_ID_UF_SETTINGS_CHANGE_CONFIRMED_BY_USER, payload=payload) - print("Sending UF settings change confirmation.") + self.logger.debug("Sending UF settings change confirmation.") self.can_interface.send(message, 0) @@ -1051,7 +1120,7 @@ message_id=self.MSG_ID_TREATMENT_DURATION_SETTING_CHANGE_REQUEST, payload=payload) - print("Sending treatment duration setting change request.") + self.logger.debug("Sending treatment duration setting change request.") # Send message self.can_interface.send(message, 0) @@ -1075,7 +1144,7 @@ message_id=self.MSG_ID_BLOOD_DIALYSATE_FLOW_SETTING_CHANGE_REQUEST_BY_USER, payload=payload) - print("Sending blood & dialysate flow rate settings change request.") + self.logger.debug("Sending blood & dialysate flow rate settings change request.") self.can_interface.send(message, 0) @@ -1101,7 +1170,7 @@ message_id=self.MSG_ID_UI_START_TREATMENT, payload=payload) - print("Sending start treatment command request.") + self.logger.debug("Sending start treatment command request.") self.can_interface.send(message, 0) @@ -1176,7 +1245,7 @@ message_id=self.MSG_ID_UI_NEW_TREATMENT_PARAMS, payload=payload) - print("Sending treatment parameters to HD.") + self.logger.debug("Sending treatment parameters to HD.") self.can_interface.send(message, 0) @@ -1192,7 +1261,7 @@ 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.logger.debug("Sending confirm treatment parameters messge.") self.can_interface.send(message, 0) Index: dialin/squish/crc.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/squish/crc.py (.../crc.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/squish/crc.py (.../crc.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- ########################################################################### # # Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. @@ -14,16 +13,6 @@ # @date (original) 09-Jul-2020 # ############################################################################ -## -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. -# copyright -# 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 crc.py -# date 2020/04/08 -# author Behrouz NematiPour crc8_table = ( 0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46, Index: dialin/squish/denaliMessages.py =================================================================== diff -u -rc3cc81dada72714b9675594cc0c6a79975e8991d -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/squish/denaliMessages.py (.../denaliMessages.py) (revision c3cc81dada72714b9675594cc0c6a79975e8991d) +++ dialin/squish/denaliMessages.py (.../denaliMessages.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- ########################################################################### # # Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. @@ -14,17 +13,6 @@ # @date (original) 09-Jul-2020 # ############################################################################ -## -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. -# copyright -# 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 denaliMessages.py -# date 2020/04/08 -# author Behrouz NematiPour -# import time import subprocess Index: dialin/squish/globals.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/squish/globals.py (.../globals.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/squish/globals.py (.../globals.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- ########################################################################### # # Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. @@ -14,17 +13,6 @@ # @date (original) 09-Jul-2020 # ############################################################################ -## -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. -# copyright -# 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 globals.py -# date 2020/02/21 -# author Behrouz NematiPour -# def SRSUI(vSRSUI = ""): return "SRSUI " + "{}".format(vSRSUI).rjust(3, '0') Index: dialin/squish/messageBuilder.py =================================================================== diff -u -rc3cc81dada72714b9675594cc0c6a79975e8991d -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/squish/messageBuilder.py (.../messageBuilder.py) (revision c3cc81dada72714b9675594cc0c6a79975e8991d) +++ dialin/squish/messageBuilder.py (.../messageBuilder.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- ########################################################################### # # Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. @@ -14,17 +13,6 @@ # @date (original) 09-Jul-2020 # ############################################################################ -## -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. -# copyright -# 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 messageBuilder.py -# date 2020/04/08 -# author Behrouz NematiPour -# from dialin.squish import utils from dialin.squish import crc @@ -99,5 +87,3 @@ msg += arg msg += crc.calcCRC8(msg) return syncByte + msg - - Index: dialin/squish/unittests.py =================================================================== diff -u -rc3cc81dada72714b9675594cc0c6a79975e8991d -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/squish/unittests.py (.../unittests.py) (revision c3cc81dada72714b9675594cc0c6a79975e8991d) +++ dialin/squish/unittests.py (.../unittests.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- ########################################################################### # # Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. @@ -14,17 +13,6 @@ # @date (original) 09-Jul-2020 # ############################################################################ -## -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. -# copyright -# 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 unittests.py -# date 2019/11/20 -# author Behrouz NematiPour -# import test import sys Index: dialin/squish/utils.py =================================================================== diff -u -rb919e9cba87e4b3b8747227113fc5ae3df6fa6a6 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- dialin/squish/utils.py (.../utils.py) (revision b919e9cba87e4b3b8747227113fc5ae3df6fa6a6) +++ dialin/squish/utils.py (.../utils.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- ########################################################################### # # Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. @@ -14,17 +13,6 @@ # @date (original) 09-Jul-2020 # ############################################################################ -## -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. -# copyright -# 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 utils.py -# date 2019/11/21 -# author Behrouz NematiPour -# import time import struct Index: tests/test_hd.py =================================================================== diff -u -r8ea13ae6dd10732bfcc456798f4785c4d88c95d3 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- tests/test_hd.py (.../test_hd.py) (revision 8ea13ae6dd10732bfcc456798f4785c4d88c95d3) +++ tests/test_hd.py (.../test_hd.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -5,12 +5,12 @@ # 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_hd.py +# @file hd_test_script.py # # @author (last) Peter Lucia -# @date (last) 21-Aug-2020 +# @date (last) 07-Apr-2020 # @author (original) Peter Lucia -# @date (original) 14-Jul-2020 +# @date (original) 02-Apr-2020 # ############################################################################ import sys @@ -76,10 +76,9 @@ # hd.bloodflow.cmd_blood_flow_broadcast_interval_override(RESET,0) - # FIXME: Update passing criteria + # TODO: Update passing criteria self.assertTrue(True) if __name__ == '__main__': unittest.main(verbosity=2) - Index: tests/test_uf.py =================================================================== diff -u -r8ea13ae6dd10732bfcc456798f4785c4d88c95d3 -r10bd08a612562df62c94e3d304f17ba24f4275a6 --- tests/test_uf.py (.../test_uf.py) (revision 8ea13ae6dd10732bfcc456798f4785c4d88c95d3) +++ tests/test_uf.py (.../test_uf.py) (revision 10bd08a612562df62c94e3d304f17ba24f4275a6) @@ -5,12 +5,12 @@ # 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_uf.py +# @file uf_test.py # # @author (last) Peter Lucia -# @date (last) 06-Aug-2020 -# @author (original) Peter Lucia -# @date (original) 14-Jul-2020 +# @date (last) 02-Jun-2020 +# @author (original) Sean Nash +# @date (original) 20-May-2020 # ############################################################################ @@ -75,8 +75,17 @@ ", DRo, " + '{:9.2f}'.format(dg.pressures.drain_pump_outlet_pressure) alarms = ", AL.s, " + hd.alarms.get_current_alarms_state() + \ ", AL.t, " + '{:4d}'.format(hd.alarms.alarm_top) + accels = ", AC.x, " + '{:9.4f}'.format(hd.accel.get_accel_vector().x) + \ + ", AC.y, " + '{:9.4f}'.format(hd.accel.get_accel_vector().y) + \ + ", AC.z, " + '{:9.4f}'.format(hd.accel.get_accel_vector().z) + \ + ", ACm.x, " + '{:9.4f}'.format(hd.accel.get_accel_max_vector().x) + \ + ", ACm.y, " + '{:9.4f}'.format(hd.accel.get_accel_max_vector().y) + \ + ", ACm.z, " + '{:9.4f}'.format(hd.accel.get_accel_max_vector().z) + \ + ", ACt.x, " + '{:9.4f}'.format(hd.accel.get_accel_tilts().x) + \ + ", ACt.y, " + '{:9.4f}'.format(hd.accel.get_accel_tilts().y) + \ + ", ACt.z, " + '{:9.4f}'.format(hd.accel.get_accel_tilts().z) - # log data + # log data f.write(modes) f.write(loadCells) f.write(ultraFilt) @@ -86,6 +95,7 @@ f.write(pumpPWMs) f.write(dgPres) f.write(alarms) + f.write(accels) f.write("\n") # print to console @@ -97,6 +107,6 @@ print(" Pump Speeds: "+pumpMeasSpds) print(" Pump PWMs/DACs: "+pumpPWMs) print(" DG Pressures: "+dgPres) + print(" Accelerometer: "+accels) print(" Alarms: "+alarms) -