Index: leahi_dialin/common/dd_defs.py =================================================================== diff -u -ra5b82c620e6a54f2b8559c54ffaa1a84e831d88e -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/common/dd_defs.py (.../dd_defs.py) (revision a5b82c620e6a54f2b8559c54ffaa1a84e831d88e) +++ leahi_dialin/common/dd_defs.py (.../dd_defs.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -364,7 +364,15 @@ SPARE5_VALV = 29 # Spare Valve 5 D100_VALV = 30 # Valve De-scaler (D100) SPARE7_VALV = 31 # Spare Valve 7 - NUM_OF_DD_VALVES = 32 # Number of Valves for the DD + M4_VALV = 32 # First IO valve (M4) + M12_VALV = 33 # Last IO valve IO valve (M12) + P11_VALV = 34 # First FP Valve (P11) + P33_VALV = 35 # FP Valve (P33) + P34_VALV = 36 # FP Valve (P34) + P37_VALV = 37 # FP Valve (P37) + P39_VALV = 38 # FP Valve (P39) + P6_VALV = 39 # Last FP Valve (P6) + NUM_OF_DD_VALVES = 40 # Number of Valves for the DD @unique class DDNotLegalStates(DialinEnum): Index: leahi_dialin/common/msg_ids.py =================================================================== diff -u -rc4579da3bd8c483e8675f2894901d3dcdbea7b99 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/common/msg_ids.py (.../msg_ids.py) (revision c4579da3bd8c483e8675f2894901d3dcdbea7b99) +++ leahi_dialin/common/msg_ids.py (.../msg_ids.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -132,9 +132,20 @@ MSG_ID_DD_DATE_AND_TIME_REQUEST = 0x6E MSG_ID_DD_DATE_AND_TIME_RESPONSE = 0x6F MSG_ID_FP_RO_REJECTION_RATIO_DATA = 0x71 + MSG_ID_TD_INSTITUTIONAL_RECORD_REQUEST = 0x82 + MSG_ID_TD_INSTITUTIONAL_RECORD_RESPONSE = 0x83 + MSG_ID_TD_ADJUST_INSTITUTIONAL_RECORD_REQUEST = 0x84 + MSG_ID_TD_ADJUST_INSTITUTIONAL_RECORD_RESPONSE = 0x85 + MSG_ID_TD_ADVANCED_INSTITUTIONAL_RECORD_REQUEST = 0x86 + MSG_ID_TD_ADVANCED_INSTITUTIONAL_RECORD_RESPONSE = 0x87 + MSG_ID_TD_ADVANCED_ADJUST_INSTITUTIONAL_RECORD_REQUEST = 0x88 + MSG_ID_TD_ADVANCED_ADJUST_INSTITUTIONAL_RECORD_RESPONSE = 0x89 MSG_ID_TD_HEPARIN_REQUEST = 0x8A MSG_ID_TD_HEPARIN_RESPONSE = 0x8B MSG_ID_TD_HEPARIN_DATA = 0x8C + MSG_ID_TD_END_TREATMENT_REQUEST = 0x8D + MSG_ID_TD_END_TREATMENT_RESPONSE = 0x8E + MSG_ID_DD_PISTON_PUMP_CONTROL_DATA = 0xF0 MSG_ID_TD_TESTER_LOGIN_REQUEST = 0x8000 Index: leahi_dialin/dd/modules/alarms.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/alarms.py (.../alarms.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/alarms.py (.../alarms.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,23 +7,25 @@ # # @file alarms.py # -# @author (last) Micahel Garthwaite -# @date (last) 17-Aug-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Quang Nguyen # @date (original) 02-Sep-2020 # ############################################################################ + import struct from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.dd_defs import DDEventDataType from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override 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 +from leahi_dialin.utils.base import AbstractSubSystem, publish +from leahi_dialin.utils.conversions import integer_to_bytearray + class DDAlarms(AbstractSubSystem): """ DD interface containing alarm related commands. @@ -45,7 +47,12 @@ self.msg_id_dd_alarm_triggered = MsgIds.MSG_ID_ALARM_TRIGGERED.value self.can_interface.register_receiving_publication_function(channel_id, self.msg_id_dd_alarm_triggered, self._handler_alarm_triggered) + self.alarm_safety_shutdown_status = 0.0 + + self.dd_alarm_info_timestamp = 0.0 self.dd_alarm_triggered_timestamp = 0.0 + self.dd_alarm_cleared_timestamp = 0.0 + self.dd_alarm_condition_cleared_timestamp = 0.0 # alarm states based on received TD alarm activation and alarm clear messages self.alarm_states = [False] * 500 # alarm condition states based on received TD alarm activation and clear condition messages @@ -82,6 +89,7 @@ self.alarm_data_type[event_data_type] = struct_unpack_type + @publish(["msg_id_dd_alarm_triggered", "alarm_states", "alarm_conditions", "alarm_data", "alarm_priorities", "alarm_ranks", "alarm_clear_top_only_flags", "dd_alarm_triggered_timestamp"]) def _handler_alarm_triggered(self, message, timestamp = 0.0): @@ -123,9 +131,140 @@ self.dd_alarm_triggered_timestamp = timestamp + @publish(["msg_id_dd_alarm_info", "safetyShutdownStatus", "dd_alarm_info_timestamp"]) def _handler_alarm_info(self, message, timestamp = 0.0): - pass + """ + Handles published DD alarm info messages. + @param message: published DD alarm info message + @return: none + """ + self.alarm_safety_shutdown_status = struct.unpack('I', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) + + self.dd_alarm_info_timestamp = timestamp + + + @publish(["msg_id_dd_alarm_cleared", "dd_alarm_cleared_timestamp"]) + def _handler_alarm_cleared(self, message, timestamp = 0.0): + """ + Handles published DD alarm cleared messages. + + @param message: published DD alarm cleared message + @return: none + """ + #ToDo + self.dd_alarm_cleared_timestamp = timestamp + + + @publish(["msg_id_dd_alarm_condition_cleared", "dd_alarm_condition_cleared_timestamp"]) + def _handler_alarm_condition_cleared(self, message, timestamp = 0.0): + """ + Handles published DD alarm condition cleared messages. + + @param message: published DD alarm condition cleared message + @return: none + """ + #ToDo + self.dd_alarm_condition_cleared_timestamp = timestamp + + + def cmd_alarm_state_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the alarm state data broadcast interval override command + Constraints: + Must be logged into DD. + Given interval must be non-zero and a multiple of the DD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + print('Not implemented in the FW') + return False + + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = '', + module_name = 'DD Alarm state', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_alarm_info_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the alarm info data broadcast interval override command + Constraints: + Must be logged into DD. + Given interval must be non-zero and a multiple of the DD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + print('Not implemented in the FW') + return False + + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = '', + module_name = 'DD Alarm info', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_alarm_cleared_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the alarm cleared data broadcast interval override command + Constraints: + Must be logged into DD. + Given interval must be non-zero and a multiple of the DD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + print('Not implemented in the FW') + return False + + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = '', + module_name = 'DD Alarm cleared', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_alarm_condition_cleared_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the alarm condition cleared data broadcast interval override command + Constraints: + Must be logged into DD. + Given interval must be non-zero and a multiple of the DD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + print('Not implemented in the FW') + return False + + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = '', + module_name = 'DD Alarm condition cleared', + logger = self.logger, + can_interface = self.can_interface) + + def cmd_alarm_state_override(self, alarm: int, state: int, reset: int = NO_RESET) -> int: """ Constructs and sends the alarm state override command @@ -139,32 +278,17 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) sta = integer_to_bytearray(state) alm = integer_to_bytearray(alarm) payload = rst + sta + alm - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_ALARM_STATE_OVERRIDE_REQUEST.value, - payload=payload) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # self.logger.debug(received_message) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = ("active" if state != 0 else "inactive") - self.logger.debug("Alarm " + str(alarm) + " " + str_res + ": " + - str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - - #TODO: alarm state override, alarm info pubish override + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_ALARM_STATE_OVERRIDE_REQUEST, + entity_name = f'DD Alarm {str(alarm)}', + override_text = "active" if state != 0 else "inactive", + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/balancing_chamber.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/balancing_chamber.py (.../balancing_chamber.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/balancing_chamber.py (.../balancing_chamber.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,23 +7,24 @@ # # @file balancing_chamber.py # -# @author (last) Micahel Garthwaite -# @date (last) 07-Mar-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Micahel Garthwaite # @date (original) 29-Oct-2020 # ############################################################################ + import struct -from enum import unique from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_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.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray + class DDBalancingChamber(AbstractSubSystem): """ Balancing Chamber @@ -46,7 +47,6 @@ self.msg_id_dd_bal_chamber_data = MsgIds.MSG_ID_DD_BAL_CHAMBER_DATA.value self.can_interface.register_receiving_publication_function(channel_id, self.msg_id_dd_bal_chamber_data, self._handler_balancing_chamber_sync) - self.execution_state = 0 self.switching_state = 0 self.switching_frequency = 0.0 @@ -57,6 +57,7 @@ self.bal_chamber_switch_only_state = 0 self.dd_bal_chamber_timestamp = 0 + @publish(["msg_id_dd_bal_chamber_data", "execution_state", "switching_state", "switching_frequency", @@ -71,7 +72,6 @@ @param message: published balancing chamber data message @return: None """ - self.execution_state = struct.unpack('I', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.switching_state = struct.unpack('I', bytearray( @@ -91,6 +91,7 @@ self.dd_bal_chamber_timestamp = timestamp + def cmd_balancing_chamber_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the balancing chamber data broadcast interval override command @@ -102,31 +103,16 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BAL_CHAMBER_DATA_PUBLISH_OVERRIDE_REQUEST, + module_name = 'DD Balancing Chamber', + logger = self.logger, + can_interface = self.can_interface) + - if not check_broadcast_interval_override_ms(ms): - return False - - reset_byte_array = integer_to_bytearray(reset) - ms_byte_array = integer_to_bytearray(ms) - payload = reset_byte_array + ms_byte_array - - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BAL_CHAMBER_DATA_PUBLISH_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override DD Balancing Chamber data broadcast interval") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_switch_frequency_override(self, frequency: float, reset: int = NO_RESET) -> int: """ Constructs and sends the balancing chamber switch frequency override command @@ -138,32 +124,21 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) freq = float_to_bytearray(frequency) payload = reset_byte_array + freq - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BAL_CHAMBER_SWITCH_FREQ_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BAL_CHAMBER_SWITCH_FREQ_OVERRIDE_REQUEST, + entity_name = 'Switch Frequency', + override_text = str(frequency), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(frequency) - self.logger.debug("override switch frequency " + ": " + str_res) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_switch_only_start_stop_override(self, start_stop: int, flow: float) -> int: """ Constructs and sends the balancing chamber switch only start stop override command @@ -175,26 +150,21 @@ @return: 1 if successful, zero otherwise """ - sts = integer_to_bytearray(start_stop) freq = float_to_bytearray(flow) payload = sts + freq - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BC_SWITCH_ONLY_START_STOP_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BC_SWITCH_ONLY_START_STOP_OVERRIDE_REQUEST, + entity_name = 'Switch Only Start' if start_stop == 1 else 'Switch Only Stop', + override_text = str(flow), + logger = self.logger, + can_interface = self.can_interface) - # Send message - received_message = self.can_interface.send(message) - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_acid_dose_volume_override(self, volume: float, reset: int = NO_RESET) -> int: """ Constructs and sends the acid dose volume override command @@ -206,32 +176,21 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) vol = float_to_bytearray(volume) payload = reset_byte_array + vol - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_ACID_DOSING_VOLUME_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_ACID_DOSING_VOLUME_OVERRIDE_REQUEST, + entity_name = 'Acid dose volume', + override_text = str(volume), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(volume) - self.logger.debug("override acid dose volume to frequency " + ": " + str_res) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_bicarb_dose_volume_override(self, volume: float, reset: int = NO_RESET) -> int: """ Constructs and sends the bicarb dose volume override command @@ -243,28 +202,16 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) vol = float_to_bytearray(volume) payload = reset_byte_array + vol - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BICARB_DOSING_VOLUME_OVERRIDE_REQUEST.value, - payload=payload) - - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(volume) - self.logger.debug("override bicarb dose volume to frequency " + ": " + str_res) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BICARB_DOSING_VOLUME_OVERRIDE_REQUEST, + entity_name = 'Bicarb dose volume', + override_text = str(volume), + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/blood_leak.py =================================================================== diff -u -r776be9fb446685fb492a2b7bd6faf4eac7dfe714 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/blood_leak.py (.../blood_leak.py) (revision 776be9fb446685fb492a2b7bd6faf4eac7dfe714) +++ leahi_dialin/dd/modules/blood_leak.py (.../blood_leak.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -1,12 +1,28 @@ +########################################################################### +# +# Copyright (c) 2020-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 blood_leak.py +# +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 +# @author (original) Dara Navaei +# @date (original) 21-Aug-2025 +# +############################################################################ import struct from logging import Logger from enum import unique -from .constants import RESET, NO_RESET -from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.dd_defs import DDBloodLeakStates -from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish, DialinEnum from leahi_dialin.utils.conversions import integer_to_bytearray, bytearray_to_byte, bytearray_to_integer, \ unsigned_short_to_bytearray, byte_to_bytearray, float_to_bytearray @@ -75,6 +91,7 @@ # Initialize all the embedded mode commands self.blood_leak_emb_mode_cmds[cmd] = '' + def get_blood_leak_status(self): """ Gets the current blood leak status @@ -83,6 +100,7 @@ """ return self.blood_leak_status + def get_blood_leak_state(self): """ Gets the current blood leak state @@ -93,6 +111,7 @@ """ return self.blood_leak_state + def get_blood_leak_emb_mode_command_response(self, emb_mod_cmd: int) -> str: """ Gets the most recent embedded mode command response for a given command @@ -106,6 +125,7 @@ else: self.logger.debug("Invalid command!") + @publish(['msg_id_dd_blood_leak_data', 'blood_leak_status', 'blood_leak_state', 'blood_leak_error_persistent_ctr', 'blood_leak_serial_comm_state', 'blood_leak_intensity', 'blood_leak_blood_detect', 'blood_leak_intensity_moving_average', @@ -114,7 +134,7 @@ 'dd_blood_leak_status_timestamp',]) def _handler_blood_leak_sync(self, message, timestamp=0.0): """ - Handles published blood leak status messages. Blood leak status is captured + Handles published blood leak status messages. Blood leak status is captured for reference. @param message: published blood leak status message @@ -142,99 +162,98 @@ message['message'][MsgFieldPositions.START_POS_FIELD_10:MsgFieldPositions.END_POS_FIELD_10]))[0] self.dd_blood_leak_status_timestamp = timestamp - def cmd_blood_leak_detector_override(self, detected: int, reset=NO_RESET): + + @publish(['msg_id_dd_send_blood_leak_emb_mode_response', 'blood_leak_emb_mode_cmd_response', + 'dd_blood_leak_emb_mode_response_timestamp']) + def _handler_blood_leak_emb_mode_cmd_resp(self, message, timestamp=0.0): """ - Constructs and sends the blood leak detector state override command - Constraints: - Must be logged into DD. + Handles published blood leak status messages. Blood leak status is captured + for reference. - @param detected: unsigned int - detected (0=detected, 1=undetected) to override detector with - @param reset: integer - 1 to reset a previous override, 0 to override - @return: 1 if successful, zero otherwise + @param message: published blood leak status message + @return: None """ - rst = integer_to_bytearray(reset) - det = integer_to_bytearray(detected) - payload = rst + det + # Clear the variable for the next read + blood_leak_emb_mode_cmd_response = '' + payload = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + cmd, index = bytearray_to_byte(payload, index, False) + length, index = bytearray_to_integer(payload, index, False) - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BLOOD_LEAK_STATUS_OVERRIDE_REQUEST.value, - payload=payload) + for i in range(0, length): + # Loop through the length and get the + char, char_index = bytearray_to_byte(payload, index + i, False) + blood_leak_emb_mode_cmd_response += chr(char) - self.logger.debug("Override blood leak detector state value") + self.blood_leak_emb_mode_cmds[EmbModeCommands(cmd).name] = blood_leak_emb_mode_cmd_response + self.dd_blood_leak_emb_mode_response_timestamp = timestamp - # Send message - received_message = self.can_interface.send(message) - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - - def cmd_blood_leak_zero_request(self): + def cmd_blood_leak_data_broadcast_interval_override(self, ms, reset=NO_RESET): """ - Request blood leak zeroing + Constructs and sends the blood leak data broadcast interval override command Constraints: Must be logged into DD. + Given interval must be non-zero and a multiple of the DD general task interval (50 ms). + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BLOOD_LEAK_ZERO_REQUEST.value) + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BLOOD_LEAK_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Blood Leak', + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("Request blood leak zeroing") - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - - def cmd_blood_leak_data_broadcast_interval_override(self, ms, reset=NO_RESET): + def cmd_blood_leak_detector_override(self, detected: int, reset=NO_RESET): """ - Constructs and sends the blood leak data broadcast interval override command + Constructs and sends the blood leak detector state override command Constraints: Must be logged into DD. - Given interval must be non-zero and a multiple of the DD general task interval (50 ms). - @param ms: integer - interval (in ms) to override with + @param detected: unsigned int - detected (0=detected, 1=undetected) to override detector with @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) - mis = integer_to_bytearray(ms) - payload = rst + mis - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BLOOD_LEAK_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) + det = integer_to_bytearray(detected) + payload = rst + det - self.logger.debug("Override DD blood leak data broadcast interval") + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BLOOD_LEAK_STATUS_OVERRIDE_REQUEST, + entity_name = 'DD Blood Leak Detector state', + override_text = str(detected), + logger = self.logger, + can_interface = self.can_interface) - # Send message - received_message = self.can_interface.send(message) - # If there is content... - if received_message is not None: - if reset == RESET: - str_res = "reset back to normal: " - else: - str_res = str(ms) + " ms: " - self.logger.debug("Blood leak data broadcast interval overridden to " + str_res + - str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False + def cmd_blood_leak_zero_request(self): + """ + Request blood leak zeroing + Constraints: + Must be logged into DD. + @return: 1 if successful, zero otherwise + """ + return cmd_generic_override( + payload = None, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BLOOD_LEAK_ZERO_REQUEST, + entity_name = 'DD Blood Leak Zeroing', + override_text = 'Active', + logger = self.logger, + can_interface = self.can_interface) + + def cmd_blood_leak_set_to_embedded_mode(self): """ Constructs and sends switching to embedded mode command @@ -243,21 +262,17 @@ @return: non-zero integer if successful, False otherwise """ - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BLOOD_LEAK_SET_TO_EMBEDDED_MODE_REQUEST.value) + return cmd_generic_override( + payload = None, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BLOOD_LEAK_SET_TO_EMBEDDED_MODE_REQUEST, + entity_name = 'DD Blood Leak Embedded mode', + override_text = 'Active', + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("Setting the blood leak to embedded mode") - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - def cmd_blood_leak_set_embedded_mode_command(self, command: int, msg_payload: int = None): """ Constructs and sends switching to embedded mode command @@ -279,49 +294,18 @@ data = unsigned_short_to_bytearray(data) payload = command_bytes + data - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BLOOD_LEAK_SET_EMBEDDED_MODE_CMD_REQUEST.value, - payload=payload) - self.logger.debug("Sending " + str(EmbModeCommands(command).name) + " to the blood leak sensor") + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BLOOD_LEAK_SET_EMBEDDED_MODE_CMD_REQUEST, + entity_name = f'DD {str(EmbModeCommands(command).name)} to the blood leak sensor', + override_text = 'Active', + logger = self.logger, + can_interface = self.can_interface) - received_message = self.can_interface.send(message) - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - else: - self.logger.debug("Invalid command!") - - @publish(['msg_id_dd_send_blood_leak_emb_mode_response', 'blood_leak_emb_mode_cmd_response', - 'dd_blood_leak_emb_mode_response_timestamp']) - def _handler_blood_leak_emb_mode_cmd_resp(self, message, timestamp=0.0): - """ - Handles published blood leak status messages. Blood leak status is captured - for reference. - - @param message: published blood leak status message - @return: None - """ - # Clear the variable for the next read - blood_leak_emb_mode_cmd_response = '' - payload = message['message'] - index = MsgFieldPositions.START_POS_FIELD_1 - cmd, index = bytearray_to_byte(payload, index, False) - length, index = bytearray_to_integer(payload, index, False) - - for i in range(0, length): - # Loop through the length and get the - char, char_index = bytearray_to_byte(payload, index + i, False) - blood_leak_emb_mode_cmd_response += chr(char) - - self.blood_leak_emb_mode_cmds[EmbModeCommands(cmd).name] = blood_leak_emb_mode_cmd_response - self.dd_blood_leak_emb_mode_response_timestamp = timestamp - def cmd_blood_leak_emb_mode_info_cmds_override(self, cmd: int, value_to_override: int, reset=NO_RESET): """ Constructs and sends the blood leak intensity override command @@ -338,26 +322,18 @@ value = integer_to_bytearray(value_to_override) index = integer_to_bytearray(EmbModeCommands(cmd).value) payload = rst + value + index - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BLOOD_LEAK_EMBEDDED_MODE_INFO_OVERRIDE_REQUEST.value, - payload=payload) - if reset == NO_RESET: - self.logger.debug("Override blood leak {} to {}".format(EmbModeCommands(cmd).name, value_to_override)) - else: - self.logger.debug("Reset override blood leak {} ".format(EmbModeCommands(cmd).name)) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BLOOD_LEAK_EMBEDDED_MODE_INFO_OVERRIDE_REQUEST, + entity_name = f'DD Blood Leak {EmbModeCommands(cmd).name}', + override_text = str(value_to_override), + logger = self.logger, + can_interface = self.can_interface) - # Send message - received_message = self.can_interface.send(message) - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - def cmd_blood_leak_intensity_moving_average_override(self, value: float, reset=NO_RESET): """ Constructs and sends the blood leak intensity moving average @@ -371,23 +347,18 @@ rst = integer_to_bytearray(reset) avg = float_to_bytearray(value) payload = rst + avg - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BLOOD_LEAK_INTENSITY_MOVING_AVERAGE_OVERRIDE_REQUEST.value, - payload=payload) - self.logger.debug("Override blood leak intensity moving average to {:5.3f}".format(value)) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BLOOD_LEAK_INTENSITY_MOVING_AVERAGE_OVERRIDE_REQUEST, + entity_name = 'DD Blood Leak Intensity Moving Average', + override_text = str(value), + logger = self.logger, + can_interface = self.can_interface) - # Send message - received_message = self.can_interface.send(message) - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - def cmd_blood_leak_zeroing_interval_in_minutes(self, upper_interval: int, value_mins: int, reset=NO_RESET): """ Constructs and sends the blood leak zeroing interval in minutes @@ -404,22 +375,13 @@ upper = integer_to_bytearray(upper_interval) payload = rst + mins + upper - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BLOOD_LEAK_ZEROING_INTERVAL_IN_MS_OVERRIDE_REQUEST.value, - payload=payload) - text = 'intensity drift' - if upper_interval == 1: - text = 'upper intensity' - - self.logger.debug("Override blood leak zeroing {} interval to {} minute(s)".format(text,mins)) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False + text = 'upper intensity' if upper_interval == 1 else 'intensity drift' + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_BLOOD_LEAK_INTENSITY_MOVING_AVERAGE_OVERRIDE_REQUEST, + entity_name = f'DD Blood Leak Zeroing {text} interval', + override_text = f'{str(value_mins)} minutes', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/concentrate_pump.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/concentrate_pump.py (.../concentrate_pump.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/concentrate_pump.py (.../concentrate_pump.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,22 +7,22 @@ # # @file concentrate_pumps.py # -# @author (last) Micahel Garthwaite -# @date (last) 07-Mar-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Micahel Garthwaite # @date (original) 29-Oct-2020 # ############################################################################ + import struct -from enum import unique from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_RESET +from leahi_dialin.common.dd_defs import DDConcentratePumpsEnum, DDConcentratePumpAttributesEnum from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions -from leahi_dialin.common.dd_defs import DDConcentratePumpsEnum, DDConcentratePumpsStates, DDConcentratePumpAttributesEnum -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.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray @@ -85,6 +85,7 @@ self.dd_concentrate_pump_timestamp = 0.0 + @publish(["msg_id_dd_conc_pump_data", "dd_concentrate_pumps", "dd_concentrate_pump_timestamp"]) def _handler_concentrate_pumps_sync(self, message, timestamp=0.0): """ @@ -94,7 +95,6 @@ @param message: published concentrate pumps' data message @return: None """ - self.dd_concentrate_pumps[DDConcentratePumpsEnum.D11_CP1_ACID.name][DDConcentratePumpAttributesEnum.CURRENT_SET_SPEED.name] = ( struct.unpack('f', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])))[0] self.dd_concentrate_pumps[DDConcentratePumpsEnum.D11_CP1_ACID.name][DDConcentratePumpAttributesEnum.MEASURED_SPEED.name] = ( @@ -148,6 +148,7 @@ self.dd_concentrate_pump_timestamp = timestamp + def cmd_concentrate_pump_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the concentrate pump data broadcast interval override command @@ -160,31 +161,16 @@ @return: 1 if successful, zero otherwise """ + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Concentrate Pump', + logger = self.logger, + can_interface = self.can_interface) - if not check_broadcast_interval_override_ms(ms): - return False - reset_byte_array = integer_to_bytearray(reset) - ms_byte_array = integer_to_bytearray(ms) - payload = reset_byte_array + ms_byte_array - - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override DD concentrate pump data broadcast interval") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_concentrate_pump_target_speed_override(self, pump_id: int, speed: float, reset: int = NO_RESET) -> int: """ Constructs and sends the concentrate pump target speed override command @@ -194,29 +180,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) speed_byte_array = float_to_bytearray(speed) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + speed_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_TARGET_SPEED_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_TARGET_SPEED_OVERRIDE_REQUEST, + entity_name = f'DD {DDConcentratePumpsEnum(pump_id).name} Concentrate Pump target speed', + override_text = str(speed), + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("override concentrate pump target speed: " + str(speed) + " - for concentrate pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_concentrate_pump_measured_speed_override(self, pump_id: int, speed: float, reset: int = NO_RESET) -> int: """ Constructs and sends the concentrate pump measured speed override command @@ -227,32 +206,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) speed_byte_array = float_to_bytearray(speed) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + speed_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_MEASURED_SPEED_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_MEASURED_SPEED_OVERRIDE_REQUEST, + entity_name = f'DD {DDConcentratePumpsEnum(pump_id).name} Concentrate Pump measured speed', + override_text = str(speed), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - self.logger.debug("reset back to normal value for concentrate pump: " + str(pump_id)) - else: - self.logger.debug("override concentrate pump measured speed: " + str(speed) + " - for concentrate pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_concentrate_pump_parked_status_override(self, pump_id: int, status: int, reset: int = NO_RESET) -> int: """ Constructs and sends the concentrate pump parked state override command @@ -263,32 +232,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) status_byte_array = integer_to_bytearray(status) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + status_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_PARKED_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_PARKED_OVERRIDE_REQUEST, + entity_name = f'DD {DDConcentratePumpsEnum(pump_id).name} Concentrate Pump parked status', + override_text = str(status), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - self.logger.debug("reset parked status back to normal for concentrate pump park status: " + str(pump_id)) - else: - self.logger.debug("override parked status to: " + str(status) + " - for concentrate pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_concentrate_pump_park_fault_state_override(self, pump_id: int, status: int, reset: int = NO_RESET) -> int: """ Constructs and sends the concentrate pump park fault state override command @@ -299,32 +258,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) status_byte_array = integer_to_bytearray(status) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + status_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_PARK_FAULT_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_PARK_FAULT_OVERRIDE_REQUEST, + entity_name = f'DD {DDConcentratePumpsEnum(pump_id).name} Concentrate Pump parked fault state', + override_text = str(status), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - self.logger.debug("reset park fault status back to normal for concentrate pump park fault: " + str(pump_id)) - else: - self.logger.debug("override park fault status to: " + str(status) + " - for concentrate pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_concentrate_pump_park_command(self, pump_id: int) -> int: """ Constructs and sends the concentrate pump park command @@ -333,26 +282,19 @@ @return: 1 if successful, zero otherwise """ - payload = integer_to_bytearray(pump_id) - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_PARK_REQUEST_OVERRIDE_REQUEST.value, - payload=payload) - self.logger.debug("park concentrate pump: " + str(pump_id)) + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONCENTRATE_PUMP_PARK_REQUEST_OVERRIDE_REQUEST, + entity_name = f'DD {DDConcentratePumpsEnum(pump_id).name} Concentrate Pump to zeroing', + override_text = 'Active', + logger = self.logger, + can_interface = self.can_interface) - # Send message - received_message = self.can_interface.send(message) - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - - def cmd_concentrate_set_start_stop(self, pump_id: int, command: int, speed: float, volume: float ) -> int: """ Constructs and sends the concentrate pump start stop command @@ -364,26 +306,18 @@ @return: 1 if successful, zero otherwise """ - pmp = integer_to_bytearray(pump_id) cmd = integer_to_bytearray(command) spd = float_to_bytearray(speed) vlm = float_to_bytearray(volume) payload = pmp + cmd + spd + vlm - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONCENTRATE_PUMPS_START_STOP_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("setting " + str(spd) + " - for concentrate pump: " + str(pump_id)) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False \ No newline at end of file + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONCENTRATE_PUMPS_START_STOP_OVERRIDE_REQUEST, + entity_name = f'DD {DDConcentratePumpsEnum(pump_id).name} Concentrate Pump speed', + override_text = str(spd), + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/conductivity_sensors.py =================================================================== diff -u -re9a1b8796610fd165c45a0a2c9c2034e00a77546 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/conductivity_sensors.py (.../conductivity_sensors.py) (revision e9a1b8796610fd165c45a0a2c9c2034e00a77546) +++ leahi_dialin/dd/modules/conductivity_sensors.py (.../conductivity_sensors.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,21 +7,22 @@ # # @file conductivity_sensors.py # -# @author (last) Dara Navaei -# @date (last) 15-May-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Quang Nguyen # @date (original) 20-Jul-2020 # ############################################################################ + import struct from logging import Logger -from leahi_dialin.common.constants import RESET, NO_RESET -from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.dd_defs import DDConductivitySensorsEnum -from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override -from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray @@ -59,6 +60,7 @@ self.dd_conductivity_timestamp = 0.0 + @publish(["msg_id_dd_conductivity_data", "dd_conductivity", "dd_conductivity_timestamp"]) def _handler_conductivity_sensors_sync(self, message, timestamp=0.0): """ @@ -68,7 +70,6 @@ @param message: published DD conductivity sensor data message @return: None """ - self.dd_conductivity[DDConductivitySensorsEnum.D17_COND.name] = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] @@ -86,6 +87,7 @@ self.dd_conductivity_timestamp = timestamp + def cmd_conductivity_sensor_data_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the conductivity sensor data broadcast interval override command @@ -97,16 +99,16 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - - cmd_generic_broadcast_interval_override( + return cmd_generic_broadcast_interval_override( ms = ms, reset = reset, channel_id = DenaliChannels.dialin_to_dd_ch_id, msg_id = MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST, - module_name = 'DD conductivity sensors', + module_name = 'DD Conductivity Sensors', logger = self.logger, can_interface = self.can_interface) + def cmd_conductivity_sensor_readings_override(self, sensor_index: int, conductivity: float, reset: int = NO_RESET) -> int: """ Constructs and sends the conductivity value override command @@ -120,34 +122,23 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) cond_byte_array = float_to_bytearray(conductivity) sensor_byte_array = integer_to_bytearray(sensor_index) payload = reset_byte_array + cond_byte_array + sensor_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_READINGS_OVERRIDE_REQUEST.value, - payload=payload) + sensor_name = DDConductivitySensorsEnum(sensor_index).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_READINGS_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Conductivity Sensor reading', + override_text = f'{str(conductivity)} microsiemens/cm', + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(conductivity) + " microsiemens/cm" - self.logger.debug("override conductivity sensor value for sensor " + DDConductivitySensorsEnum(sensor_index).name - + ": " + str_res) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_conductivity_sensor_read_counter_override(self, sensor_index: int, counter: int, reset: int = NO_RESET) -> int: """ Constructs and sends the conductivity read counter override command @@ -161,34 +152,23 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) read_byte_array = integer_to_bytearray(counter) sensor_byte_array = integer_to_bytearray(sensor_index) payload = reset_byte_array + read_byte_array + sensor_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_READ_COUNTER_OVERRIDE_REQUEST.value, - payload=payload) + sensor_name = DDConductivitySensorsEnum(sensor_index).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_READINGS_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Conductivity Sensor read counter', + override_text = str(counter), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(counter) - self.logger.debug("override conductivity sensor value for sensor " + DDConductivitySensorsEnum[str(sensor_index)].name - + ": " + str_res) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_conductivity_sensor_error_counter_override(self, sensor_index: int, counter: int, reset: int = NO_RESET) -> int: """ Constructs and sends the conductivity error count override command @@ -199,30 +179,18 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) error_byte_array = integer_to_bytearray(counter) sensor_byte_array = integer_to_bytearray(sensor_index) payload = reset_byte_array + error_byte_array + sensor_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_ERROR_COUNTER_OVERRIDE_REQUEST.value, - payload=payload) - - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(counter) - self.logger.debug("override conductivity sensor value for sensor " + DDConductivitySensorsEnum[str(sensor_index)].name - + ": " + str_res) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False \ No newline at end of file + sensor_name = DDConductivitySensorsEnum(sensor_index).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_ERROR_COUNTER_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Conductivity Sensor error counter', + override_text = str(counter), + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/dd_test_configs.py =================================================================== diff -u -r0bdafdb1821e164a8416ea4b47be946f13239b5a -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/dd_test_configs.py (.../dd_test_configs.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) +++ leahi_dialin/dd/modules/dd_test_configs.py (.../dd_test_configs.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -19,7 +19,7 @@ from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions from leahi_dialin.common.override_templates import cmd_generic_override -from leahi_dialin.common.test_config_defs import DDTestConfigOptions +from leahi_dialin.common.test_config_defs import DDFPTestConfigOptions from leahi_dialin.protocols.CAN import DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, bytearray_to_integer @@ -59,7 +59,7 @@ @param config: (int) Test config to set @return: the status of a test config """ - return self.dd_test_configs[DDTestConfigOptions(config).name] + return self.dd_test_configs[DDFPTestConfigOptions(config).name] @publish(['msg_id_dd_send_test_config', 'dd_test_configs', 'dd_test_configs_response_timestamp']) @@ -74,7 +74,7 @@ payload = message['message'] index = MsgFieldPositions.START_POS_FIELD_1 - for config in DDTestConfigOptions.__members__: + for config in DDFPTestConfigOptions.__members__: if 'NUM_OF_TEST_CONFIGS' not in config: config_value, index = bytearray_to_integer(payload, index, False) self.dd_test_configs[config] = config_value @@ -101,7 +101,7 @@ reset = reset, channel_id = DenaliChannels.dialin_to_dd_ch_id, msg_id = MsgIds.MSG_ID_DD_SET_TEST_CONFIGURATION, - entity_name = f'DD {DDTestConfigOptions(config).name} Test Config', + entity_name = f'DD {DDFPTestConfigOptions(config).name} Test Config', override_text = 'Active', logger = self.logger, can_interface = self.can_interface) @@ -119,7 +119,6 @@ @return: 1 if successful, zero otherwise """ - return cmd_generic_override( payload = None, reset = NO_RESET, @@ -139,7 +138,6 @@ @return: 1 if successful, zero otherwise """ - response = cmd_generic_override( payload = None, reset = NO_RESET, @@ -149,7 +147,7 @@ override_text = 'Active', logger = self.logger, can_interface = self.can_interface) - + # Update the stored test configs from the FW self.cmd_request_test_config_status_from_fw() return response Index: leahi_dialin/dd/modules/dialysate_pump.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/dialysate_pump.py (.../dialysate_pump.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/dialysate_pump.py (.../dialysate_pump.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,22 +7,22 @@ # # @file dialysate_pump.py # -# @author (last) Micahel Garthwaite -# @date (last) 07-Mar-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Micahel Garthwaite # @date (original) 29-Oct-2020 # ############################################################################ + import struct -from enum import unique from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_RESET +from leahi_dialin.common.dd_defs import DDDialysatePumpsEnum, DDDialysatePumpAttributesEnum from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions -from leahi_dialin.common.dd_defs import DDDialysatePumpsEnum, DDDialysatePumpAttributesEnum, DDDialysatePumpsStates -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.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray @@ -78,6 +78,7 @@ self.dd_dialysate_pump_timestamp = 0 + @publish(["msg_id_dd_dialysate_pumps_data", "dd_dialysate_pumps", "dd_dialysate_pump_timestamp",]) def _handler_dialysate_pumps_sync(self, message, timestamp=0.0): """ @@ -87,7 +88,6 @@ @param message: published dialysate pumps' data message @return: None """ - self.dd_dialysate_pumps[DDDialysatePumpsEnum.D12_PUMP.name][DDDialysatePumpAttributesEnum.TARGET_RPM.name] = ( struct.unpack('f', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])))[0] self.dd_dialysate_pumps[DDDialysatePumpsEnum.D48_PUMP.name][DDDialysatePumpAttributesEnum.TARGET_RPM.name] = ( @@ -140,6 +140,7 @@ self.dd_dialysate_pump_timestamp = timestamp + def cmd_dialysate_pump_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the dialysate pump data broadcast interval override command @@ -151,31 +152,16 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Dialysate Pump', + logger = self.logger, + can_interface = self.can_interface) - if not check_broadcast_interval_override_ms(ms): - return False - reset_byte_array = integer_to_bytearray(reset) - ms_byte_array = integer_to_bytearray(ms) - payload = reset_byte_array + ms_byte_array - - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override DD dialysate pump data broadcast interval") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_dialysate_pump_target_speed_override(self, pump_id: int, speed: float, reset: int = NO_RESET) -> int: """ Constructs and sends the dialysate pump target speed override command @@ -186,29 +172,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) speed_byte_array = float_to_bytearray(speed) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + speed_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_TARGET_SPEED_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_TARGET_SPEED_OVERRIDE_REQUEST, + entity_name = f'DD {DDDialysatePumpsEnum(pump_id).name} Dialysate Pump target speed', + override_text = str(speed), + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("override target speed: " + str(speed) + " - for pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_dialysate_pump_measured_speed_override(self, pump_id: int, speed: float, reset: int = NO_RESET) -> int: """ Constructs and sends the dialysate pump target speed override command @@ -219,29 +198,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) speed_byte_array = float_to_bytearray(speed) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + speed_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_MEASURED_SPEED_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_MEASURED_SPEED_OVERRIDE_REQUEST, + entity_name = f'DD {DDDialysatePumpsEnum(pump_id).name} Dialysate Pump measured speed', + override_text = str(speed), + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("override target speed: " + str(speed) + " - for pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_dialysate_pump_target_pressure_override(self, pump_id: int, pressure: float, reset: int = NO_RESET) -> int: """ Constructs and sends the dialysate pump target speed override command @@ -252,29 +224,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) pressure_byte_array = float_to_bytearray(pressure) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + pressure_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_TARGET_PRESSURE_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_TARGET_PRESSURE_OVERRIDE_REQUEST, + entity_name = f'DD {DDDialysatePumpsEnum(pump_id).name} Dialysate Pump target pressure', + override_text = str(pressure), + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("override target speed: " + str(pressure) + " - for pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_dialysate_pump_measured_current_override(self, pump_id: int, current: float, reset: int = NO_RESET) -> int: """ Constructs and sends the dialysate pump measured current override command @@ -285,29 +250,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) current_byte_array = float_to_bytearray(current) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + current_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_MEASURED_CURRENT_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_MEASURED_CURRENT_OVERRIDE_REQUEST, + entity_name = f'DD {DDDialysatePumpsEnum(pump_id).name} Dialysate Pump measured current', + override_text = str(current), + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("override target speed: " + str(current) + " - for pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_dialysate_pump_measured_direction_override(self, pump_id: int, direction: float, reset: int = NO_RESET) -> int: """ Constructs and sends the dialysate pump measured direction override command @@ -318,29 +276,22 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) direction_byte_array = float_to_bytearray(direction) pump_id_byte_array = integer_to_bytearray(pump_id) payload = reset_byte_array + direction_byte_array + pump_id_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_MEASURED_DIRECTION_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_MEASURED_DIRECTION_OVERRIDE_REQUEST, + entity_name = f'DD {DDDialysatePumpsEnum(pump_id).name} Dialysate Pump measured direction', + override_text = str(direction), + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("override target speed: " + str(direction) + " - for pump: " + str(pump_id)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_dialysate_set_start_stop(self, pump_id: int, command: int, speed: int, control: int ) -> int: """ Constructs and sends the dialysate pump start stop command @@ -351,26 +302,18 @@ @return: 1 if successful, zero otherwise """ - pmp = integer_to_bytearray(pump_id) cmd = integer_to_bytearray(command) rpm = integer_to_bytearray(speed) ctl = integer_to_bytearray(control) payload = pmp + cmd + rpm + ctl - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_START_STOP_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("setting " + str(cmd) + " - for pump: " + str(pump_id)) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False \ No newline at end of file + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_DIALYSATE_PUMPS_START_STOP_OVERRIDE_REQUEST, + entity_name = f'DD {DDDialysatePumpsEnum(pump_id).name} Dialysate Pump start & stop', + override_text = str(cmd), + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/events.py =================================================================== diff -u -r7d9d004527efeccb91958b440abdff08c2c52648 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/events.py (.../events.py) (revision 7d9d004527efeccb91958b440abdff08c2c52648) +++ leahi_dialin/dd/modules/events.py (.../events.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,23 +7,29 @@ # # @file events.py # -# @author (last) Jonny Paguio -# @date (last) 15-Sep-2025 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Dara Navaei # @date (original) 12-Oct-2021 # ############################################################################ import struct from logging import Logger -from leahi_dialin.common import * +from datetime import datetime +from time import time + +from leahi_dialin.common.dd_defs import DDEventList, DDEventDataType, DDOpModes, DDFaultStates, \ + DDServiceModesStates, DDInitStates, DDStandByModeStates, DDPreGenDialysateStates, \ + DDGenDialysateModeStates, DDPostGenDialysateState, DDHeatersState, DDHeatersCoolingStates, \ + DDROPermeateStates, DDNotLegalStates from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions from leahi_dialin.protocols.CAN import DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish -from datetime import datetime -from time import time + + class DDEvents(AbstractSubSystem): """ Dialysate Delivery (DD) Dialin API sub-class for events related commands. @@ -35,7 +41,6 @@ @param can_interface: Denali CAN Messenger object """ - super().__init__() self.can_interface = can_interface self.logger = logger @@ -92,6 +97,7 @@ self._dd_event_data_type[event_data_type] = struct_unpack_type + def get_dd_nth_event(self, event_id, event_number=0): """ Returns the nth requested DD event @@ -112,6 +118,7 @@ return event + def clear_dd_event_list(self): """ Clears the DD event list @@ -121,6 +128,7 @@ for key in self._dd_event_dictionary: self._dd_event_dictionary[key].clear() + def get_dd_events(self, event_id, number_of_events=1): """ Returns the requested number of a certain DD event ID @@ -148,6 +156,7 @@ return list_of_events + @publish(["msg_id_dd_event", "dd_events_timestamp", '_dd_event_dictionary']) def _handler_events_sync(self, message, timestamp=0.0): """ @@ -287,6 +296,7 @@ self._dd_event_dictionary[event_state_name].append(event_tuple) self.dd_events_timestamp = timestamp + @publish(["msg_id_dd_op_mode_data", "dd_event_op_mode_timestamp", "dd_event_op_mode", "dd_event_sub_mode"]) def _handler_dd_op_mode_sync(self, message, timestamp=0.0): """ @@ -296,12 +306,11 @@ @param message: published DD operation mode broadcast message @return: None """ - mode = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) smode = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) self.dd_event_op_mode = mode[0] self.dd_event_sub_mode = smode[0] - self.dd_event_op_mode_timestamp = timestamp \ No newline at end of file + self.dd_event_op_mode_timestamp = timestamp Index: leahi_dialin/dd/modules/gen_dialysate.py =================================================================== diff -u -r0bdafdb1821e164a8416ea4b47be946f13239b5a -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/gen_dialysate.py (.../gen_dialysate.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) +++ leahi_dialin/dd/modules/gen_dialysate.py (.../gen_dialysate.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -50,12 +50,6 @@ self.execution_state = 0 self.dialysate_delivery_in_progress = 0 - self.d6_level = 0 - self.d63_level = 0 - self.d46_level = 0 - self.d9_pressure = 0.0 - self.d18_pressure = 0.0 - self.d51_pressure = 0.0 self.dialysate_good_to_deliver = 0 self.targetQd = 0.0 self.dd_gen_dialysate_timestamp = 0 @@ -77,27 +71,14 @@ @param message: published gen dialysate data message @return: None """ - self.execution_state = struct.unpack('I', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.dialysate_delivery_in_progress = struct.unpack('I', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] - self.d6_level = struct.unpack('I', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] - self.d63_level = struct.unpack('I', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] - self.d46_level = struct.unpack('I', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] - self.d9_pressure = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] - self.d18_pressure = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] - self.d51_pressure = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8]))[0] self.dialysate_good_to_deliver = struct.unpack('I', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_9:MsgFieldPositions.END_POS_FIELD_9]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] self.targetQd = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_10:MsgFieldPositions.END_POS_FIELD_10]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] self.dd_gen_dialysate_timestamp = timestamp @@ -112,7 +93,6 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - return cmd_generic_broadcast_interval_override( ms = ms, reset = reset, @@ -132,7 +112,6 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) inprog = integer_to_bytearray(in_progress) payload = reset_byte_array + inprog @@ -157,7 +136,6 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) dev = integer_to_bytearray(delivery) payload = reset_byte_array + dev @@ -182,7 +160,6 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) tmp = float_to_bytearray(temperature) payload = reset_byte_array + tmp @@ -207,7 +184,6 @@ @return: 1 if successful, zero otherwise """ - sts = integer_to_bytearray(state) payload = sts @@ -231,7 +207,6 @@ @return: 1 if successful, zero otherwise """ - reset_value = integer_to_bytearray(reset) interval_value = integer_to_bytearray(state) payload = reset_value + interval_value Index: leahi_dialin/dd/modules/heaters.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/heaters.py (.../heaters.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/heaters.py (.../heaters.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,23 +7,22 @@ # # @file heaters.py # -# @author (last) Michael Garthwaite -# @date (last) 28-Oct-2024 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Dara Navaei # @date (original) 29-May-2020 # ############################################################################ import struct -from enum import unique from logging import Logger -from .constants import NO_RESET +from leahi_dialin.common.constants import NO_RESET +from leahi_dialin.common.dd_defs import DDHeatersNames, DDHeatersAttributesEnum from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions -from leahi_dialin.common.dd_defs import DDHeatersStartStop, DDHeatersState, DDHeatersNames, DDHeatersAttributesEnum -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.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray @@ -38,7 +37,6 @@ @param can_interface: Denali CAN Messenger object """ - super().__init__() self.can_interface = can_interface @@ -83,6 +81,7 @@ self.msg_id_dd_heaters_data = MsgIds.MSG_ID_DD_HEATERS_DATA.value self.can_interface.register_receiving_publication_function(channel_id, self.msg_id_dd_heaters_data, self._handler_heaters_sync) + @publish(["msg_id_dd_heaters_data", "dd_heaters", "dbg1", "dbg2", "dbg3", "dbg4", "dbg5", "dbg6", "dbg7", "dbg8", "dbg9", "dd_heaters_timestamp"]) @@ -135,6 +134,7 @@ self.dd_heaters_timestamp = timestamp + def cmd_heaters_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends broadcast time interval. @@ -146,29 +146,16 @@ @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 + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_HEATERS_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Heaters', + logger = self.logger, + can_interface = self.can_interface) - 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_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_HEATERS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("Sending {} ms publish interval to the Heaters 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 - def cmd_heater_duty_cycle_override(self, heater: int, duty_cycle: float, reset: int = NO_RESET) -> int: """ Constructs and sends heater duty cycle override command @@ -179,25 +166,22 @@ @param reset: (int) 1 to reset a previous override, 0 to override @returns 1 if successful, zero otherwise """ - reset_value = integer_to_bytearray(reset) - heater_name = integer_to_bytearray(heater) + rst = integer_to_bytearray(reset) + htr = integer_to_bytearray(heater) duty = float_to_bytearray(duty_cycle/100) - payload = reset_value + duty + heater_name - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_HEATERS_DUTY_CYCLE_OVERRIDE_REQUEST.value, - payload=payload) + payload = rst + duty + htr - self.logger.debug("Overriding {} heater's duty cycle to {:5.3f} %".format(DDHeatersNames(heater).name, duty_cycle)) - # Send message - received_message = self.can_interface.send(message) + heater_name = DDHeatersNames(heater).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_HEATERS_DUTY_CYCLE_OVERRIDE_REQUEST, + entity_name = f'DD {heater_name} Heaters Duty Cycle', + override_text = str(duty_cycle), + logger = self.logger, + can_interface = self.can_interface) - # 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 def cmd_heater_start_stop_override(self, heater: int, command: int, temperature: float) -> int: """ @@ -214,21 +198,19 @@ tmp = float_to_bytearray(temperature) payload = htr + cmd + tmp - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_HEATERS_START_STOP_OVERRIDE_REQUEST.value, - payload=payload) + heater_name = DDHeatersNames(heater).name.split('_')[0] + start_or_stop = 'Start' if command == 0 else 'Stop' + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_HEATERS_START_STOP_OVERRIDE_REQUEST, + entity_name = f'DD {heater_name} Heaters {start_or_stop} temperature', + override_text = str(temperature), + logger = self.logger, + can_interface = self.can_interface) - # 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 - def cmd_heater_target_temperature_override(self, heater: int, temperature: float, reset: int) -> int: """ Constructs and sends heater set target temperture override @@ -243,22 +225,18 @@ rst = integer_to_bytearray(reset) payload = rst + tmp + htr - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_HEATERS_TARGET_TEMPERATURE_OVERRIDE_REQUEST.value, - payload=payload) + heater_name = DDHeatersNames(heater).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_HEATERS_TARGET_TEMPERATURE_OVERRIDE_REQUEST, + entity_name = f'DD {heater_name} Heaters target temperature', + override_text = str(temperature), + logger = self.logger, + can_interface = self.can_interface) - # 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 - - def cmd_heater_pwm_period_override(self, heater: int, period: float, reset: int) -> int: """ Constructs and sends heater pwm period override @@ -273,17 +251,13 @@ rst = integer_to_bytearray(reset) payload = rst + prd + htr - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_HEATERS_PWM_PERIOD_OVERRIDE_REQUEST.value, - payload=payload) - - # 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 + heater_name = DDHeatersNames(heater).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_HEATERS_PWM_PERIOD_OVERRIDE_REQUEST, + entity_name = f'DD {heater_name} Heaters PWM period', + override_text = str(period), + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/levels.py =================================================================== diff -u -r809b92241a33a60e8b04968b2484deed871f6f69 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/levels.py (.../levels.py) (revision 809b92241a33a60e8b04968b2484deed871f6f69) +++ leahi_dialin/dd/modules/levels.py (.../levels.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,8 +7,8 @@ # # @file levels.py # -# @author (last) Michael Garthwaite -# @date (last) 28-Oct-2024 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Dara Navaei # @date (original) 29-May-2020 # @@ -18,10 +18,10 @@ from logging import Logger from leahi_dialin.common.constants import NO_RESET -from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions from leahi_dialin.common.dd_defs import DDLevelSensorEnum -from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override -from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray @@ -79,6 +79,7 @@ self.dd_levels_timestamp = timestamp + def cmd_levels_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends dd levels broadcast time interval override. @@ -90,15 +91,16 @@ @param reset: (int) 1 to reset a previous override, 0 to override @returns 1 if successful, zero otherwise """ - cmd_generic_broadcast_interval_override( + return cmd_generic_broadcast_interval_override( ms = ms, reset = reset, channel_id = DenaliChannels.dialin_to_dd_ch_id, msg_id = MsgIds.MSG_ID_DD_LEVELS_PUBLISH_INTERVAL_OVERRIDE_REQUEST, - module_name = 'DD level sensors', + module_name = 'DD Levels', logger = self.logger, can_interface = self.can_interface) - + + def cmd_level_status_override(self, level_sensor: int, status: int, reset: int = NO_RESET) -> int: """ Constructs and sends level status cycle override command @@ -113,16 +115,14 @@ level_sensor = integer_to_bytearray(level_sensor) sts = integer_to_bytearray(status) payload = reset_value + sts + level_sensor - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_LEVELS_STATUS_OVERRIDE_REQUEST.value, - payload=payload) - 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 + sensor_name = DDLevelSensorEnum(level_sensor).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_LEVELS_STATUS_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Level Status', + override_text = str(status), + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/post_gen_dialysate.py =================================================================== diff -u -r6fa8a72c463310fd943270135aebfcb10d7a1210 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/post_gen_dialysate.py (.../post_gen_dialysate.py) (revision 6fa8a72c463310fd943270135aebfcb10d7a1210) +++ leahi_dialin/dd/modules/post_gen_dialysate.py (.../post_gen_dialysate.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,23 +7,23 @@ # # @file post_gen_dialysate.py # -# @author (last) Micahel Garthwaite -# @date (last) 07-Mar-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Micahel Garthwaite # @date (original) 29-Oct-2020 # ############################################################################ + import struct -from enum import unique from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_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 +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish + class DDPostGenDialysate(AbstractSubSystem): """ Post Gen Dialysate @@ -50,6 +50,7 @@ self.execution_state = 0 self.post_gen_state_timestamp = 0 + @publish(["msg_id_dd_post_gen_dialysate_state_data", "execution_state", "post_gen_state_timestamp"]) def _handler_post_gen_dialysate_sync(self, message, timestamp=0.0): """ @@ -58,12 +59,12 @@ @param message: published post gen dialysate data message @return: None """ - self.execution_state = struct.unpack('I', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.post_gen_state_timestamp = timestamp + def cmd_post_gen_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the broadcast time interval override for post gen dialysate data. @@ -75,25 +76,11 @@ @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_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_POST_GEND_MODE_DATA_PUBLISH_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("Sending {} ms publish interval to the Post-Gen 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 + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_POST_GEND_MODE_DATA_PUBLISH_OVERRIDE_REQUEST, + module_name = 'DD Post-Gen Dialysate', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/pre_gen_dialysate.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/pre_gen_dialysate.py (.../pre_gen_dialysate.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/pre_gen_dialysate.py (.../pre_gen_dialysate.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,23 +7,23 @@ # # @file pre_gen_dialysate.py # -# @author (last) Micahel Garthwaite -# @date (last) 07-Mar-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Micahel Garthwaite # @date (original) 29-Oct-2020 # ############################################################################ + import struct -from enum import unique from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_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 +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish + class DDPreGenDialysate(AbstractSubSystem): """ Pre Gen Dialysate @@ -62,6 +62,7 @@ self.pre_gen_acid = 0 self.pre_gen_bicarb = 0 + @publish(["msg_id_dd_pre_gen_dialysate_state_data", "execution_state", "pre_gen_state_timestamp"]) def _handler_pre_gen_state_sync(self, message, timestamp=0.0): """ @@ -70,12 +71,12 @@ @param message: published pre gen dialysate data message @return: None """ - self.execution_state = struct.unpack('I', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.pre_gen_state_timestamp = timestamp + @publish(["msg_id_dd_pre_gen_dialysate_request_data", "pre_gen_start", "pre_gen_dial_rate", "pre_gen_dial_temp", "pre_gen_acid", "pre_gen_bicarb", @@ -87,7 +88,6 @@ @param message: published pre gen dialysate request message @return: None """ - self.pre_gen_start = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.pre_gen_dial_rate = struct.unpack('f', bytearray( @@ -101,6 +101,7 @@ self.pre_gen_request_timestamp = timestamp + def cmd_pre_gen_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the broadcast time interval override for pre gen dialysate data. @@ -112,25 +113,11 @@ @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_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_PRE_GEND_MODE_DATA_PUBLISH_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("Sending {} ms publish interval to the Pre-Gen 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 + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_PRE_GEND_MODE_DATA_PUBLISH_OVERRIDE_REQUEST, + module_name = 'DD Pre-Gen Dialysate', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/pressure_sensors.py =================================================================== diff -u -rd2697fb12fc381fed6e7fb0820ec6486513243f6 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/pressure_sensors.py (.../pressure_sensors.py) (revision d2697fb12fc381fed6e7fb0820ec6486513243f6) +++ leahi_dialin/dd/modules/pressure_sensors.py (.../pressure_sensors.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,21 +7,22 @@ # # @file pressure_sensors.py # -# @author (last) Micahel Garthwaite -# @date (last) 07-Mar-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Sean # @date (original) 14-Apr-2020 # ############################################################################ + import struct from logging import Logger -from leahi_dialin.common.constants import NO_RESET, RESET -from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.dd_defs import DDPressureNames -from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override -from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray @@ -59,6 +60,7 @@ self.dd_pressures_timestamp = 0 + @publish(["msg_id_dd_pressures_data", "dd_pressures", "dd_pressures_timestamp"]) def _handler_pressures_sync(self, message,timestamp=0.0): """ @@ -83,6 +85,7 @@ self.dd_pressures_timestamp = timestamp + def cmd_pressure_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the pressure broadcast interval override command. @@ -95,16 +98,16 @@ @return: 1 if successful, zero otherwise """ - - cmd_generic_broadcast_interval_override( + return cmd_generic_broadcast_interval_override( ms = ms, reset = reset, channel_id = DenaliChannels.dialin_to_dd_ch_id, msg_id = MsgIds.MSG_ID_DD_PRESSURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST, - module_name = 'DD pressure sensors', + module_name = 'DD Pressure Sensors', logger = self.logger, can_interface = self.can_interface) + def cmd_pressure_readings_override(self, sensor: int, pressure: float, reset: int = NO_RESET) -> int: """ Constructs and sends the pressure readings override command. @@ -116,29 +119,23 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) prs = float_to_bytearray(pressure) idx = integer_to_bytearray(sensor) payload = rst + prs + idx - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_PRESSURE_SENSOR_READINGS_OVERRIDE_REQUEST.value, - payload=payload) + sensor_name = DDPressureNames(sensor).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_PRESSURE_SENSOR_READINGS_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Pressure Sensors pressure', + override_text = f'{str(pressure)} psi', + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("override pressure reading") - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - def cmd_pressure_sensor_read_counter_override(self, sensor: int, counter: int, reset: int = NO_RESET) -> int: """ Constructs and sends the pressure sensor read counter override command @@ -151,33 +148,23 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) read_byte_array = integer_to_bytearray(counter) sensor_byte_array = integer_to_bytearray(sensor) payload = reset_byte_array + read_byte_array + sensor_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_PRESSURE_SENSOR_READ_COUNTER_OVERRIDE_REQUEST.value, - payload=payload) + sensor_name = DDPressureNames(sensor).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_PRESSURE_SENSOR_READ_COUNTER_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Pressure Sensors read counter', + override_text = str(counter), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(sensor) + " psi" - self.logger.debug("override read counter value for pressure sensor " + str(sensor) + ": " + str_res) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_pressure_sensor_error_counter_override(self, sensor: int, counter: int, reset: int = NO_RESET) -> int: """ Constructs and sends the pressure sensor error counter override command. @@ -190,33 +177,23 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) error_byte_array = integer_to_bytearray(counter) sensor_byte_array = integer_to_bytearray(sensor) payload = reset_byte_array + error_byte_array + sensor_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_PRESSURE_SENSOR_ERROR_COUNTER_OVERRIDE_REQUEST.value, - payload=payload) + sensor_name = DDPressureNames(sensor).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_PRESSURE_SENSOR_ERROR_COUNTER_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Pressure Sensors error counter', + override_text = str(counter), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(sensor) + " psi" - self.logger.debug("override error counter value for pressure sensor " + str(sensor) + ": " + str_res) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_pressure_filtered_readings_override(self, sensor: int, pressure: float, reset: int = NO_RESET) -> int: """ Constructs and sends the pressure filtered readings override command. @@ -228,25 +205,18 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) prs = float_to_bytearray(pressure) idx = integer_to_bytearray(sensor) payload = rst + prs + idx - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_PRESSURE_SENSOR_FILTER_READINGS_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override pressure reading") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False \ No newline at end of file + sensor_name = DDPressureNames(sensor).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_PRESSURE_SENSOR_FILTER_READINGS_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Pressure Sensors filtered pressure', + override_text = f'{str(pressure)} psi', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/rinse_pump.py =================================================================== diff -u -r0a01371d0edb6d84a3b086ef229f38e080519530 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/rinse_pump.py (.../rinse_pump.py) (revision 0a01371d0edb6d84a3b086ef229f38e080519530) +++ leahi_dialin/dd/modules/rinse_pump.py (.../rinse_pump.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,22 +7,24 @@ # # @file rinse_pump.py # -# @author (last) Jonny Paguio -# @date (last) 13-Oct-2025 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Jonny Paguio # @date (original) 13-Oct-2025 # ############################################################################ + import struct from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_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.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray + class DDRinsePump(AbstractSubSystem): """ Rinse Pump @@ -51,6 +53,7 @@ self.d79_pump_rpm = 0 self.dd_rinse_pump_timestamp = 0 + @publish(["msg_id_dd_rinse_pump_data", "d79_state", "d79_pump_pwm", "d79_pump_rpm", "dd_rinse_pump_timestamp"]) @@ -61,7 +64,6 @@ @param message: published rinse pump data message @return: None """ - self.d79_state = struct.unpack('I', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.d79_pump_pwm = struct.unpack('f', bytearray( @@ -71,6 +73,7 @@ self.dd_rinse_pump_timestamp = timestamp + def cmd_rinse_pump_data_publish_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the rinse pump data publish interval override command @@ -82,31 +85,16 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_RINSE_PUMP_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Rinse Pump', + logger = self.logger, + can_interface = self.can_interface) - if not check_broadcast_interval_override_ms(ms): - return False - reset_byte_array = integer_to_bytearray(reset) - ms_byte_array = integer_to_bytearray(ms) - payload = reset_byte_array + ms_byte_array - - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_RINSE_PUMP_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override DD Rinse Pump data publish interval") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_rinse_pump_pwm_percent_override(self, pwm_pct: float, reset: int = NO_RESET) -> int: """ Constructs and sends the rinse pump PWM override request @@ -118,28 +106,21 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) float_pct_byte_array = float_to_bytearray(pwm_pct) payload = reset_byte_array + float_pct_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_RINSE_PUMP_PWM_PERCENT_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_RINSE_PUMP_PWM_PERCENT_OVERRIDE_REQUEST, + entity_name = f'DD Rinse Pump PWM', + override_text = str(pwm_pct), + logger = self.logger, + can_interface = self.can_interface) + - self.logger.debug("Override DD Rinse Pump PWM to {}%.".format(pwm_pct)) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_rinse_pump_on_off_request(self, on_off: int) -> int: """ Constructs and sends the rinse pump On/Off request @@ -150,23 +131,15 @@ @param on_off: integer - On/Off value @return: 1 if successful, zero otherwise """ - on_off_byte_array = integer_to_bytearray(on_off) payload = on_off_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_RINSE_PUMP_TURN_ON_OFF_REQUEST.value, - payload=payload) - - self.logger.debug("Setting DD Rinse Pump to {}".format(on_off)) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_RINSE_PUMP_TURN_ON_OFF_REQUEST, + entity_name = f'DD Rinse Pump state', + override_text = 'On' if on_off == 1 else 'Off', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/spent_chamber_fill.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/spent_chamber_fill.py (.../spent_chamber_fill.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/spent_chamber_fill.py (.../spent_chamber_fill.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,22 +7,23 @@ # # @file spent_chamber_fill.py # -# @author (last) Jonny Paguio -# @date (last) 26-Aug-2025 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Jonny Paguio # @date (original) 26-Aug-2025 # ############################################################################ + import struct from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_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 +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish + class DDSpentChamberFill(AbstractSubSystem): """ Spent Chamber Fill @@ -50,6 +51,7 @@ self.total_spent_chamber_fill_counter = 0 self.dd_spent_chamber_timestamp = 0 + @publish(["msg_id_dd_spent_chamber_fill_data", "execution_state", "switching_period", "total_spent_chamber_fill_counter", @@ -61,7 +63,6 @@ @param message: published spent chamber fill data message @return: None """ - self.execution_state = struct.unpack('I', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.switching_period = struct.unpack('I', bytearray( @@ -71,6 +72,7 @@ self.dd_spent_chamber_timestamp = timestamp + def cmd_spent_chamber_fill_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the spent chamber fill data broadcast interval override command @@ -82,27 +84,11 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - - if not check_broadcast_interval_override_ms(ms): - return False - - reset_byte_array = integer_to_bytearray(reset) - ms_byte_array = integer_to_bytearray(ms) - payload = reset_byte_array + ms_byte_array - - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_SPENT_CHAMB_FILL_DATA_PUBLISH_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override DD Spent Chamber Fill data broadcast interval") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False \ No newline at end of file + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_SPENT_CHAMB_FILL_DATA_PUBLISH_OVERRIDE_REQUEST, + module_name = 'DD Spent Chamber Fill', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/temperature_sensors.py =================================================================== diff -u -r5681154cdaaf629c997dc05472657bf40c94d6e1 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/temperature_sensors.py (.../temperature_sensors.py) (revision 5681154cdaaf629c997dc05472657bf40c94d6e1) +++ leahi_dialin/dd/modules/temperature_sensors.py (.../temperature_sensors.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,28 +7,27 @@ # # @file temperature_sensors.py # -# @author (last) Micahel Garthwaite -# @date (last) 28-Jul-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Dara Navaei # @date (original) 01-Dec-2021 # ############################################################################ + import struct from logging import Logger -from leahi_dialin.common.constants import NO_RESET, RESET -from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.dd_defs import COND_SENSOR_INDEX_OFFSET, PRES_SENSOR_INDEX_OFFSET, DDTemperaturesNames -from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override -from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray class DDTemperatureSensors(AbstractSubSystem): - - def __init__(self, can_interface, logger: Logger): super().__init__() @@ -68,6 +67,7 @@ self.can_interface.register_receiving_publication_function(channel_id, self.msg_id_dd_temperature_data, self._handler_temperature_sensors_sync) + @publish(["msg_id_dd_temperature_data", "dd_temperatures", "dd_temperatures_timestamp"]) def _handler_temperature_sensors_sync(self, message,timestamp=0.0): """ @@ -145,6 +145,7 @@ self.dd_temperatures_timestamp = timestamp + def cmd_temperatures_data_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends broadcast time interval. @@ -156,12 +157,12 @@ @param reset: (int) 1 to reset a previous override, 0 to override @returns 1 if successful, zero otherwise """ - cmd_generic_broadcast_interval_override( + return cmd_generic_broadcast_interval_override( ms = ms, reset = reset, channel_id = DenaliChannels.dialin_to_dd_ch_id, msg_id = MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST, - module_name = 'DD temperature sensors', + module_name = 'DD Temperature Sensors', logger = self.logger, can_interface = self.can_interface) @@ -179,45 +180,34 @@ @returns 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) - value = float_to_bytearray(sensor_value) - # DD Conductivity Sensors' Temperature Reading Override if DDTemperaturesNames.D16_TEMP.value <= sensor_index <= DDTemperaturesNames.D99_TEMP.value: index = integer_to_bytearray((sensor_index - COND_SENSOR_INDEX_OFFSET)) - payload = rst + value + index - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_TEMPERATURE_OVERRIDE_REQUEST.value, - payload=payload) - + message_id = MsgIds.MSG_ID_DD_CONDUCTIVITY_SENSOR_TEMPERATURE_OVERRIDE_REQUEST # DD Pressure Sensors' Temperature Reading Override elif DDTemperaturesNames.D9_TEMP.value <= sensor_index < DDTemperaturesNames.NUM_OF_TEMP_SENSORS.value: index = integer_to_bytearray((sensor_index - PRES_SENSOR_INDEX_OFFSET)) - payload = rst + value + index - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_PRESSURE_SENSOR_TEMPERATURE_OVERRIDE_REQUEST.value, - payload=payload) - + message_id = MsgIds.MSG_ID_DD_PRESSURE_SENSOR_TEMPERATURE_OVERRIDE_REQUEST # DD Temperature Sensors' Temperature Reading Override else: index = integer_to_bytearray(sensor_index) - payload = rst + value + index - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_MEASURED_TEMPERATURE_OVERRIDE_REQUEST.value, - payload=payload) + message_id = MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_MEASURED_TEMPERATURE_OVERRIDE_REQUEST - self.logger.debug("Setting sensor {} to {} C".format(DDTemperaturesNames(sensor_index).name, sensor_value)) + rst = integer_to_bytearray(reset) + value = float_to_bytearray(sensor_value) + payload = rst + value + index - # Send message - received_message = self.can_interface.send(message) + sensor_name = DDTemperaturesNames(sensor_index).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = message_id, + entity_name = f'DD {sensor_name} Temperature Sensor temperature', + override_text = f'{str(sensor_value)} Celsius', + logger = self.logger, + can_interface = self.can_interface) - # 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 def cmd_temperature_sensor_read_counter_override(self, sensor: int, counter: int, reset: int = NO_RESET) -> int: """ @@ -229,33 +219,23 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) read_byte_array = integer_to_bytearray(counter) sensor_byte_array = integer_to_bytearray(sensor) payload = reset_byte_array + read_byte_array + sensor_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_READ_COUNTER_OVERRIDE_REQUEST.value, - payload=payload) + sensor_name = DDTemperaturesNames(sensor).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_READ_COUNTER_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Temperature Sensor read counter', + override_text = str(counter), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(counter) + " celsius" - self.logger.debug("override read counter for temperature sensor " + str(sensor) + ": " + str_res) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_baro_sensor_read_counter_override(self, counter: int, reset: int = NO_RESET) -> int: """ Constructs and sends the barometer sensor read counter override command @@ -265,32 +245,21 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) read_byte_array = integer_to_bytearray(counter) payload = reset_byte_array + read_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_BARO_READ_COUNTER_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_BARO_READ_COUNTER_OVERRIDE_REQUEST, + entity_name = f'DD Barometer Sensor read counter', + override_text = str(counter), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(counter) - self.logger.debug("override baro sensor value for sensor " + ": " + str_res) - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_baro_sensor_crc_override(self, crc: int, reset: int = NO_RESET) -> int: """ Constructs and sends the barometer sensor CRC override command @@ -300,26 +269,21 @@ @return: 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) read_byte_array = integer_to_bytearray(crc) payload = reset_byte_array + read_byte_array - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_BARO_CRC_OVERRIDE_REQUEST.value, - payload=payload) + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_TEMPERATURE_SENSOR_BARO_CRC_OVERRIDE_REQUEST, + entity_name = f'DD Barometer Sensor CRC', + override_text = str(crc), + logger = self.logger, + can_interface = self.can_interface) - # Send message - received_message = self.can_interface.send(message) - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False - def cmd_pressure_filtered_temperature_override(self, sensor: int, temperature: float, reset: int = NO_RESET) -> int: """ Constructs and sends the filtered temperature override command. @@ -331,25 +295,18 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) tmp = float_to_bytearray(temperature) idx = integer_to_bytearray(sensor - PRES_SENSOR_INDEX_OFFSET) payload = rst + tmp + idx - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_PRESSURE_SENSOR_FILTER_TEMPERATURE_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override pressure sensor filtered temperature") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False \ No newline at end of file + sensor_name = DDTemperaturesNames(sensor).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_PRESSURE_SENSOR_FILTER_TEMPERATURE_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} Temperature Sensor filtered temperature', + override_text = f'{str(temperature)} Celsius', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/ultrafiltration.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/ultrafiltration.py (.../ultrafiltration.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/ultrafiltration.py (.../ultrafiltration.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,23 +7,23 @@ # # @file ultrafiltration.py # -# @author (last) Micahel Garthwaite -# @date (last) 07-Mar-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Micahel Garthwaite # @date (original) 29-Oct-2020 # ############################################################################ + import struct -from enum import unique from logging import Logger -from .constants import RESET, NO_RESET +from leahi_dialin.common.constants import NO_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 +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override +from leahi_dialin.protocols.CAN import DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish + class DDUltrafiltration(AbstractSubSystem): """ Ultrafiltration @@ -53,6 +53,7 @@ self.is_uf_requested = 0 self.uf_timestamp = 0.0 + @publish(["msg_id_dd_uf_data", "uf_exec_state","uf_rate", "compensated_uf_rate", "is_uf_requested", "uf_timestamp"]) @@ -63,7 +64,6 @@ @param message: published ultrafiltration data message @return: None """ - self.uf_exec_state = struct.unpack('I', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.uf_rate = struct.unpack('f', bytearray( @@ -75,6 +75,7 @@ self.uf_timestamp = timestamp + def cmd_uf_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the broadcast time interval override for ultrafiltration data. @@ -86,25 +87,11 @@ @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_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_UF_DATA_PUBLISH_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("Sending {} ms publish interval to the Ultrafiltration 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 + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_UF_DATA_PUBLISH_OVERRIDE_REQUEST, + module_name = 'DD Ultrafiltration', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/valves.py =================================================================== diff -u -ra5b82c620e6a54f2b8559c54ffaa1a84e831d88e -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/valves.py (.../valves.py) (revision a5b82c620e6a54f2b8559c54ffaa1a84e831d88e) +++ leahi_dialin/dd/modules/valves.py (.../valves.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -7,8 +7,8 @@ # # @file valves.py # -# @author (last) Micahel Garthwaite -# @date (last) 17-Aug-2023 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Peman Montazemi # @date (original) 19-May-2020 # @@ -19,11 +19,12 @@ from collections import OrderedDict from leahi_dialin.common.constants import NO_RESET -from leahi_dialin.common.msg_defs import MsgIds from leahi_dialin.common.dd_defs import DDValveNames -from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override +from leahi_dialin.common.msg_defs import MsgIds +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish +from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray # Valve states @@ -51,7 +52,6 @@ @param can_interface: Denali CAN Messenger object """ - super().__init__() self.can_interface = can_interface self.logger = logger @@ -106,6 +106,7 @@ for valve in DDValveNames.__members__: self.valves_sensed_states[valve] = '' + def get_valve_states(self): """ Gets the valve states @@ -149,6 +150,7 @@ self.spare7_valv.get("state", None) ] + @staticmethod def sort_by_id(observation): """ @@ -158,7 +160,6 @@ @param observation: dictionary of the observed valve states @return: a list of tuples of the valve states """ - result = [] for key, value in observation.items(): if isinstance(value, dict): @@ -167,18 +168,19 @@ result = sorted(result, key=lambda each: each[1]) return result + @staticmethod def _binary_to_valve_state(binary) -> bool: """ @param binary: binary value @return: 1 = energized, otherwise de-energized """ - if binary != 0: return ENERGIZED else: return DEENERGIZED + @publish(["msg_id_dd_valves_states_data", "valve_states_all", "d14_valv", @@ -227,7 +229,6 @@ vsa = struct.unpack('I', bytearray(message['message'][self.START_POS_VALVES_STATES:self.END_POS_ALL_VALVES])) self.valve_states_all = vsa[0] - vst = struct.unpack('H', bytearray(message['message'][self.START_POS_VALVES_STATES:self.END_POS_VALVES_STATES])) # Extract each valve state from U16 valves states using bit-masking self.d14_valv["state"] = self._binary_to_valve_state(vst[0] & 1) @@ -277,6 +278,29 @@ self.dd_valves_states_timestamp = timestamp + + def cmd_valve_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the valve state override command. + Constraints: + Must be logged into DD. + Given interval must be non-zero and a multiple of the DD general task interval (50 ms). + + @param ms: unsigned int - broadcast interval (in ms) + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + + """ + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_VALVE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Valves', + logger = self.logger, + can_interface = self.can_interface) + + def cmd_valve_sensed_state_override(self, valve: int, state: bool, reset: int = NO_RESET) -> int: """ Constructs and sends the valve sensed state override command. @@ -289,29 +313,23 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) ste = integer_to_bytearray(int(state)) vlv = integer_to_bytearray(valve) payload = rst + ste + vlv - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_VALVE_SENSED_STATE_OVERRIDE_REQUEST.value, - payload=payload) + valve_name = DDValveNames(valve).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_VALVE_SENSED_STATE_OVERRIDE_REQUEST, + entity_name = f'DD {valve_name} Valve sensed state', + override_text = str(state), + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("Override valve sensed state") - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - def cmd_valve_override(self, valve: int, state: bool, reset: int = NO_RESET) -> int: """ Constructs and sends the valve state override command. @@ -324,29 +342,23 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) ste = integer_to_bytearray(int(state)) vlv = integer_to_bytearray(valve) payload = rst + ste + vlv - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_VALVE_STATE_OVERRIDE_REQUEST.value, - payload=payload) + valve_name = DDValveNames(valve).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_VALVE_STATE_OVERRIDE_REQUEST, + entity_name = f'DD {valve_name} Valve state', + override_text = str(state), + logger = self.logger, + can_interface = self.can_interface) - self.logger.debug("Override valve state") - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - def cmd_bc_valves_override(self, bcv1: bool, bcv2: bool, bcv3: bool, bcv4: bool, bcv5: bool, bcv6: bool, bcv7: bool, bcv8: bool) -> int: """ Constructs and sends the balancing chamber valve states override command. @@ -364,7 +376,6 @@ @param bcv8: bool - valve state for D22_VALV (true=open, false=closed) @return: 1 if successful, zero otherwise """ - valve = 0 if bcv1: valve = valve | 0x1 @@ -385,45 +396,17 @@ payload = integer_to_bytearray(valve) - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_BC_VALVE_STATES_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("Override balancing chamber valve states") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - - def cmd_valve_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: - """ - Constructs and sends the valve state override command. - Constraints: - Must be logged into DD. - Given interval must be non-zero and a multiple of the DD general task interval (50 ms). - - @param ms: unsigned int - broadcast interval (in ms) - @param reset: integer - 1 to reset a previous override, 0 to override - @return: 1 if successful, zero otherwise - - """ - - cmd_generic_broadcast_interval_override( - ms = ms, - reset = reset, + return cmd_generic_override( + payload = payload, + reset = NO_RESET, channel_id = DenaliChannels.dialin_to_dd_ch_id, - msg_id = MsgIds.MSG_ID_DD_VALVE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, - module_name = 'DD valve', + msg_id = MsgIds.MSG_ID_DD_BC_VALVE_STATES_OVERRIDE_REQUEST, + entity_name = f'DD Balancing Chamber Valves state', + override_text = '', logger = self.logger, can_interface = self.can_interface) + def cmd_valve_set_open_close(self, valve: int, state: int) -> int: """ Constructs and sends the valve open close command @@ -435,24 +418,17 @@ @return: 1 if successful, zero otherwise """ - vlv = integer_to_bytearray(valve) sts = integer_to_bytearray(state) payload = vlv + sts - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_VALVES_OPEN_CLOSE_STATE_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("setting " + str(state) + " - for valve: " + str(valve)) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.error("Timeout!!!!") - return False + valve_name = DDValveNames(valve).name.split('_')[0] + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_VALVES_OPEN_CLOSE_STATE_OVERRIDE_REQUEST, + entity_name = f'DD {valve_name} Valve state', + override_text = str(state), + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/voltages.py =================================================================== diff -u -r7ce778dc51b7dba5a7a7ca14244ed7eea7bf029d -r410054cfec7aee839266233249413b08b368fbd3 --- leahi_dialin/dd/modules/voltages.py (.../voltages.py) (revision 7ce778dc51b7dba5a7a7ca14244ed7eea7bf029d) +++ leahi_dialin/dd/modules/voltages.py (.../voltages.py) (revision 410054cfec7aee839266233249413b08b368fbd3) @@ -8,21 +8,22 @@ # @file voltages.py # # @author (last) Zoltan Miskolci -# @date (last) 04-Dec-2025 +# @date (last) 07-Jan-2026 # @author (original) Sean Nash # @date (original) 15-Apr-2021 # ############################################################################ + import struct from logging import Logger -from .constants import RESET, NO_RESET -from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.common.constants import NO_RESET +from leahi_dialin.common.dd_defs import DDMonitoredVoltages +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override +from leahi_dialin.protocols.CAN import DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray -from leahi_dialin.utils.checks import check_broadcast_interval_override_ms -from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions -from leahi_dialin.common.dd_defs import DDMonitoredVoltages class DDVoltages(AbstractSubSystem): @@ -57,7 +58,6 @@ @param message: published monitored voltages data message @return: none """ - v12 = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) v33 = struct.unpack('f', bytearray( @@ -86,85 +86,52 @@ self.dd_voltages_timestamp = timestamp - def cmd_monitored_voltage_override(self, signal: int = 0, volts: float = 0.0, reset: int = NO_RESET) -> int: + + def cmd_monitored_voltages_broadcast_interval_override(self, ms: int = 1000, reset: int = NO_RESET) -> int: """ - Constructs and sends the DD monitored voltage override command + Constructs and sends the monitored DD voltages broadcast interval override command Constraints: Must be logged into DD. - Given signal must be valid member of DDMonitoredVoltages enum + Given interval must be non-zero and a multiple of the DD general task interval (50 ms). - @param signal: integer - ID of signal to override - @param volts: float - value (in volts) to override signal with + @param ms: integer - interval (in ms) to override with @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ + return cmd_generic_broadcast_interval_override( + ms = ms, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_VOLTAGE_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Voltages', + logger = self.logger, + can_interface = self.can_interface) - rst = integer_to_bytearray(reset) - vlt = float_to_bytearray(volts) - idx = integer_to_bytearray(signal) - payload = rst + vlt + idx - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_MONITORED_VOLTAGE_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override monitored DD voltage for signal " + str(signal)) - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - if reset == RESET: - str_res = "reset back to normal. " - else: - str_res = str(volts) + " V. " - self.logger.debug("Monitored DD voltage overridden to " + str_res + - str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - - def cmd_monitored_voltages_broadcast_interval_override(self, ms: int = 1000, reset: int = NO_RESET) -> int: + def cmd_monitored_voltage_override(self, signal: int = 0, volts: float = 0.0, reset: int = NO_RESET) -> int: """ - Constructs and sends the monitored DD voltages broadcast interval override command + Constructs and sends the DD monitored voltage override command Constraints: Must be logged into DD. - Given interval must be non-zero and a multiple of the DD general task interval (50 ms). + Given signal must be valid member of DDMonitoredVoltages enum - @param ms: integer - interval (in ms) to override with + @param signal: integer - ID of signal to override + @param volts: float - value (in volts) to override signal with @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - - if not check_broadcast_interval_override_ms(ms): - return False - rst = integer_to_bytearray(reset) - mis = integer_to_bytearray(ms) - payload = rst + mis + vlt = float_to_bytearray(volts) + idx = integer_to_bytearray(signal) + payload = rst + vlt + idx - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_VOLTAGE_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override monitored DD voltages broadcast interval") - - # Send message - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - if reset == RESET: - str_res = "reset back to normal: " - else: - str_res = str(ms) + " ms: " - self.logger.debug("DD monitored voltages broadcast interval overridden to " + str_res + - str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False \ No newline at end of file + sensor_name = DDMonitoredVoltages(signal).name + return cmd_generic_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_MONITORED_VOLTAGE_OVERRIDE_REQUEST, + entity_name = f'DD {sensor_name} voltage', + override_text = f'{str(volts)} V', + logger = self.logger, + can_interface = self.can_interface)