########################################################################### # # Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. # # THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN # WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. # # @file blood_pressure.py # # @author (last) Zoltan Miskolci # @date (last) 06-Jul-2026 # @author (original) Zoltan Miskolci # @date (original) 06-Jul-2026 # ############################################################################ # Module imports from logging import Logger # Project imports from leahi_dialin.common.generic_defs import DataTypes from leahi_dialin.common.msg_defs import RequestRejectReasons from leahi_dialin.common.msg_ids import MsgIds 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.td.proxies.ui_proxy import UIProxy class TDBloodPressure(AbstractSubSystem): """ @brief Treatment Device (TD) Dialin API sub-class for TD patient vitals related commands. """ def __init__(self, can_interface: CanMessenger, logger: Logger): """ TDBloodPressure constructor """ 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.td_sync_broadcast_ch_id, message_id = MsgIds.MSG_ID_TD_BLOOD_PRESSURE_DATA.value, function = self._handler_bp_sync) self.can_interface.register_receiving_publication_function(channel_id = CanChannels.td_sync_broadcast_ch_id, message_id = MsgIds.MSG_ID_TD_BLOOD_PRESSURE_RESPONSE.value, function = self._handler_bp_rr_sync) self.blood_pressure_timestamp = 0.0 #: The timestamp of the latest message self.rr_timestamp = 0.0 #: The timestamp of the latest reject reason message self.rr_ack = False self.reject_reason = RequestRejectReasons.REQUEST_REJECT_REASON_NONE self.systolic = 0 self.diastolic = 0 self.heart_rate = 0 # ============================================================ Properties ============================================================ @property def rr_ack(self) -> bool: """ The Reject Reason message's Ack data """ return self._rr_ack @rr_ack.setter def rr_ack(self, value): self._rr_ack = value @property def reject_reason(self) -> RequestRejectReasons: """ The Reject Reason enum data """ return self._reject_reason @reject_reason.setter def reject_reason(self, value): self._reject_reason = value @property def systolic(self) -> int: """ The Patient's systolic blood pressure in mmHg """ return self._systolic @systolic.setter def systolic(self, value): self._systolic = value @property def diastolic(self) -> int: """ The Patient's diastolic blood pressure in mmHg """ return self._diastolic @diastolic.setter def diastolic(self, value): self._diastolic = value @property def heart_rate(self) -> int: """ The Patient's heart rate in PBM """ return self._heart_rate @heart_rate.setter def heart_rate(self, value): self._heart_rate = value # ============================================================ Handlers ============================================================ @publish(["msg_id_td_blood_pressure_data", "systolic", "diastolic", "heart_rate", "blood_pressure_timestamp"]) def _handler_bp_sync(self, message, timestamp=0.0): """ Handles published TD Blood Pressure data messages. Blood Pressure data are captured for reference. @param message: published data message @return: none """ msg_list =[] msg_list.append((type(self).systolic, DataTypes.U32)) msg_list.append((type(self).diastolic, DataTypes.U32)) msg_list.append((type(self).heart_rate, DataTypes.U32)) self.process_into_vars(decoder_list = msg_list, message = message) self.blood_pressure_timestamp = timestamp @publish(["msg_id_td_blood_pressure_response", "ack", "reject_reason", "rr_timestamp"]) def _handler_bp_rr_sync(self, message, timestamp=0.0): """ Handles published TD Blood Pressure Reject Reason data messages. Blood Pressure Reject Reason data are captured for reference. @param message: published data message @return: none """ msg_list =[] msg_list.append((type(self).ack, DataTypes.BOOL)) msg_list.append((type(self).reject_reason, DataTypes.U32)) self.process_into_vars(decoder_list = msg_list, message = message) self.reject_reason = RequestRejectReasons(self.reject_reason) self.rr_timestamp = timestamp # ============================================================ Overrides and Requests ============================================================ def cmd_send_ui_blood_pressure_request(self) -> None: """ Constructs and sends a UI request to measure blood pressure. :return: none """ return UIProxy(can_interface = self.can_interface, logger = self.logger).cmd_send_ui_blood_pressure_request()