Index: dialin/common/msg_defs.py =================================================================== diff -u -r287af45040e35882e001fb3ea835f304007870c4 -rfbe3580dfcda2338d9fa33d09bee85099ea7b801 --- dialin/common/msg_defs.py (.../msg_defs.py) (revision 287af45040e35882e001fb3ea835f304007870c4) +++ dialin/common/msg_defs.py (.../msg_defs.py) (revision fbe3580dfcda2338d9fa33d09bee85099ea7b801) @@ -194,12 +194,17 @@ MSG_ID_HEAT_DISINFECT_PUBLISH_INTERVAL_OVERRIDE = 0xA021 # Heat disinfection data publish interval override request MSG_ID_DG_SOFTWARE_RESET_REQUEST = 0xA022 # DG reset request MSG_ID_DG_OPERATION_MODE_REQUEST = 0xA023 # DG operation mode request - MSG_ID_CONCENTRATE_PUMP_TARGET_SPEED_OVERRIDE = 0xA024 # Concentrate pumps' target speed override request + MSG_ID_CONCENTRATE_PUMP_TARGET_SPEED_OVERRIDE = 0xA024 MSG_ID_UV_REACTORS_DATA_PUBLISH_INTERVAL_OVERRIDE = 0xA025 # UV reactors data publish interval override MSG_ID_CONCENTRATE_PUMP_STATE_CHANGE_REQUEST = 0xA026 # Concentrate pumps' state change request (on / off) MSG_ID_CONCENTRATE_PUMP_PUBLISH_INTERVAL_OVERRIDE = 0xA027 # Concentrate pumps' data publish interval override request - MSG_ID_DG_START_STOP_UV_REACTORS_OVERRIDE = 0xA028 # DG start/stop UV reactors override request + MSG_ID_DG_START_STOP_INLET_UV_REACTOR = 0xA028 # DG start/stop inlet UV reactor MSG_ID_DG_REQUEST_CALIBRATION_DATA = 0xA029 # Requests calibration data from DG + MSG_ID_DG_FANS_DATA_PUBLISH_OVERRIDE = 0xA02A # Fans data publish interval override request + MSG_ID_DG_START_STOP_OUTLET_UV_REACTOR = 0xA02B # DG start/stop outlet UV reactor + MSG_ID_DG_UV_REACTORS_HEALTH_OVERRIDE = 0xA02C # DG UV reactors health override request + MSG_ID_DG_THERMISTORS_DATA_PUBLISH_INTERVAL_OVERRIDE = 0xA02D # DG thermistors data publish interval override + MSG_ID_DG_THERMISTORS_VALUE_OVERRIDE = 0xA02E # DG thermistors value override MSG_ID_HD_DEBUG_EVENT = 0xFFF1 # HD debug event text to be logged in event log MSG_ID_DG_DEBUG_EVENT = 0xFFF2 # DG debug event text to be logged in event log Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -r287af45040e35882e001fb3ea835f304007870c4 -rfbe3580dfcda2338d9fa33d09bee85099ea7b801 --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 287af45040e35882e001fb3ea835f304007870c4) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision fbe3580dfcda2338d9fa33d09bee85099ea7b801) @@ -26,6 +26,10 @@ from .heaters import Heaters from .temperature_sensors import TemperatureSensors from .conductivity_sensors import ConductivitySensors +from .heat_disinfection import HeatDisinfection +from .thermistors import Thermistors +from .fans import Fans +from .uv_reactors import UVReactors from .concentrate_pumps import ConcentratePumps from ..utils.conversions import integer_to_bytearray from ..protocols.CAN import (DenaliCanMessenger, DenaliMessage, DenaliChannels) @@ -140,6 +144,10 @@ self.conductivity_sensors = ConductivitySensors(self.can_interface, self.logger) self.concentrate_pumps = ConcentratePumps(self.can_interface, self.logger) self.alarms = DGAlarms(self.can_interface, self.logger) + self.heat_disinfect = HeatDisinfection(self.can_interface, self.logger) + self.thermistors = Thermistors(self.can_interface, self.logger) + self.fans = Fans(self.can_interface, self.logger) + self.uv_reactors = UVReactors(self.can_interface, self.logger) def get_version(self): """ Index: dialin/dg/drain_pump.py =================================================================== diff -u -r287af45040e35882e001fb3ea835f304007870c4 -rfbe3580dfcda2338d9fa33d09bee85099ea7b801 --- dialin/dg/drain_pump.py (.../drain_pump.py) (revision 287af45040e35882e001fb3ea835f304007870c4) +++ dialin/dg/drain_pump.py (.../drain_pump.py) (revision fbe3580dfcda2338d9fa33d09bee85099ea7b801) @@ -17,17 +17,41 @@ from ..utils.conversions import integer_to_bytearray from ..common.msg_defs import MsgIds, MsgFldPositions from .constants import RESET, NO_RESET -from ..protocols.CAN import (DenaliMessage, - DenaliChannels) +from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish from logging import Logger +import enum +class DrainPumpStates(enum.Enum): + DRAIN_PUMP_OFF_STATE = 0 + DRAIN_PUMP_CONTROL_TO_TARGET_STATE = 1 + DRAIN_PUMP_OPEN_LOOP_STATE = 2 + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + class DGDrainPump(_AbstractSubSystem): """ Dialysate Generator (DG) Dialin API sub-class for drain pump related commands. """ + # Drain pump message IDs + MSG_ID_DG_DRAIN_PUMP_PUBLISHED_DATA = 0x0024 + MSG_ID_DG_DRAIN_PUMP_SET_SPEED_OVERRIDE = 0xA00B + MSG_ID_DG_DRAIN_PUMP_BROADAST_INTERVAL_OVERRIDE = 0xA00C + + # Drain pump broadcast message field positions + START_POS_SET_SPD = DenaliMessage.PAYLOAD_START_INDEX + END_POS_SET_SPD = START_POS_SET_SPD + 4 + START_POS_DAC = END_POS_SET_SPD + END_POS_DAC = START_POS_DAC + 4 + START_POS_PRESS_DIFF = END_POS_DAC + END_POS_PRESS_DIFF = START_POS_PRESS_DIFF + 4 + START_POS_PUMP_STATE = END_POS_PRESS_DIFF + END_POS_PUMP_STATE = START_POS_PUMP_STATE + 4 + def __init__(self, can_interface, logger: Logger): """ DGDrainPump constructor @@ -43,16 +67,18 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_drain_pump_sync) - self.target_drain_pump_speed_RPM = 0 + self.target_drain_pump_RPM = 0 self.dac_value = 0 + self.pressure_difference = 0 + self.drain_pump_state = 0 def get_target_drain_pump_speed(self): """ Gets the target drain pump speed @return: The target drain pump speed (RPM) """ - return self.target_drain_pump_speed_RPM + return self.target_drain_pump_RPM def get_dac_value(self): """ @@ -61,7 +87,7 @@ """ return self.dac_value - @_publish(["target_drain_pump_speed_RPM", "dac_value"]) + @_publish(["target_drain_pump_RPM", "dac_value", "pressure_difference", "drain_pump_state"]) def _handler_drain_pump_sync(self, message): """ Handles published drain pump data messages. Drain pump data are captured @@ -72,12 +98,18 @@ """ tgt = struct.unpack('i', bytearray( - message['message'][MsgFldPositions.START_POS_FIELD_1:MsgFldPositions.END_POS_FIELD_1])) + message['message'][self.START_POS_SET_SPD:self.END_POS_SET_SPD]))[0] dac = struct.unpack('i', bytearray( - message['message'][MsgFldPositions.START_POS_FIELD_2:MsgFldPositions.END_POS_FIELD_2])) + message['message'][self.START_POS_DAC:self.END_POS_DAC]))[0] + diff = struct.unpack('f', bytearray( + message['message'][self.START_POS_PRESS_DIFF:self.END_POS_PRESS_DIFF]))[0] + state = struct.unpack('i', bytearray( + message['message'][self.START_POS_PUMP_STATE:self.END_POS_PUMP_STATE]))[0] - self.target_drain_pump_speed_RPM = tgt[0] - self.dac_value = dac[0] + self.target_drain_pump_RPM = tgt + self.dac_value = dac + self.pressure_difference = diff + self.drain_pump_state = state def cmd_drain_pump_speed_set_point_override(self, speed, reset=NO_RESET): """ Index: dialin/dg/hd_proxy.py =================================================================== diff -u -r287af45040e35882e001fb3ea835f304007870c4 -rfbe3580dfcda2338d9fa33d09bee85099ea7b801 --- dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 287af45040e35882e001fb3ea835f304007870c4) +++ dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision fbe3580dfcda2338d9fa33d09bee85099ea7b801) @@ -27,6 +27,12 @@ \brief Dialysate Generator (DG) Dialin API sub-class for HD proxy commands. """ + # Pressure/Occlusion message IDs + MSG_ID_HD_SWITCH_RESERVOIRS_CMD = 0x0021 + MSG_ID_HD_FILL_CMD = 0x0022 + MSG_ID_HD_DRAIN_CMD = 0x0023 + MSG_ID_HD_START_STOP_DG_CMD = 0x0026 + MSG_ID_HD_START_STOP_DG_TRIMMER_HEATER = 0x002B # Reservoir IDs RESERVOIR1 = 0 Index: dialin/dg/ro_pump.py =================================================================== diff -u -r287af45040e35882e001fb3ea835f304007870c4 -rfbe3580dfcda2338d9fa33d09bee85099ea7b801 --- dialin/dg/ro_pump.py (.../ro_pump.py) (revision 287af45040e35882e001fb3ea835f304007870c4) +++ dialin/dg/ro_pump.py (.../ro_pump.py) (revision fbe3580dfcda2338d9fa33d09bee85099ea7b801) @@ -17,22 +17,47 @@ from ..utils.conversions import integer_to_bytearray, float_to_bytearray from ..common.msg_defs import MsgIds, MsgFldPositions from .constants import RESET, NO_RESET -from ..protocols.CAN import (DenaliMessage, - DenaliChannels) +from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish from logging import Logger +import enum +class ROPumpStates(enum.Enum): + RO_PUMP_OFF_STATE = 0 + RO_PUMP_RAMP_UP_STATE = 1 + RO_PUMP_VERIFY_FLOW_STATE = 2 + RO_PUMP_CONTROL_TO_TARGET_STATE = 3 + RO_PUMP_OPEN_LOOP_STATE = 4 + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + + class DGROPump(_AbstractSubSystem): """ DGROPump Dialysate Generator (DG) Dialin API sub-class for RO pump related commands. """ - #Enums - RAMP_UP_STATE = 0 + # RO pump message IDs + MSG_ID_DG_RO_PUMP_PUBLISHED_DATA = 0x1F + MSG_ID_DG_RO_PUMP_PRESSURE_SET_PT_OVERRIDE = 0xA008 + #MSG_ID_DG_RO_FLOW_RATE_OVERRIDE = 0xA009 + MSG_ID_DG_RO_PUMP_BROADCAST_INTERVAL_OVERRIDE = 0xA00A + MSG_ID_RO_PUMP_SET_PT_OVERRIDE = 0xA008 + # RO pump broadcast message field positions + START_POS_PRES_SET_PT = DenaliMessage.PAYLOAD_START_INDEX + END_POS_PRES_SET_PT = START_POS_PRES_SET_PT + 4 + START_POS_MEAS_FLOW = END_POS_PRES_SET_PT + END_POS_MEAS_FLOW = START_POS_MEAS_FLOW + 4 + START_POS_PWM = END_POS_MEAS_FLOW + END_POS_PWM = START_POS_PWM + 4 + START_POS_STATE = END_POS_PWM + END_POS_STATE = START_POS_STATE + 4 def __init__(self, can_interface, logger: Logger): """ @@ -45,11 +70,11 @@ if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id + msg_id = MsgIds.MSG_ID_RO_PUMP_DATA.value - self.can_interface.register_receiving_publication_function(channel_id, msg_id, - self._handler_ro_pump_sync) + self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_ro_pump_sync) - self.target_pressure_psi = 0 + self.target_pressure_psi = 0.0 self.measured_flow_rate_lpm = 0.0 self.pwm_duty_cycle_pct = 0.0 self.ro_pump_state = 0.0 @@ -75,48 +100,26 @@ """ return self.pwm_duty_cycle_pct - @_publish([ - "target_pressure_psi", - "measured_flow_rate_lpm", - "pwm_duty_cycle_pct", - "ro_pump_state" - ]) + @_publish(["target_pressure_psi", "measured_flow_rate_lpm", "pwm_duty_cycle_pct", "ro_pump_state"]) def _handler_ro_pump_sync(self, message): """ Handles published ro pump data messages. RO pump data are captured for reference. @param message: published RO pump data message + @return: None """ + tgt = struct.unpack('f', bytearray(message['message'][self.START_POS_PRES_SET_PT:self.END_POS_PRES_SET_PT]))[0] + flow = struct.unpack('f', bytearray(message['message'][self.START_POS_MEAS_FLOW:self.END_POS_MEAS_FLOW]))[0] + pwm = struct.unpack('f', bytearray(message['message'][self.START_POS_PWM:self.END_POS_PWM]))[0] + ro_state = struct.unpack('i', bytearray(message['message'][self.START_POS_STATE:self.END_POS_STATE]))[0] - tgt = struct.unpack('f', bytearray( - message['message'][MsgFldPositions.START_POS_FIELD_1:MsgFldPositions.END_POS_FIELD_1])) - flow = struct.unpack('f', bytearray( - message['message'][MsgFldPositions.START_POS_FIELD_2:MsgFldPositions.END_POS_FIELD_2])) - pwm = struct.unpack('f', bytearray( - message['message'][MsgFldPositions.START_POS_FIELD_3:MsgFldPositions.END_POS_FIELD_3])) - ro_state = struct.unpack('i', bytearray( - message['message'][MsgFldPositions.START_POS_FIELD_4:MsgFldPositions.END_POS_FIELD_4])) + self.target_pressure_psi = tgt + self.measured_flow_rate_lpm = flow + self.pwm_duty_cycle_pct = pwm + self.ro_pump_state = ROPumpStates(ro_state).name if ROPumpStates.has_value(ro_state) else 'State Unknown' - self.target_pressure_psi = tgt[0] - self.measured_flow_rate_lpm = flow[0] - self.pwm_duty_cycle_pct = pwm[0] - raw_ro_pump_state = ro_state[0] - - #self.ro_pump_state = self.ro_pump_states.get("RO_PUMP_OFF_STATE", -1) - - if raw_ro_pump_state == 0: - self.ro_pump_state = "RO_PUMP_OFF_STATE" - elif raw_ro_pump_state == 1: - self.ro_pump_state = "RO_PUMP_RAMP_UP_STATE" - elif raw_ro_pump_state == 2: - self.ro_pump_state = "RO_PUMP_VERIFY_FLOW_STATE" - elif raw_ro_pump_state == 3: - self.ro_pump_state = "RO_PUMP_CONTROL_TO_TARGET_STATE" - elif raw_ro_pump_state == 4: - self.ro_pump_state = "RO_PUMP_OPEN_LOOP_STATE" - def cmd_ro_pump_set_point_override(self, pressure, reset=NO_RESET): """ Constructs and sends the RO pump set point override command. Index: dialin/dg/valves.py =================================================================== diff -u -r287af45040e35882e001fb3ea835f304007870c4 -rfbe3580dfcda2338d9fa33d09bee85099ea7b801 --- dialin/dg/valves.py (.../valves.py) (revision 287af45040e35882e001fb3ea835f304007870c4) +++ dialin/dg/valves.py (.../valves.py) (revision fbe3580dfcda2338d9fa33d09bee85099ea7b801) @@ -21,12 +21,66 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish from logging import Logger +import enum # Valve states ENERGIZED = True DEENERGIZED = False +class VPiVSPVBfStates(enum.Enum): + VALVE_STATE_CLOSED = 0 + VALVE_STATE_OPEN = 1 + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + +class VPdStates(enum.Enum): + + VALVE_STATE_OPEN_C_TO_NO = 0 + VALVE_STATE_DRAIN_C_TO_NC = 1 + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + +class VPoStates(enum.Enum): + + VALVE_STATE_NOFILL_C_TO_NO = 0 + VALVE_STATE_FILL_C_TO_NC = 1 + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + +class VDrVRcStates(enum.Enum): + + VALVE_STATE_DRAIN_C_TO_NO = 0 + VALVE_STATE_RECIRC_C_TO_NC = 1 + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + +class VRoVRiStates(enum.Enum): + + VALVE_STATE_R1_C_TO_NO = 0 + VALVE_STATE_R2_C_TO_NC = 1 + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + +class VRdVRfStates(enum.Enum): + + VALVE_STATE_R2_C_TO_NO = 0 + VALVE_STATE_R1_C_TO_NC = 1 + + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + class DGValves(_AbstractSubSystem): """ Dialysate Generation (DG) interface for valve related commands. @@ -50,6 +104,7 @@ VALVE_RESERVOIR_1 = 10 # VR1 VALVE_RESERVOIR_2 = 11 # VR2 VALVE_PRODUCTION_DRAIN = 12 # VPD + NUM_OF_VALVES = 13 # Number of valves def __init__(self, can_interface, logger: Logger): """ @@ -81,6 +136,8 @@ self.valve_state_VR2 = {"id": self.VALVE_RESERVOIR_2, "state": DEENERGIZED} self.valve_state_VPD = {"id": self.VALVE_PRODUCTION_DRAIN, "state": DEENERGIZED} + self.valve_states_enum = [0 for i in range(self.NUM_OF_VALVES)] + def get_valve_states(self): """ Gets the valve states @@ -127,6 +184,7 @@ For example: >>> dg = DG() >>> observation = {'datetime': datetime.datetime(2020, 7, 13, 10, 43, 27, 433357), + 'valve_state_VBF': {'id': 5, 'state': True}, 'valve_state_VDR': {'id': 7, 'state': True}, 'valve_state_VPD': {'id': 12, 'state': True}, @@ -142,6 +200,7 @@ 'valve_state_VSP': {'id': 9, 'state': True}, 'valve_states_all': 8191} >>> self.logger.debug(dg.valves.sort_by_id(observation)) + ('valve_state_VRF', 0, True) ('valve_state_VRI', 1, True) ('valve_state_VRD', 2, True) @@ -193,7 +252,8 @@ "valve_state_VSP", "valve_state_VR1", "valve_state_VR2", - "valve_state_VPD" + "valve_state_VPD", + "valve_states_enum" ]) def _handler_valves_sync(self, message): """ @@ -220,6 +280,20 @@ self.valve_state_VR2["state"] = self._binary_to_valve_state(vst[0] & 2048) self.valve_state_VPD["state"] = self._binary_to_valve_state(vst[0] & 4096) + self.valve_states_enum[self.VALVE_RESERVOIR_FILL] = VRdVRfStates(self._binary_to_valve_state(vst[0] & 1)).name # VRF + self.valve_states_enum[self.VALVE_RESERVOIR_INLET] = VRoVRiStates(self._binary_to_valve_state(vst[0] & 2)).name # VRI + self.valve_states_enum[self.VALVE_RESERVOIR_DRAIN] = VRdVRfStates(self._binary_to_valve_state(vst[0] & 4)).name # VRD + self.valve_states_enum[self.VALVE_RESERVOIR_OUTLET] = VRoVRiStates(self._binary_to_valve_state(vst[0] & 8)).name # VRO + self.valve_states_enum[self.VALVE_PRESSURE_OUTLET] = VPoStates(self._binary_to_valve_state(vst[0] & 16)).name # VPO + self.valve_states_enum[self.VALVE_BYPASS_FILTER] = VPiVSPVBfStates(self._binary_to_valve_state(vst[0] & 32)).name # VBF + self.valve_states_enum[self.VALVE_RECIRCULATE] = VDrVRcStates(self._binary_to_valve_state(vst[0] & 64)).name # VRC + self.valve_states_enum[self.VALVE_DRAIN] = VDrVRcStates(self._binary_to_valve_state(vst[0] & 128)).name # VDR + self.valve_states_enum[self.VALVE_PRESSURE_INLET] = VPiVSPVBfStates(self._binary_to_valve_state(vst[0] & 256)).name # VPI + self.valve_states_enum[self.VALVE_SAMPLING_PORT] = VPiVSPVBfStates(self._binary_to_valve_state(vst[0] & 512)).name # VSP + self.valve_states_enum[self.VALVE_RESERVOIR_1] = self._binary_to_valve_state(vst[0] & 1024) # VR1 + self.valve_states_enum[self.VALVE_RESERVOIR_2] = self._binary_to_valve_state(vst[0] & 2048) # VR2 + self.valve_states_enum[self.VALVE_PRODUCTION_DRAIN] = VPdStates(self._binary_to_valve_state(vst[0] & 4096)).name # VPD + def cmd_valve_override(self, state, valve, reset=NO_RESET): """ Constructs and sends the valve state override command. Index: dialin/hd/alarms.py =================================================================== diff -u -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab -rfbe3580dfcda2338d9fa33d09bee85099ea7b801 --- dialin/hd/alarms.py (.../alarms.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) +++ dialin/hd/alarms.py (.../alarms.py) (revision fbe3580dfcda2338d9fa33d09bee85099ea7b801) @@ -8,35 +8,27 @@ # @file alarms.py # # @author (last) Peter Lucia -# @date (last) 26-Aug-2020 +# @date (last) 10-Nov-2020 # @author (original) Peter Lucia # @date (original) 02-Apr-2020 # ############################################################################ +import struct +from logging import Logger + +from .constants import RESET, NO_RESET +from ..common.msg_defs import MsgIds from ..protocols.CAN import (DenaliMessage, DenaliChannels) -from ..utils.conversions import integer_to_bytearray from ..utils.base import _AbstractSubSystem, _publish -from .constants import RESET, NO_RESET -from collections import OrderedDict -import struct -from logging import Logger -from ..common.alarm_defs import AlarmList +from ..utils.conversions import integer_to_bytearray class HDAlarms(_AbstractSubSystem): """ HD interface containing alarm related commands. """ - # alarms message IDs - MSG_ID_HD_ALARMS_PUBLISHED_STATUS = 0x0002 - MSG_ID_HD_ALARM_ACTIVATE = 0x0003 - MSG_ID_HD_ALARM_CLEAR = 0x0004 - MSG_ID_HD_ALARM_LAMP_OVERRIDE = 0x8004 - MSG_ID_HD_ALARM_STATE_OVERRIDE = 0x8006 - MSG_ID_HD_ALARM_TIME_OVERRIDE = 0x8007 - # Alarm lamp patterns HD_ALARM_LAMP_PATTERN_OFF = 0 HD_ALARM_LAMP_PATTERN_OK = 1 @@ -67,68 +59,6 @@ START_POS_ALARM_ID = DenaliMessage.PAYLOAD_START_INDEX END_POS_ALARM_ID = START_POS_ALARM_ID + 2 - # See AlarmDefs.h - ALARM_ID_NO_ALARM = 0 - ALARM_ID_SOFTWARE_FAULT = 1 - ALARM_ID_STUCK_BUTTON_TEST_FAILED = 2 - ALARM_ID_FPGA_POST_TEST_FAILED = 3 - ALARM_ID_WATCHDOG_POST_TEST_FAILED = 4 - ALARM_ID_UI_COMM_POST_FAILED = 5 - ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK = 6 - ALARM_ID_BLOOD_PUMP_OFF_CHECK = 7 - ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK = 8 - ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK = 9 - ALARM_ID_DIAL_IN_PUMP_MC_CURRENT_CHECK = 10 - ALARM_ID_DIAL_IN_PUMP_OFF_CHECK = 11 - ALARM_ID_DIAL_IN_PUMP_MC_DIRECTION_CHECK = 12 - ALARM_ID_DIAL_IN_PUMP_ROTOR_SPEED_CHECK = 13 - ALARM_ID_DIAL_OUT_PUMP_MC_CURRENT_CHECK = 14 - ALARM_ID_DIAL_OUT_PUMP_OFF_CHECK = 15 - ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK = 16 - ALARM_ID_DIAL_OUT_PUMP_ROTOR_SPEED_CHECK = 17 - ALARM_ID_WATCHDOG_EXPIRED = 18 - ALARM_ID_RTC_COMM_ERROR = 19 - ALARM_ID_RTC_CONFIG_ERROR = 20 - ALARM_ID_DG_COMM_TIMEOUT = 21 - ALARM_ID_UI_COMM_TIMEOUT = 22 - ALARM_ID_COMM_TOO_MANY_BAD_CRCS = 23 - ALARM_ID_TREATMENT_STOPPED_BY_USER = 24 - ALARM_ID_BLOOD_SITTING_WARNING = 25 - ALARM_ID_BLOOD_SITTING_TOO_LONG_NO_RESUME = 26 - ALARM_ID_BLOOD_SITTING_TOO_LONG_NO_RINSEBACK = 27 - ALARM_ID_CAN_MESSAGE_NOT_ACKED = 28 - ALARM_ID_OCCLUSION_BLOOD_PUMP = 29 - ALARM_ID_OCCLUSION_DIAL_IN_PUMP = 30 - ALARM_ID_OCCLUSION_DIAL_OUT_PUMP = 31 - ALARM_ID_ARTERIAL_PRESSURE_LOW = 32 - ALARM_ID_ARTERIAL_PRESSURE_HIGH = 33 - ALARM_ID_VENOUS_PRESSURE_LOW = 34 - ALARM_ID_VENOUS_PRESSURE_HIGH = 35 - ALARM_ID_UF_RATE_TOO_HIGH_ERROR = 36 - ALARM_ID_UF_VOLUME_ACCURACY_ERROR = 37 - ALARM_ID_RTC_BATTERY_LOW = 38 - ALARM_ID_RTC_OR_TIMER_ACCURACY_FAILURE = 39 - ALARM_ID_RTC_RAM_OPS_ERROR = 40 - ALARM_ID_NVDATA_EEPROM_OPS_FAILURE = 41 - ALARM_ID_NVDATA_MFG_RECORD_CRC_ERROR = 42 - ALARM_ID_NVDATA_SRVC_RECORD_CRC_ERROR = 43 - ALARM_ID_NVDATA_CAL_RECORD_CRC_ERROR = 44 - ALARM_ID_NVDATA_HW_USAGE_DATA_CRC_ERROR = 45 - AlARM_ID_NVDATA_DISINFECTION_DATE_CRC_ERROR = 46 - ALARM_ID_RO_PUMP_OUT_PRESSURE_OUT_OF_RANGE = 47 - ALARM_ID_TEMPERATURE_SENSORS_OUT_OF_RANGE = 48 - ALARM_ID_TEMPERATURE_SENSORS_INCONSISTENT = 49 - ALARM_ID_HD_COMM_TIMEOUT = 50 - ALARM_ID_VALVE_CONTROL_FAILURE = 51 - ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK = 52 - ALARM_ID_DIAL_IN_PUMP_FLOW_VS_MOTOR_SPEED_CHECK = 53 - ALARM_ID_DIAL_OUT_PUMP_FLOW_VS_MOTOR_SPEED_CHECK = 54 - ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK = 55 - ALARM_ID_DIAL_IN_PUMP_MOTOR_SPEED_CHECK = 56 - ALARM_ID_DIAL_OUT_PUMP_MOTOR_SPEED_CHECK = 57 - ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH = 58 - ALARM_ID_INLET_WATER_TEMPERATURE_OUT_OF_RANGE = 59 - def __init__(self, can_interface, logger: Logger): """ @param can_interface: Denali Can Messenger object @@ -139,16 +69,16 @@ if self.can_interface is not None: channel_id = DenaliChannels.hd_alarm_broadcast_ch_id - msg_id = self.MSG_ID_HD_ALARMS_PUBLISHED_STATUS + msg_id = MsgIds.MSG_ID_ALARM_STATUS.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_alarms_status_sync) channel_id = DenaliChannels.hd_alarm_broadcast_ch_id - msg_id = self.MSG_ID_HD_ALARM_ACTIVATE + msg_id = MsgIds.MSG_ID_ALARM_TRIGGERED.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_alarm_activate) channel_id = DenaliChannels.hd_alarm_broadcast_ch_id - msg_id = self.MSG_ID_HD_ALARM_CLEAR + msg_id = MsgIds.MSG_ID_ALARM_CLEARED.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_alarm_clear) @@ -162,11 +92,6 @@ # alarm states based on received HD alarm activation and alarm clear messages self.alarm_states = [False] * 500 - self.ids = OrderedDict() - 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): """ @@ -270,6 +195,7 @@ @param message: published HD alarm activation message @return: none """ + self.logger.debug("Alarm activated!") alarm_id = struct.unpack('