Index: leahi_dialin/common/msg_ids.py =================================================================== diff -u -r951bd79131f9c5dd0e62d40a2101815100cdb787 -r71216b08590dd4b556c10b3384dddc26c8d29a99 --- leahi_dialin/common/msg_ids.py (.../msg_ids.py) (revision 951bd79131f9c5dd0e62d40a2101815100cdb787) +++ leahi_dialin/common/msg_ids.py (.../msg_ids.py) (revision 71216b08590dd4b556c10b3384dddc26c8d29a99) @@ -125,6 +125,7 @@ MSG_ID_TD_BLOOD_PUMP_MEASURED_MOTOR_SPEED_OVERRIDE_REQUEST = 0x8029 MSG_ID_TD_BLOOD_PUMP_MEASURED_ROTOR_SPEED_OVERRIDE_REQUEST = 0x802A MSG_ID_TD_BLOOD_PUMP_ROTOR_COUNT_OVERRIDE_REQUEST = 0x802B + MSG_ID_TD_TMP_PRESSURE_OVERRIDE_REQUEST = 0x802C MSG_ID_DD_TESTER_LOGIN_REQUEST = 0xA000 MSG_ID_DD_SOFTWARE_RESET_REQUEST = 0xA001 Index: leahi_dialin/dd/modules/temperature_sensors.py =================================================================== diff -u -r7946b4fd43270deee7fcd5510190cab11b3e646c -r71216b08590dd4b556c10b3384dddc26c8d29a99 --- leahi_dialin/dd/modules/temperature_sensors.py (.../temperature_sensors.py) (revision 7946b4fd43270deee7fcd5510190cab11b3e646c) +++ leahi_dialin/dd/modules/temperature_sensors.py (.../temperature_sensors.py) (revision 71216b08590dd4b556c10b3384dddc26c8d29a99) @@ -5,7 +5,7 @@ # 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 temperatures.py +# @file temperature_sensors.py # # @author (last) Micahel Garthwaite # @date (last) 28-Jul-2023 Index: leahi_dialin/dd/modules/valves.py =================================================================== diff -u -rd28c8c54ba1f74adf348d1db6f5bfe034628c812 -r71216b08590dd4b556c10b3384dddc26c8d29a99 --- leahi_dialin/dd/modules/valves.py (.../valves.py) (revision d28c8c54ba1f74adf348d1db6f5bfe034628c812) +++ leahi_dialin/dd/modules/valves.py (.../valves.py) (revision 71216b08590dd4b556c10b3384dddc26c8d29a99) @@ -44,10 +44,10 @@ D8_VALV = 2 # Valve Hydraulics Bypass (D8) D54_VALV = 3 # Valve Rinse Port (D54) D53_VALV = 4 # Valve Drain (D53) - D65_VALV = 5 # Valve DryBcarb Inlet (D65) + D34_VALV = 5 # Valve DryBcarb Inlet (D65) D64_VALV = 6 # Valve Purge 1 (D64) D31_VALV = 7 # Valve Pressure Test (D31) - D34_VALV = 8 # Valve Dialyzer Bypass (D34) + D65_VALV = 8 # Valve Dialyzer Bypass (D34) D35_VALV = 9 # Valve Dialyzer Inlet (D35) D40_VALV = 10 # Valve Dialyzer Outlet (D40) D47_VALV = 11 # Valve Dialysate Out Purge 2 (D47) @@ -258,10 +258,10 @@ self.d8_valv["state"] = self._binary_to_valve_state(vst[0] & 4) self.d54_valv["state"] = self._binary_to_valve_state(vst[0] & 8) self.d53_valv["state"] = self._binary_to_valve_state(vst[0] & 16) - self.d65_valv["state"] = self._binary_to_valve_state(vst[0] & 32) + self.d34_valv["state"] = self._binary_to_valve_state(vst[0] & 32) self.d64_valv["state"] = self._binary_to_valve_state(vst[0] & 64) self.d31_valv["state"] = self._binary_to_valve_state(vst[0] & 128) - self.d34_valv["state"] = self._binary_to_valve_state(vst[0] & 256) + self.d65_valv["state"] = self._binary_to_valve_state(vst[0] & 256) self.d35_valv["state"] = self._binary_to_valve_state(vst[0] & 512) self.d40_valv["state"] = self._binary_to_valve_state(vst[0] & 1024) self.d47_valv["state"] = self._binary_to_valve_state(vst[0] & 2048) @@ -376,10 +376,10 @@ @param bcv1: bool - valve state for D23_VALV (true=open, false=closed) @param bcv2: bool - valve state for D19_VALV (true=open, false=closed) @param bcv3: bool - valve state for D25_VALV (true=open, false=closed) - @param bcv4: bool - valve state for D26_VALV (true=open, false=closed) + @param bcv4: bool - valve state for D21_VALV (true=open, false=closed) @param bcv5: bool - valve state for D24_VALV (true=open, false=closed) @param bcv6: bool - valve state for D20_VALV (true=open, false=closed) - @param bcv7: bool - valve state for D21_VALV (true=open, false=closed) + @param bcv7: bool - valve state for D26_VALV (true=open, false=closed) @param bcv8: bool - valve state for D22_VALV (true=open, false=closed) @return: 1 if successful, zero otherwise """ Index: leahi_dialin/fp/filtration_purification.py =================================================================== diff -u -r0f08c28544b557b2bbd8c04b10cff284f41e4fb9 -r71216b08590dd4b556c10b3384dddc26c8d29a99 --- leahi_dialin/fp/filtration_purification.py (.../filtration_purification.py) (revision 0f08c28544b557b2bbd8c04b10cff284f41e4fb9) +++ leahi_dialin/fp/filtration_purification.py (.../filtration_purification.py) (revision 71216b08590dd4b556c10b3384dddc26c8d29a99) @@ -110,6 +110,7 @@ self.flows = FPFlowSensors(self.can_interface, self.logger) self.levels = FPLevels(self.can_interface, self.logger) self.pressures = FPPressureSensors(self.can_interface, self.logger) + self.temperatures = FPTemperatureSensors(self.can_interface, self.logger) self.valves = FPValves(self.can_interface, self.logger) @publish(["fp_debug_events_timestamp","fp_debug_events"]) Index: leahi_dialin/fp/modules/temperatures.py =================================================================== diff -u --- leahi_dialin/fp/modules/temperatures.py (revision 0) +++ leahi_dialin/fp/modules/temperatures.py (revision 71216b08590dd4b556c10b3384dddc26c8d29a99) @@ -0,0 +1,114 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file temperature_sensors.py +# +# @author (last) Micahel Garthwaite +# @date (last) 28-Jul-2023 +# @author (original) Dara Navaei +# @date (original) 01-Dec-2021 +# +############################################################################ +import struct +from enum import unique +from logging import Logger + +from .constants import NO_RESET, RESET +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish, DialinEnum +from leahi_dialin.utils.checks import check_broadcast_interval_override_ms +from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray + +@unique +class FPTemperaturesNames(DialinEnum): + P23_TEMP = 0 # P23 temperature sensor. + P22_TEMP = 1 # P22 temperature sensor. + P10_TEMP = 2 # P10 temperature from inlet conductivity sensor. + P19_TEMP = 3 # P19 temperature from outlet conductivity sensor. + FP_BOARD_TEMP = 4 # Board Temperature Sensor + +class FPTemperatureSensors(AbstractSubSystem): + + def __init__(self, can_interface, logger: Logger): + super().__init__() + + self.can_interface = can_interface + self.logger = logger + + + if self.can_interface is not None: + channel_id = DenaliChannels.dd_sync_broadcast_ch_id + msg_id = MsgIds.MSG_ID_RO_TEMPERATURE_DATA.value + self.can_interface.register_receiving_publication_function(channel_id, msg_id, + self._handler_temperature_sensors_sync) + + self.fp_temperature_sensors_timestamp = 0.0 + self.fp_temperatures = {FPTemperaturesNames.P23_TEMP.name: 0.0, + FPTemperaturesNames.P22_TEMP.name: 0.0, + FPTemperaturesNames.P10_TEMP.name: 0.0, + FPTemperaturesNames.P19_TEMP.name: 0.0, + FPTemperaturesNames.FP_BOARD_TEMP.name: 0.0 } + + @publish(["fp_temperatures_timestamp", "fp_temperatures"]) + def _handler_temperature_sensors_sync(self, message,timestamp=0.0): + """ + Handles published FP temperature sensors message + + @param message: published FP temperature sensors data message + @returns none + """ + self.fp_temperatures[FPTemperaturesNames.P23_TEMP.name] = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + + self.fp_temperatures[FPTemperaturesNames.P22_TEMP.name] = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + + self.fp_temperatures[FPTemperaturesNames.P10_TEMP.name] = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + + self.fp_temperatures[FPTemperaturesNames.P19_TEMP.name] = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] + + self.fp_temperatures[FPTemperaturesNames.FP_BOARD_TEMP.name] = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] + + + def cmd_temperatures_data_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends broadcast time interval. + Constraints: + Must be logged into FP. + Given interval must be non-zero and a multiple of the FP general task interval (50 ms). + + @param ms: (int) Publish time interval in ms + @param reset: (int) 1 to reset a previous override, 0 to override + @returns 1 if successful, zero otherwise + """ + if not check_broadcast_interval_override_ms(ms): + return False + + reset_value = integer_to_bytearray(reset) + interval_value = integer_to_bytearray(ms) + payload = reset_value + interval_value + + message = DenaliMessage.build_message( + channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_RO_TEMPERATURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("Sending {} ms publish interval to the Temperature Sensors module".format(ms)) + # Send message + received_message = self.can_interface.send(message) + + # If there is content in message + if received_message is not None: + # Response payload is OK or not + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False \ No newline at end of file Index: leahi_dialin/fp/modules/valves.py =================================================================== diff -u -r5b9473d9ca6a66d4d03c509fae6051710895b498 -r71216b08590dd4b556c10b3384dddc26c8d29a99 --- leahi_dialin/fp/modules/valves.py (.../valves.py) (revision 5b9473d9ca6a66d4d03c509fae6051710895b498) +++ leahi_dialin/fp/modules/valves.py (.../valves.py) (revision 71216b08590dd4b556c10b3384dddc26c8d29a99) @@ -76,15 +76,15 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_valves_sync) self.valve_states_all = 0x0000 - self.m4_vwi_state= {"id": FPValveNames.M4_VWI.value, "state": DEENERGIZED} - self.p39_vrod_state = {"id": FPValveNames.P39_VROD.value, "state": DEENERGIZED} - self.p6_vff_state = {"id": FPValveNames.P6_VFF.value, "state": DEENERGIZED} - self.p11_vpi_state = {"id": FPValveNames.P11_VPI.value, "state": DEENERGIZED} - self.p33_vcr_state = {"id": FPValveNames.P33_VCR.value, "state": DEENERGIZED} - self.p34_vcb_state = {"id": FPValveNames.P34_VCB.value, "state": DEENERGIZED} - self.p37_vcd_state = {"id": FPValveNames.P37_VCD.value, "state": DEENERGIZED} - self.m7_vfb_state = {"id": FPValveNames.M7_VFB.value, "state": DEENERGIZED} - self.p20_spp_state = {"id": FPValveNames.P20_SPP.value, "state": DEENERGIZED} + self.m4_valv = {"id": FPValveNames.M4_VWI.value, "state": DEENERGIZED} + self.p39_valv = {"id": FPValveNames.P39_VROD.value, "state": DEENERGIZED} + self.p6_valv = {"id": FPValveNames.P6_VFF.value, "state": DEENERGIZED} + self.p11_valv = {"id": FPValveNames.P11_VPI.value, "state": DEENERGIZED} + self.p33_valv = {"id": FPValveNames.P33_VCR.value, "state": DEENERGIZED} + self.p34_valv = {"id": FPValveNames.P34_VCB.value, "state": DEENERGIZED} + self.p37_valv = {"id": FPValveNames.P37_VCD.value, "state": DEENERGIZED} + self.m7_valv = {"id": FPValveNames.M7_VFB.value, "state": DEENERGIZED} + self.p20_valv = {"id": FPValveNames.P20_SPP.value, "state": DEENERGIZED} # NOTE: The len function counts the enums with the same number only once. This is not the case in the DG valves # class because each valve must have a unique ID. @@ -100,15 +100,15 @@ @return: All valve states """ return [ - self.m4_vwi_state.get("state"), - self.p39_vrod_state.get("state"), - self.p6_vff_state.get("state"), - self.p11_vpi_state.get("state"), - self.p33_vcr_state.get("state"), - self.p34_vcb_state.get("state"), - self.p37_vcd_state.get("state"), - self.m7_vfb_state.get("state"), - self.p20_spp_state.get("state") + self.m4_valv.get("state"), + self.p39_valv.get("state"), + self.p6_valv.get("state"), + self.p11_valv.get("state"), + self.p33_valv.get("state"), + self.p34_valv.get("state"), + self.p37_valv.get("state"), + self.m7_valv.get("state"), + self.p20_valv.get("state") ] @staticmethod @@ -144,15 +144,15 @@ @publish([ "fp_valves_states_timestamp", "valve_states_all", - "m4_vwi_state", - "p39_vrod_state", - "p6_vff_state", - "p11_vpi_state", - "p33_vcr_state", - "p34_vcb_state", - "p37_vcd_state", - "m7_vfb_state", - "p20_spp_state", + "m4_valv", + "p39_valv", + "p6_valv", + "p11_valv", + "p33_valv", + "p34_valv", + "p37_valv", + "m7_valv", + "p20_valv", "valve_states_enum" ]) def _handler_valves_sync(self, message, timestamp=0.0): @@ -166,15 +166,15 @@ vst = struct.unpack('H', bytearray(message['message'][self.START_POS_VALVES_STATES:self.END_POS_VALVES_STATES])) self.valve_states_all = vst[0] # Extract each valve state from U16 valves states using bit-masking - self.m4_vwi_state["state"] = self._binary_to_valve_state(vst[0] & 1) - self.p39_vrod_state["state"] = self._binary_to_valve_state(vst[0] & 2) - self.p6_vff_state["state"] = self._binary_to_valve_state(vst[0] & 4) - self.p11_vpi_state["state"] = self._binary_to_valve_state(vst[0] & 8) - self.p33_vcr_state["state"] = self._binary_to_valve_state(vst[0] & 16) - self.p34_vcb_state["state"] = self._binary_to_valve_state(vst[0] & 32) - self.p37_vcd_state["state"] = self._binary_to_valve_state(vst[0] & 64) - self.m7_vfb_state["state"] = self._binary_to_valve_state(vst[0] & 128) - self.p20_spp_state["state"] = self._binary_to_valve_state(vst[0] & 256) + self.m4_valv["state"] = self._binary_to_valve_state(vst[0] & 1) + self.p39_valv["state"] = self._binary_to_valve_state(vst[0] & 2) + self.p6_valv["state"] = self._binary_to_valve_state(vst[0] & 4) + self.p11_valv["state"] = self._binary_to_valve_state(vst[0] & 8) + self.p33_valv["state"] = self._binary_to_valve_state(vst[0] & 16) + self.p34_valv["state"] = self._binary_to_valve_state(vst[0] & 32) + self.p37_valv["state"] = self._binary_to_valve_state(vst[0] & 64) + self.m7_valv["state"] = self._binary_to_valve_state(vst[0] & 128) + self.p20_valv["state"] = self._binary_to_valve_state(vst[0] & 256) start = self.END_POS_VALVES_STATES end = start + 1 Index: leahi_dialin/td/modules/valves.py =================================================================== diff -u -rd0d72ba74208cb43073ec38c7bbfebb2d32dcc66 -r71216b08590dd4b556c10b3384dddc26c8d29a99 --- leahi_dialin/td/modules/valves.py (.../valves.py) (revision d0d72ba74208cb43073ec38c7bbfebb2d32dcc66) +++ leahi_dialin/td/modules/valves.py (.../valves.py) (revision 71216b08590dd4b556c10b3384dddc26c8d29a99) @@ -29,8 +29,8 @@ @unique class ValvesEnum(DialinEnum): - H1_VBA = 0 - H19_VBV = 1 + H1_VALV = 0 + H19_VALV = 1 @unique @@ -92,8 +92,8 @@ self.td_valves_timestamp = 0.0 # A dictionary of the valves with the status - self.valves_status = {ValvesEnum.H1_VBA.name: {}, - ValvesEnum.H19_VBV.name: {}} + self.valves_status = {ValvesEnum.H1_VALV.name: {}, + ValvesEnum.H19_VALV.name: {}} @publish(["td_valves_timestamp","valves_status"]) def _handler_valves_sync(self, message: dict, timestamp=0.0) -> None: