Index: dialin/common/msg_ids.py =================================================================== diff -u -r94a543f6b3f0d408b46637dbd831e98219755f47 -r452264e8979100b5110f8629aee08168ad509fb0 --- dialin/common/msg_ids.py (.../msg_ids.py) (revision 94a543f6b3f0d408b46637dbd831e98219755f47) +++ dialin/common/msg_ids.py (.../msg_ids.py) (revision 452264e8979100b5110f8629aee08168ad509fb0) @@ -177,7 +177,7 @@ MSG_ID_HD_SET_STANDBY_DISINFECT_SUB_MODE_REQUEST = 0X9A MSG_ID_HD_SET_STANDBY_DISINFECT_SUB_MODE_RESPONSE = 0X9B MSG_ID_HD_DISINFECTS_UI_STATE_READINGS = 0X9C - MSG_ID___AVAILABLE_1 = 0x9D + MSG_ID_HD_TEMPERATURES_DATA = 0x9D MSG_ID_HD_UI_VERSION_INFO_REQUEST = 0x9E MSG_ID_HD_UI_VERSION_INFO_RESPONSE = 0x9F MSG_ID_REQUEST_HD_USAGE_INFO = 0XA0 @@ -282,6 +282,9 @@ MSG_ID_HD_BLOOD_PRIME_SAFETY_VOLUME_OVERRIDE = 0X8061 MSG_ID_HD_SWITCHES_STATUS_OVERRIDE = 0X8062 MSG_ID_HD_SWITCHES_PUBLISH_INTERVAL_OVERRIDE = 0X8063 + MSG_ID_HD_BATTERY_REMAINING_PERCENT_OVERRIDE = 0x8064 + MSG_ID_HD_TEMPERATURES_VALUE_OVERRIDE = 0x8065 + MSG_ID_HD_TEMPERATURES_PUBLISH_INTERVAL_OVERRIDE = 0x8066 MSG_ID_DG_TESTER_LOGIN_REQUEST = 0XA000 MSG_ID_DG_ALARM_STATE_OVERRIDE = 0XA001 MSG_ID_DG_WATCHDOG_TASK_CHECKIN_OVERRIDE = 0XA002 Index: dialin/hd/switches.py =================================================================== diff -u -rc4776c1885f259b231532ef5ba7e904178cd0005 -r452264e8979100b5110f8629aee08168ad509fb0 --- dialin/hd/switches.py (.../switches.py) (revision c4776c1885f259b231532ef5ba7e904178cd0005) +++ dialin/hd/switches.py (.../switches.py) (revision 452264e8979100b5110f8629aee08168ad509fb0) @@ -55,10 +55,9 @@ @_publish(["hd_switches_status"]) def _handler_switches_sync(self, message): """ - Handles published drain pump data messages. Switches data are captured - for reference. + Handles published HD switches data messages. Switches data are captured for reference. - @param message: published drain pump data message + @param message: published switches data message @return: none """ front_door = struct.unpack('i', bytearray( Index: dialin/hd/temperatures.py =================================================================== diff -u --- dialin/hd/temperatures.py (revision 0) +++ dialin/hd/temperatures.py (revision 452264e8979100b5110f8629aee08168ad509fb0) @@ -0,0 +1,163 @@ + + + +import struct +from ..utils.conversions import integer_to_bytearray +from ..common.msg_defs import MsgIds, MsgFieldPositions +from .constants import RESET, NO_RESET +from ..protocols.CAN import (DenaliMessage, DenaliChannels) +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum +from ..utils.checks import check_broadcast_interval_override_ms +from logging import Logger +from enum import unique + + +@unique +class HDTemperaturesNames(DialinEnum): + + THERMISTOR_ONBOARD_NTC = 0 + THERMISTOR_POWER_SUPPLY_1 = 1 + TEMPSENSOR_FPGA_BOARD = 2 + TEMPSENSOR_VENOUS_PRESS_TEMP = 3 + TEMPSENSOR_PBA_ADC_SENSOR = 4 + + +class HDTemperatures(_AbstractSubSystem): + """ + @brief Hemodialysis Device (HD) Dialin API sub-class for HD temperatures related commands. + """ + + def __init__(self, can_interface, logger: Logger): + """ + HDTemperatures constructor + + """ + super().__init__() + + self.can_interface = can_interface + self.logger = logger + + if self.can_interface is not None: + channel_id = DenaliChannels.hd_sync_broadcast_ch_id + msg_id = MsgIds.MSG_ID_HD_TEMPERATURES_DATA.value + self.can_interface.register_receiving_publication_function(channel_id, msg_id, + self._handler_temperatures_sync) + + self.hd_temperatures = {HDTemperaturesNames.THERMISTOR_ONBOARD_NTC.name: 0.0, + HDTemperaturesNames.THERMISTOR_POWER_SUPPLY_1.name: 0.0, + HDTemperaturesNames.TEMPSENSOR_FPGA_BOARD.name: 0.0, + HDTemperaturesNames.TEMPSENSOR_VENOUS_PRESS_TEMP.name: 0.0, + HDTemperaturesNames.TEMPSENSOR_PBA_ADC_SENSOR.name: 0.0} + + def get_hd_temperatures_values(self) -> dict: + """ + Gets the status of HD temperature sensors + + @return: The HD temperatures values in a dictionary + """ + return self.hd_temperatures + + @_publish(["hd_temperatures"]) + def _handler_temperatures_sync(self, message): + """ + Handles published HD temperatures data messages. Temperatures data are captured for reference. + + @param message: published temperatures data message + @return: none + """ + onboard_thermistor = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + power_supply_thermistor = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + fpga_board_sensor = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + venous_pressure_sensor_temp = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] + pba_adc_sensor = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] + + self.hd_temperatures[HDTemperaturesNames.THERMISTOR_ONBOARD_NTC.name] = onboard_thermistor + self.hd_temperatures[HDTemperaturesNames.THERMISTOR_POWER_SUPPLY_1.name] = power_supply_thermistor + self.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_FPGA_BOARD.name] = fpga_board_sensor + self.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_VENOUS_PRESS_TEMP.name] = venous_pressure_sensor_temp + self.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_PBA_ADC_SENSOR.name] = pba_adc_sensor + + def cmd_hd_temperatures_value_override(self, sensor: int, value: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the HD temperatures value override command + Constraints: + Must be logged into HD. + + @param sensor: (int) sensor ID that is status is overridden + @param value: (int) value that the temperature sensor will be overridden to + @param reset: (int) 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + reset_value = integer_to_bytearray(reset) + snsr = integer_to_bytearray(sensor) + vl = integer_to_bytearray(value) + payload = reset_value + vl + snsr + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_TEMPERATURES_VALUE_OVERRIDE.value, + payload=payload) + + self.logger.debug("Override temperature sensor value") + + # Send message + received_message = self.can_interface.send(message) + + # If there is no content... + if received_message is not None: + + self.logger.debug("Switch " + str(HDTemperaturesNames(sensor).name) + " to: " + + 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_hd_temperatures_data_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the HD temperatures data publication override command. + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: (int) interval (in ms) to override with + @param reset: (int) 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 + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_TEMPERATURES_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("Override HD temperatures data broadcast interval") + + # 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 = str(mis) + self.logger.debug( + "HD temperatures data broadcast interval overridden to " + str_res + " ms: " + + 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