Index: dialin/common/dg_defs.py =================================================================== diff -u -r6eb7388c7884a276c3c8b93aa8060feaab38081b -r4e696543dce83e9ac7d469197b25dbf080e22e26 --- dialin/common/dg_defs.py (.../dg_defs.py) (revision 6eb7388c7884a276c3c8b93aa8060feaab38081b) +++ dialin/common/dg_defs.py (.../dg_defs.py) (revision 4e696543dce83e9ac7d469197b25dbf080e22e26) @@ -211,10 +211,9 @@ DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE = 6 DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE = 7 DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_STATE = 8 - DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COOL_DOWN_RO_FILTER = 9 - DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_WATER_PATH_STATE = 10 - DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_BASIC_PATH_STATE = 11 - DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COMPLETE = 12 + DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_WATER_PATH_STATE = 9 + DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_BASIC_PATH_STATE = 10 + DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COMPLETE = 11 @unique Index: dialin/dg/chemical_disinfect.py =================================================================== diff -u -r428c5c0a653129867b1cb32b5e64f89f68191c4b -r4e696543dce83e9ac7d469197b25dbf080e22e26 --- dialin/dg/chemical_disinfect.py (.../chemical_disinfect.py) (revision 428c5c0a653129867b1cb32b5e64f89f68191c4b) +++ dialin/dg/chemical_disinfect.py (.../chemical_disinfect.py) (revision 4e696543dce83e9ac7d469197b25dbf080e22e26) @@ -25,8 +25,10 @@ class ChemCancellationModes(DialinEnum): CANCELLATION_MODE_NONE = 0 CANCELLATION_MODE_BASIC = 1 - CANCELLATION_MODE_WATER = 2 - CANCELLATION_MODE_CHEMICAL = 3 + CANCELLATION_MODE_HOT = 2 + CANCELLATION_MODE_COLD = 3 + CANCELLATION_MODE_CHEMICAL = 4 + CANCELLATION_MODE_WATER = 5 class ChemicalDisinfect(AbstractSubSystem): Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -r428c5c0a653129867b1cb32b5e64f89f68191c4b -r4e696543dce83e9ac7d469197b25dbf080e22e26 --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 428c5c0a653129867b1cb32b5e64f89f68191c4b) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 4e696543dce83e9ac7d469197b25dbf080e22e26) @@ -151,6 +151,9 @@ MsgIds.MSG_ID_DG_VERSION.value, self._handler_dg_version) + self.can_interface.register_transmitting_interval_message(INTERVAL_10s, + self._send_dg_checkin_message) + # initialize variables that will be populated by DG version response self.dg_version = None self.fpga_version = None @@ -542,3 +545,13 @@ else: self.logger.debug("Timeout!!!!") return False + + def _send_dg_checkin_message(self) -> None: + """ + Constructs and sends an DG Dialin check in message to the DG. + + @return: none + """ + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=MsgIds.MSG_ID_DG_DIALIN_CHECK_IN.value) + self.can_interface.send(message, 0) \ No newline at end of file Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -r6ff50b4ae97f1d8071f1d8fdafae60f6fd704b9d -r4e696543dce83e9ac7d469197b25dbf080e22e26 --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 6ff50b4ae97f1d8071f1d8fdafae60f6fd704b9d) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 4e696543dce83e9ac7d469197b25dbf080e22e26) @@ -53,7 +53,7 @@ from .hd_test_configs import HDTestConfig from ..common.msg_defs import MsgIds, MsgFieldPositions from ..protocols.CAN import DenaliMessage, DenaliCanMessenger, DenaliChannels -from ..utils.base import AbstractSubSystem, publish, LogManager +from ..utils.base import AbstractSubSystem, publish, LogManager, INTERVAL_10s from ..utils.checks import check_broadcast_interval_override_ms from ..utils.conversions import integer_to_bytearray, unsigned_short_to_bytearray, bytearray_to_integer, \ bytearray_to_byte @@ -121,6 +121,9 @@ MsgIds.MSG_ID_HD_UI_VERSION_INFO_RESPONSE.value, self._handler_ui_version_response_sync) + self.can_interface.register_transmitting_interval_message(INTERVAL_10s, + self._send_hd_checkin_message) + # create properties self.hd_op_mode_timestamp = 0.0 self.hd_debug_events_timestamp = 0.0 @@ -732,3 +735,12 @@ self.can_interface.send(message, 0) + def _send_hd_checkin_message(self) -> None: + """ + Constructs and sends an HD Dialin check in message to the HD. + + @return: none + """ + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_DIALIN_CHECK_IN.value) + self.can_interface.send(message, 0) Index: dialin/protocols/CAN.py =================================================================== diff -u -rb2883ad890516361d0c22919811ff1d5752c0aaf -r4e696543dce83e9ac7d469197b25dbf080e22e26 --- dialin/protocols/CAN.py (.../CAN.py) (revision b2883ad890516361d0c22919811ff1d5752c0aaf) +++ dialin/protocols/CAN.py (.../CAN.py) (revision 4e696543dce83e9ac7d469197b25dbf080e22e26) @@ -29,7 +29,7 @@ import struct from .. import common from ..common import MsgIds -from ..utils import SingletonMeta +from ..utils import SingletonMeta, IntervalTimer from concurrent.futures import ThreadPoolExecutor @@ -503,6 +503,7 @@ self.sync_response_dictionary = {} self.ui_received_function_ptr = None self.pending_requests = {} + self.transmit_interval_dictionary = {} def start(self): """ @@ -866,3 +867,17 @@ message = "# " + DenaliCanMessenger.convert_message_to_string(complete_dialin_message) print(message) + + def register_transmitting_interval_message(self, interval: float, function) ->None: + """ + registers a callback function with a specified time interval to a dictionary + @return: None + """ + function_id = id(function) + + if function_id in self.transmit_interval_dictionary.keys(): + self.logger.error("ERROR: Attempting to assign more than one timed interval per given method.") + self.transmit_interval_dictionary[function_id].stop() + self.transmit_interval_dictionary[function_id].start() + else: + self.transmit_interval_dictionary[function_id] = IntervalTimer(interval, function) Index: dialin/utils/base.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -r4e696543dce83e9ac7d469197b25dbf080e22e26 --- dialin/utils/base.py (.../base.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ dialin/utils/base.py (.../base.py) (revision 4e696543dce83e9ac7d469197b25dbf080e22e26) @@ -18,7 +18,12 @@ from abc import ABC, abstractmethod from datetime import datetime from enum import Enum +from threading import Timer +INTERVAL_1s = 1 +INTERVAL_5s = 5 +INTERVAL_10s = 10 +INTERVAL_60s = 60 class AbstractObserver(ABC): """ @@ -66,7 +71,6 @@ class LogManager: - LOG_FMT = '%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s' LOG_FMT_NO_METADATA = '%(message)s' LOG_DT_FMT = '%m-%d-%Y:%H:%M:%S' @@ -285,3 +289,34 @@ @classmethod def has_value(cls, value): return value in cls._value2member_map_ + + +class IntervalTimer(object): + """ + A class object that is used to execute a function on a timed interval. + Timed interval auto starts on object creation. + Uses to send CAN messages at a specified interval. + + """ + def __init__(self, interval, function, *args, **kwargs): + self._timer = None + self.interval = interval + self.function = function + self.args = args + self.kwargs = kwargs + self.is_running = False + self.start() + + def _run(self): + self.is_running = False + self.start() + self.function(*self.args, **self.kwargs) + + def start(self): + if not self.is_running: + self._timer = Timer(self.interval, self._run) + self._timer.start() + self.is_running = True + + def stop(self): + self._timer.cancel()