########################################################################### # # Copyright (c) 2020-2026 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 heat_disinfect.py # # @author (last) Jashwant Gantyada # @date (last) 19-Aug-2026 # @author (original) Jashwant Gantyada # @date (original) 19-Aug-2026 # ############################################################################ # Module imports from logging import Logger # Project imports from leahi_dialin.common.constants import NO_RESET from leahi_dialin.common.generic_defs import DataTypes from leahi_dialin.common.msg_ids import MsgIds from leahi_dialin.common.override_templates import cmd_generic_broadcast_interval_override, cmd_generic_override from leahi_dialin.protocols.CAN import CanMessenger, CanChannels from leahi_dialin.utils.abstract_classes import AbstractSubSystem from leahi_dialin.utils.base import publish from leahi_dialin.utils.conversions import integer_to_bytearray class DDHeatDisinfect(AbstractSubSystem): """ Heat Disinfect Dialysate Delivery (DD) Dialin API sub-class for Heat Disinfect related commands. """ def __init__(self, can_interface: CanMessenger, logger: Logger): """ @param can_interface: Can Messenger object """ super().__init__() self.can_interface = can_interface self.logger = logger if self.can_interface is not None: self.can_interface.register_receiving_publication_function(channel_id = CanChannels.dd_sync_broadcast_ch_id, message_id = MsgIds.MSG_ID_DD_HEAT_DISINFECT_STATE_DATA.value, function = self._handler_heat_disinfect_sync) self.execution_state = 0 #: heatDisinfectExecState self.sub_state = 0 #: heatDisinfectSubState self.dd_recirc_dwell_time_ms = 0 #: ddRecircDwellTimeMS self.wcid_recirc_dwell_time_ms = 0 #: wcidRecircDwellTimeMS self.dd_dwell_at_target = 0 #: ddDwellAtTarget self.wcid_dwell_at_target = 0 #: wcidDwellAtTarget self.dd_heat_disinfect_timestamp = 0 #: The timestamp of the last message @property def execution_state(self) -> int: return self._execution_state @execution_state.setter def execution_state(self, value): self._execution_state = value @property def sub_state(self) -> int: return self._sub_state @sub_state.setter def sub_state(self, value): self._sub_state = value @property def dd_recirc_dwell_time_ms(self) -> int: return self._dd_recirc_dwell_time_ms @dd_recirc_dwell_time_ms.setter def dd_recirc_dwell_time_ms(self, value): self._dd_recirc_dwell_time_ms = value @property def wcid_recirc_dwell_time_ms(self) -> int: return self._wcid_recirc_dwell_time_ms @wcid_recirc_dwell_time_ms.setter def wcid_recirc_dwell_time_ms(self, value): self._wcid_recirc_dwell_time_ms = value @property def dd_dwell_at_target(self) -> int: return self._dd_dwell_at_target @dd_dwell_at_target.setter def dd_dwell_at_target(self, value): self._dd_dwell_at_target = value @property def wcid_dwell_at_target(self) -> int: return self._wcid_dwell_at_target @wcid_dwell_at_target.setter def wcid_dwell_at_target(self, value): self._wcid_dwell_at_target = value @publish(["msg_id_dd_heat_disinfect_state_data", "execution_state", "sub_state", "dd_recirc_dwell_time_ms", "wcid_recirc_dwell_time_ms", "dd_dwell_at_target", "wcid_dwell_at_target", "dd_heat_disinfect_timestamp"]) def _handler_heat_disinfect_sync(self, message, timestamp=0.0): """ Handles published heat disinfect data messages. @param message: published heat disinfect data message @return: None """ msg_list = [] msg_list.append((type(self).execution_state, DataTypes.U32)) msg_list.append((type(self).sub_state, DataTypes.U32)) msg_list.append((type(self).dd_recirc_dwell_time_ms, DataTypes.U32)) msg_list.append((type(self).wcid_recirc_dwell_time_ms, DataTypes.U32)) msg_list.append((type(self).dd_dwell_at_target, DataTypes.U32)) msg_list.append((type(self).wcid_dwell_at_target, DataTypes.U32)) self.process_into_vars(decoder_list = msg_list, message = message) self.dd_heat_disinfect_timestamp = timestamp def cmd_heat_disinfect_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the heat disinfect 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 """ return cmd_generic_broadcast_interval_override( ms = ms, reset = reset, channel_id = CanChannels.dialin_to_dd_ch_id, msg_id = MsgIds.MSG_ID_DD_HEAT_DISINFECT_MODE_DATA_PUBLISH_OVERRIDE_REQUEST, module_name = 'DD Heat Disinfect', logger = self.logger, can_interface = self.can_interface) def cmd_heat_disinfect_start_stop(self, start: int) -> int: """ Constructs and sends the heat disinfect start stop request Constraints: Must be logged into DD. @param start: int - value to start or stop heat disinfect ( start = 1, stop = 0 ) @return: 1 if successful, zero otherwise """ payload = integer_to_bytearray(start) return cmd_generic_override( payload = payload, reset = NO_RESET, channel_id = CanChannels.dialin_to_dd_ch_id, msg_id = MsgIds.MSG_ID_DD_HEAT_DISINFECT_REQUEST_DATA, entity_name = 'Heat Disinfect Start' if start == 1 else 'Heat Disinfect Stop', override_text = str(start), logger = self.logger, can_interface = self.can_interface)