Index: leahi_dialin/common/override_templates.py =================================================================== diff -u -r51f77692576780b2857eddf0e49e8014c8b2ebc1 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/common/override_templates.py (.../override_templates.py) (revision 51f77692576780b2857eddf0e49e8014c8b2ebc1) +++ leahi_dialin/common/override_templates.py (.../override_templates.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -8,7 +8,7 @@ # @file override_templates.py # # @author (last) Zoltan Miskolci -# @date (last) 04-Dec-2025 +# @date (last) 07-Jan-2026 # @author (original) Zoltan Miskolci # @date (original) 04-Dec-2025 # @@ -96,19 +96,25 @@ message_id=msg_id.value, payload=payload) - logger.debug(f"override {entity_name} value") + if payload is None: + logger.debug(f'Call command: {entity_name}') + else: + logger.debug(f'Override {entity_name} value') # Send message received_message = can_interface.send(message) # If there is content... if received_message is not None: if reset == RESET: - str_res = "reset back to normal: " + str_res = f'its default value' else: str_res = override_text - logger.debug(f"{entity_name} is overridden to " + str_res + - str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + if payload is None: + logger.debug(f'{entity_name} is {str_res} {str(received_message["message"][DenaliMessage.PAYLOAD_START_INDEX])}') + else: + logger.debug(f'{entity_name} is 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: Index: leahi_dialin/dd/modules/alarms.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/alarms.py (.../alarms.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/alarms.py (.../alarms.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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,146 @@ 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 @@ -145,26 +290,12 @@ 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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/balancing_chamber.py (.../balancing_chamber.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/balancing_chamber.py (.../balancing_chamber.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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", @@ -91,6 +92,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 @@ -103,30 +105,16 @@ @return: 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_BAL_CHAMBER_DATA_PUBLISH_OVERRIDE_REQUEST, + module_name = 'DD Balancing Chamber', + logger = self.logger, + can_interface = self.can_interface) + - 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 @@ -143,27 +131,17 @@ 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 @@ -180,21 +158,17 @@ 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 @@ -211,27 +185,17 @@ 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 @@ -248,23 +212,12 @@ 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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/blood_leak.py (.../blood_leak.py) (revision 776be9fb446685fb492a2b7bd6faf4eac7dfe714) +++ leahi_dialin/dd/modules/blood_leak.py (.../blood_leak.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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,100 @@ 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) - self.logger.debug("Request blood leak zeroing") + 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) - # 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 +264,18 @@ @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) - self.logger.debug("Setting the blood leak to embedded mode") + 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) - 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 +297,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 +325,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 +350,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 @@ -399,27 +373,20 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ + + text = 'upper intensity' if upper_interval == 1 else 'intensity drift' + rst = integer_to_bytearray(reset) mins = integer_to_bytearray(value_mins) 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 + 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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/concentrate_pump.py (.../concentrate_pump.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/concentrate_pump.py (.../concentrate_pump.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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): """ @@ -148,6 +149,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 @@ -161,30 +163,16 @@ """ - 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_CONCENTRATE_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Concentrate Pump', + logger = self.logger, + can_interface = self.can_interface) - 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 @@ -200,23 +188,17 @@ 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 @@ -233,26 +215,17 @@ 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 @@ -269,26 +242,17 @@ 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 @@ -305,26 +269,17 @@ 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 @@ -335,24 +290,18 @@ """ 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 @@ -371,19 +320,12 @@ 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 -r7c0309a22098e7c4b0ef1599fc737f6f8929b9ac -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/conductivity_sensors.py (.../conductivity_sensors.py) (revision 7c0309a22098e7c4b0ef1599fc737f6f8929b9ac) +++ leahi_dialin/dd/modules/conductivity_sensors.py (.../conductivity_sensors.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -7,22 +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 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 DDConductivitySensorsEnum -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.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 +59,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): """ @@ -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 @@ -98,36 +100,16 @@ @return: 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_CONDUCTIVITY_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Conductivity Sensors', + logger = self.logger, + can_interface = self.can_interface) - 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_CONDUCTIVITY_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override DD conductivity sensor 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("Conductivity sensor 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.error("Timeout!!!!") - return False - 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 @@ -147,28 +129,18 @@ 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 @@ -188,28 +160,18 @@ 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 @@ -226,24 +188,13 @@ 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) Fisheye: Tag 0bdafdb1821e164a8416ea4b47be946f13239b5a refers to a dead (removed) revision in file `leahi_dialin/dd/modules/constants.py'. Fisheye: No comparison available. Pass `N' to diff? Index: leahi_dialin/dd/modules/dd_test_configs.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/dd_test_configs.py (.../dd_test_configs.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/dd_test_configs.py (.../dd_test_configs.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -7,23 +7,25 @@ # # @file dd_test_configs.py # -# @author (last) Jonny Paguio -# @date (last) 20-Aug-2025 +# @author (last) Zoltan Miskolci +# @date (last) 07-Jan-2026 # @author (original) Jonny Paguio # @date (original) 20-Aug-2025 # ############################################################################ 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.override_templates import cmd_generic_override from leahi_dialin.common.test_config_defs import DDTestConfigOptions -from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels -from .constants import NO_RESET -from leahi_dialin.utils.conversions import integer_to_bytearray, bytearray_to_integer +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 + class DDTestConfig(AbstractSubSystem): """ @@ -50,7 +52,7 @@ self.can_interface.register_receiving_publication_function(channel_id, self.msg_id_dd_send_test_config, self._handler_dd_test_config_sync) - def cmd_get_test_config_status(self, config: int): + def get_test_config_status(self, config: int): """ Returns the status of a test config @@ -59,6 +61,27 @@ """ return self.dd_test_configs[DDTestConfigOptions(config).name] + + @publish(['msg_id_dd_send_test_config', 'dd_test_configs', 'dd_test_configs_response_timestamp']) + def _handler_dd_test_config_sync(self, message, timestamp=0.0): + """ + Handles published test configuration status messages. + Triggered by: cmd_request_test_config_status_from_fw + + @param message: published DD test configurations message + @return: None + """ + payload = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + + for config in DDTestConfigOptions.__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 + + self.dd_test_configs_response_timestamp = timestamp + + def cmd_set_test_config(self, config: int, reset: int = NO_RESET): """ Constructs and sends the DD test config @@ -73,26 +96,21 @@ c = integer_to_bytearray(config) payload = reset_value + c - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_SET_TEST_CONFIGURATION.value, - payload=payload) + response = cmd_generic_override( + payload = payload, + 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', + 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 - if reset == NO_RESET: - self.logger.debug("Setting {}".format(DDTestConfigOptions(config).name)) - else: - self.logger.debug("Resetting {}".format(DDTestConfigOptions(config).name)) - # Send message - received_message = self.can_interface.send(message) - - # If there is no 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_request_test_config_status_from_fw(self): """ Constructs and sends the DD test configs request @@ -101,26 +119,18 @@ @return: 1 if successful, zero otherwise """ - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_GET_TEST_CONFIGURATION.value) - self.logger.debug('Getting DD test configuration record') - # Reset the test configs regardless of whether the message has been acknowledged or not. The reset might be out - # sync and reset the test configuration while the latest data has been received. If the test configuration is - # reset in Dialin but the message was not acknowledged, the user shall send the request again - self._reset_test_configs_record() + return cmd_generic_override( + payload = None, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_GET_TEST_CONFIGURATION, + entity_name = f'Get DD Test Configuration Record', + 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: - self.logger.debug("Received FW ACK after requesting DD test configuration record.") - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - def cmd_reset_all_test_configs(self): """ Constructs and sends the DD test configs reset all @@ -129,47 +139,17 @@ @return: 1 if successful, zero otherwise """ - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_RESET_ALL_TEST_CONFIGURATIONS.value) - self.logger.debug("Resetting all DD test configurations") + response = cmd_generic_override( + payload = None, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_RESET_ALL_TEST_CONFIGURATIONS, + entity_name = f'Reset all Test Configurations', + override_text = 'Active', + logger = self.logger, + can_interface = self.can_interface) - # Send message - received_message = self.can_interface.send(message) - - # If there is no 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 - - @publish(['msg_id_dd_send_test_config', 'dd_test_configs', 'dd_test_configs_response_timestamp']) - def _handler_dd_test_config_sync(self, message, timestamp=0.0): - """ - Handles published test configuration status messages. - - @param message: published DD test configurations message - @return: None - """ - payload = message['message'] - index = MsgFieldPositions.START_POS_FIELD_1 - - for config in DDTestConfigOptions.__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 - - self.dd_test_configs_response_timestamp = timestamp - - def _reset_test_configs_record(self): - """ - Resets the test configuration dictionary - - @return: None - """ - for config in DDTestConfigOptions.__members__: - # Loop through the list of the test configuration and set the values to 0xFFFFFFFF - if 'NUM_OF_TEST_CONFIGS' not in config: - self.dd_test_configs[config] = 0xFFFFFFFF \ No newline at end of file + # 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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/dialysate_pump.py (.../dialysate_pump.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/dialysate_pump.py (.../dialysate_pump.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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): """ @@ -140,6 +141,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 +153,17 @@ @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 @@ -192,23 +180,17 @@ 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 @@ -225,23 +207,17 @@ 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 @@ -258,23 +234,17 @@ 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 @@ -291,23 +261,17 @@ 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 @@ -324,23 +288,17 @@ 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 @@ -358,19 +316,12 @@ 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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/events.py (.../events.py) (revision 7d9d004527efeccb91958b440abdff08c2c52648) +++ leahi_dialin/dd/modules/events.py (.../events.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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. @@ -92,6 +98,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 +119,7 @@ return event + def clear_dd_event_list(self): """ Clears the DD event list @@ -121,6 +129,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 +157,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 +297,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): """ @@ -304,4 +315,4 @@ 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 -r0d41ec2fd13ad36c344b6a8a7c2b88ef18e057b7 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/gen_dialysate.py (.../gen_dialysate.py) (revision 0d41ec2fd13ad36c344b6a8a7c2b88ef18e057b7) +++ leahi_dialin/dd/modules/gen_dialysate.py (.../gen_dialysate.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -7,23 +7,24 @@ # # @file 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.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 DDGenDialysate(AbstractSubSystem): """ Gen Dialysate @@ -59,6 +60,7 @@ self.targetQd = 0.0 self.dd_gen_dialysate_timestamp = 0 + @publish(["msg_id_dd_gen_dialysate_mode_data", "execution_state", "dialysate_delivery_in_progress", "d6_level", @@ -98,6 +100,7 @@ message['message'][MsgFieldPositions.START_POS_FIELD_10:MsgFieldPositions.END_POS_FIELD_10]))[0] self.dd_gen_dialysate_timestamp = timestamp + def cmd_gen_dialysate_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the gen dialysate data broadcast interval override command @@ -110,30 +113,16 @@ @return: 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_GEND_MODE_DATA_PUBLISH_OVERRIDE_REQUEST, + module_name = 'DD Gen Dialysate', + logger = self.logger, + can_interface = self.can_interface) - 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_GEND_MODE_DATA_PUBLISH_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override DD Gen Dialysate 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_delivery_in_progress_override(self, in_progress: int, reset: int = NO_RESET) -> int: """ Constructs and sends the dialysate delivery in progress override command @@ -148,27 +137,17 @@ inprog = integer_to_bytearray(in_progress) payload = reset_byte_array + inprog - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIAL_DELIVERY_IN_PROGRESS_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_DIAL_DELIVERY_IN_PROGRESS_OVERRIDE_REQUEST, + entity_name = f'DD Dialysate Delivery in progress', + override_text = str(in_progress), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(in_progress) - self.logger.debug("override dialysate delivery in progress to " + ": " + 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_dialysate_delivery_good_to_deliver_override(self, delivery: int, reset: int = NO_RESET) -> int: """ Constructs and sends the dialysate delivery good to deliver override command @@ -183,27 +162,17 @@ dev = integer_to_bytearray(delivery) payload = reset_byte_array + dev - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_DIAL_DELIVERY_GOOD_TO_DELIVER_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_DIAL_DELIVERY_GOOD_TO_DELIVER_OVERRIDE_REQUEST, + entity_name = f'DD Dialysate Delivery is good to deliver', + override_text = str(delivery), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(delivery) - self.logger.debug("override dialysate good to delivery to " + ": " + 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_hydraulics_chamber_target_temperature_override(self, temperature: float, reset: int = NO_RESET) -> int: """ Constructs and sends the hydraulic fluid temperature override command @@ -218,27 +187,17 @@ tmp = float_to_bytearray(temperature) payload = reset_byte_array + tmp - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_HYD_CHAMBER_TARGET_TEMP_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_HYD_CHAMBER_TARGET_TEMP_OVERRIDE_REQUEST, + entity_name = f'DD Hydraulics Chamber target Temperature', + override_text = str(temperature), + logger = self.logger, + can_interface = self.can_interface) - if reset == RESET: - str_res = "reset back to normal" - else: - str_res = str(temperature) - self.logger.debug("override hydraulic fluid temperature to " + ": " + 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_dialysate_delivery_set_state_override(self, state: int) -> int: """ Constructs and sends the set execution state override command @@ -252,23 +211,20 @@ sts = integer_to_bytearray(state) payload = sts - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_GEND_EXEC_STATE_OVERRIDE_REQUEST.value, - payload=payload) - # Send message - received_message = self.can_interface.send(message) + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_GEND_EXEC_STATE_OVERRIDE_REQUEST, + entity_name = f'DD Dialysate Delivery set state', + override_text = str(state), + logger = self.logger, + can_interface = self.can_interface) - # 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_stop_gen_mode_override(self, state: int, reset: int = NO_RESET) -> int: """ - Constructs and sends start pre gen mode override request + Constructs and sends stop gen mode override request @param state: int - value to override state @param reset: integer - 1 to reset a previous override, 0 to override @@ -280,18 +236,12 @@ interval_value = integer_to_bytearray(state) payload = reset_value + interval_value - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_STOP_GEN_DIALYSATE_MODE_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("Sending {} start pre gen mode override".format(state)) - # 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_override( + payload = payload, + reset = reset, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_STOP_GEN_DIALYSATE_MODE_OVERRIDE_REQUEST, + entity_name = f'DD Dialysate Delivery pre gen mode', + override_text = str(state), + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/heaters.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/heaters.py (.../heaters.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/heaters.py (.../heaters.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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 @@ -83,6 +82,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 +135,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 +147,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 +167,23 @@ @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: """ @@ -209,26 +195,25 @@ @param temperature: float - temp to set to @returns 1 if successful, zero otherwise """ + htr = integer_to_bytearray(heater) cmd = integer_to_bytearray(command) 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 +228,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 +254,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 -r56cd024ca23456ab0ae5f6acd30cb4cde02beb4a -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/levels.py (.../levels.py) (revision 56cd024ca23456ab0ae5f6acd30cb4cde02beb4a) +++ leahi_dialin/dd/modules/levels.py (.../levels.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -7,24 +7,23 @@ # # @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 # ############################################################################ import struct -from enum import unique from logging import Logger -from .constants import 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 DDLevelSensorEnum -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.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 class DDLevels(AbstractSubSystem): @@ -75,6 +74,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. @@ -86,29 +86,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_LEVELS_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Levels', + 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_LEVELS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("Sending {} ms publish interval to the Levels 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_level_status_override(self, level_sensor: int, status: int, reset: int = NO_RESET) -> int: """ Constructs and sends level status cycle override command @@ -123,16 +110,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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- 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 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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): """ @@ -64,6 +65,7 @@ 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 +77,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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- 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 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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): """ @@ -76,6 +77,7 @@ 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", @@ -101,6 +103,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 +115,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 -r35e8d930cb1a45457de87d93728fe60c7cb10ab5 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/pressure_sensors.py (.../pressure_sensors.py) (revision 35e8d930cb1a45457de87d93728fe60c7cb10ab5) +++ leahi_dialin/dd/modules/pressure_sensors.py (.../pressure_sensors.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -7,22 +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 enum import unique from logging import Logger -from .constants import NO_RESET, RESET -from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.dd_defs import DDPressureNames -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.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 @@ -58,6 +58,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): """ @@ -80,6 +81,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. @@ -92,31 +94,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_PRESSURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Pressure Sensors', + logger = self.logger, + can_interface = self.can_interface) - if not check_broadcast_interval_override_ms(ms): - return False - rst = integer_to_bytearray(reset) - ivl = integer_to_bytearray(ms) - payload = rst + ivl - - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_PRESSURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override pressure 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.debug("Timeout!!!!") - return False - def cmd_pressure_readings_override(self, sensor: int, pressure: float, reset: int = NO_RESET) -> int: """ Constructs and sends the pressure readings override command. @@ -134,23 +121,18 @@ 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 @@ -169,27 +151,18 @@ 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. @@ -208,27 +181,18 @@ 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. @@ -246,19 +210,13 @@ 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 -rfa63b92d3d3a3f2870833583bff12729e180e2d1 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/rinse_pump.py (.../rinse_pump.py) (revision fa63b92d3d3a3f2870833583bff12729e180e2d1) +++ leahi_dialin/dd/modules/rinse_pump.py (.../rinse_pump.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -7,22 +7,23 @@ # # @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.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 DDRinsePump(AbstractSubSystem): """ Rinse Pump @@ -49,9 +50,8 @@ self.d79_state = 0 self.dd_rinse_pump_timestamp = 0 - @publish(["msg_id_dd_rinse_pump_data", - "d79_state", - "dd_rinse_pump_timestamp"]) + + @publish(["msg_id_dd_rinse_pump_data", "d79_state", "dd_rinse_pump_timestamp"]) def _handler_rinse_pump_sync(self, message, timestamp=0.0): """ Handles published rinse pump data messages. @@ -65,6 +65,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 @@ -76,27 +77,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_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 \ 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_RINSE_PUMP_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Rinse Pump', + logger = self.logger, + can_interface = self.can_interface) Index: leahi_dialin/dd/modules/spent_chamber_fill.py =================================================================== diff -u -rec8a2600b9e8cf6fe7e02c200a1c24221ca86863 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- 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 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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", @@ -71,6 +73,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 +85,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 -r6e0b0571d3f4064c8d7bb2b737e326c460780759 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/temperature_sensors.py (.../temperature_sensors.py) (revision 6e0b0571d3f4064c8d7bb2b737e326c460780759) +++ leahi_dialin/dd/modules/temperature_sensors.py (.../temperature_sensors.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -7,29 +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 enum import unique from logging import Logger -from .constants import NO_RESET, RESET -from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.dd_defs import COND_SENSOR_INDEX_OFFSET, PRES_SENSOR_INDEX_OFFSET, DDTemperaturesNames -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.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__() @@ -65,6 +63,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): """ @@ -132,6 +131,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. @@ -143,30 +143,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_TEMPERATURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + module_name = 'DD Temperature Sensors', + 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_TEMPERATURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("Sending {} ms publish interval to the Temperature Sensors module".format(ms)) - # Send message - received_message = self.can_interface.send(message) - - # If there is content in message - if received_message is not None: - # Response payload is OK or not - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - def cmd_temperatures_value_override(self, sensor_index: int, sensor_value: float, reset: int = NO_RESET) -> int: """ Constructs and sends the value override of a temperature sensor. @@ -180,45 +166,35 @@ @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.D75_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: """ @@ -236,27 +212,18 @@ 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 @@ -271,27 +238,17 @@ 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 @@ -306,21 +263,17 @@ 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. @@ -338,19 +291,13 @@ 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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/ultrafiltration.py (.../ultrafiltration.py) (revision ec8a2600b9e8cf6fe7e02c200a1c24221ca86863) +++ leahi_dialin/dd/modules/ultrafiltration.py (.../ultrafiltration.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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"]) @@ -75,6 +76,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 +88,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 -rfa63b92d3d3a3f2870833583bff12729e180e2d1 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/valves.py (.../valves.py) (revision fa63b92d3d3a3f2870833583bff12729e180e2d1) +++ leahi_dialin/dd/modules/valves.py (.../valves.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -7,24 +7,23 @@ # # @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 # ############################################################################ import struct -from enum import unique from logging import Logger from collections import OrderedDict -from .constants import NO_RESET +from leahi_dialin.common.constants import NO_RESET +from leahi_dialin.common.dd_defs import DDValveNames from leahi_dialin.common.msg_defs import MsgIds -from leahi_dialin.common.dd_defs import DDValveStates, DDValveNames +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.base import AbstractSubSystem, publish from leahi_dialin.utils.conversions import integer_to_bytearray # Valve states @@ -107,6 +106,7 @@ for valve in DDValveNames.__members__: self.valves_sensed_states[valve] = '' + def get_valve_states(self): """ Gets the valve states @@ -150,6 +150,7 @@ self.spare7_valv.get("state", None) ] + @staticmethod def sort_by_id(observation): """ @@ -168,6 +169,7 @@ result = sorted(result, key=lambda each: each[1]) return result + @staticmethod def _binary_to_valve_state(binary) -> bool: """ @@ -180,6 +182,7 @@ else: return DEENERGIZED + @publish(["msg_id_dd_valves_states_data", "valve_states_all", "d14_valv", @@ -278,6 +281,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. @@ -296,23 +322,18 @@ 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. @@ -331,23 +352,18 @@ 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. @@ -386,61 +402,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) + return cmd_generic_override( + payload = payload, + reset = NO_RESET, + channel_id = DenaliChannels.dialin_to_dd_ch_id, + 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) - 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 - - """ - - if not check_broadcast_interval_override_ms(ms): - return False - - rst = integer_to_bytearray(reset) - ivl = integer_to_bytearray(ms) - payload = rst + ivl - - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dd_ch_id, - message_id=MsgIds.MSG_ID_DD_VALVE_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, - payload=payload) - - self.logger.debug("override valves states publish interval") - - # 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_valve_set_open_close(self, valve: int, state: int) -> int: """ Constructs and sends the valve open close command @@ -457,19 +429,13 @@ 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 \ No newline at end of file + 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 -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/modules/voltages.py (.../voltages.py) (revision 7ce778dc51b7dba5a7a7ca14244ed7eea7bf029d) +++ leahi_dialin/dd/modules/voltages.py (.../voltages.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -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): @@ -86,85 +87,53 @@ 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) Index: leahi_dialin/dd/proxies/td_proxy.py =================================================================== diff -u -r2dab2b0329a56006e07cd36a3883ed099d7a367a -r0bdafdb1821e164a8416ea4b47be946f13239b5a --- leahi_dialin/dd/proxies/td_proxy.py (.../td_proxy.py) (revision 2dab2b0329a56006e07cd36a3883ed099d7a367a) +++ leahi_dialin/dd/proxies/td_proxy.py (.../td_proxy.py) (revision 0bdafdb1821e164a8416ea4b47be946f13239b5a) @@ -13,13 +13,14 @@ # @date (original) 02-Apr-2020 # ############################################################################ + import struct from logging import Logger from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions from leahi_dialin.protocols.CAN import DenaliMessage, DenaliCanMessenger, DenaliChannels from leahi_dialin.utils.base import AbstractSubSystem, publish -from leahi_dialin.utils.conversions import integer_to_bytearray, byte_to_bytearray, float_to_bytearray +from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray class TDProxy(AbstractSubSystem): @@ -53,6 +54,7 @@ self.dialysate_delivery_request_bicarb = 0 self.dd_td_to_dd_request_response_timestamp = 0.0 + @publish(["dd_td_to_dd_request_response_timestamp", "dialysate_delivery_request_start","dialysate_delivery_request_dial_rate", "dialysate_delivery_request_uf_rate","dialysate_delivery_request_dial_temp", @@ -106,6 +108,7 @@ self.logger.debug("Sending TD gen dialysate data request to DD.") self.can_interface.send(message, 0) + def cmd_td_send_dd_start_pre_gen_request(self, start: bool = 0, dialysate_rate: float = 0.0, dialysate_temp: float = 0.0, acid_type: int = 0, bicarb_type: int = 0 ): """ @@ -129,4 +132,4 @@ payload=payload) self.logger.debug("Sending TD start pre gen request to DD.") - self.can_interface.send(message, 0) \ No newline at end of file + self.can_interface.send(message, 0)