Index: dialin/common/msg_ids.py =================================================================== diff -u -r452264e8979100b5110f8629aee08168ad509fb0 -r5b95fe318aeec36597d8fbbdbba1d54b1d48f380 --- dialin/common/msg_ids.py (.../msg_ids.py) (revision 452264e8979100b5110f8629aee08168ad509fb0) +++ dialin/common/msg_ids.py (.../msg_ids.py) (revision 5b95fe318aeec36597d8fbbdbba1d54b1d48f380) @@ -183,6 +183,7 @@ MSG_ID_REQUEST_HD_USAGE_INFO = 0XA0 MSG_ID_DG_SWITCHES_DATA = 0xA1 MSG_ID_HD_SWITCHES_DATA = 0xA2 + MSG_ID_HD_FANS_DATA = 0xA3 MSG_ID_CAN_ERROR_COUNT = 0X999 MSG_ID_TESTER_LOGIN_REQUEST = 0X8000 MSG_ID_DIAL_OUT_FLOW_SET_PT_OVERRIDE = 0X8001 @@ -285,6 +286,7 @@ 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_HD_FANS_PUBLISH_INTERVAL_OVERRIDE = 0x8067 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/fans.py =================================================================== diff -u --- dialin/hd/fans.py (revision 0) +++ dialin/hd/fans.py (revision 5b95fe318aeec36597d8fbbdbba1d54b1d48f380) @@ -0,0 +1,118 @@ + + +import struct +from ..utils.conversions import integer_to_bytearray +from ..utils.checks import check_broadcast_interval_override_ms +from .constants import NO_RESET, RESET +from ..common.msg_defs import MsgIds, MsgFieldPositions +from ..protocols.CAN import (DenaliMessage, DenaliChannels) +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum +from logging import Logger +from enum import unique + + +@unique +class FansNames(DialinEnum): + + FAN_INLET_1 = 0 + + +class HDFans(_AbstractSubSystem): + """ + @brief Hemodialysis Device (HD) Dialin API sub-class for fans related commands. + """ + + def __init__(self, can_interface, logger: Logger): + """ + + @param can_interface: Denali CAN Messenger object + """ + + 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_FANS_DATA.value + self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_fans_sync) + + # Publish variables + self.target_duty_cycle = 0.0 + self.inlet_1_rpm = 0.0 + + def get_fans_target_duty_cycle(self): + """ + Gets the fans target duty cycle + + @return: Fans target duty cycle + """ + return self.target_duty_cycle + + def get_fan_inlet_1_rpm(self): + """ + Gets the inlet 1 fan RPM + + @return: Fan inlet 1 RPM + """ + return self.inlet_1_rpm + + @_publish(['target_duty_cycle', 'inlet_1_rpm']) + def _handler_fans_sync(self, message): + """ + Handles published thermistors message. + + @param message: published thermistors message + @return: none + """ + tgt_pwm = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + inlet_1_rpm = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + + self.target_duty_cycle = tgt_pwm + self.inlet_1_rpm = inlet_1_rpm + + def cmd_fans_data_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the fans data publish interval. + 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_FANS_PUBLISH_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("Override fans data publish 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( + "Fans 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 \ No newline at end of file Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -rc19568936f7925714a39b7951eae672ab91769a4 -r5b95fe318aeec36597d8fbbdbba1d54b1d48f380 --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision c19568936f7925714a39b7951eae672ab91769a4) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 5b95fe318aeec36597d8fbbdbba1d54b1d48f380) @@ -37,6 +37,8 @@ from .pretreatment import HDPreTreatment from .syringe_pump import HDSyringePump from .switches import HDSwitches +from .temperatures import HDTemperatures +from .fans import HDFans from ..protocols.CAN import (DenaliMessage, DenaliCanMessenger, DenaliChannels) @@ -118,6 +120,8 @@ self.system_record = HDSystemNVRecords(self.can_interface, self.logger) self.service_record = HDServiceNVRecords(self.can_interface, self.logger) self.switches = HDSwitches(self.can_interface, self.logger) + self.temperatures = HDTemperatures(self.can_interface, self.logger) + self.fans = HDFans(self.can_interface, self.logger) def get_operation_mode(self): """ Index: dialin/hd/system_record.py =================================================================== diff -u -r94a543f6b3f0d408b46637dbd831e98219755f47 -r5b95fe318aeec36597d8fbbdbba1d54b1d48f380 --- dialin/hd/system_record.py (.../system_record.py) (revision 94a543f6b3f0d408b46637dbd831e98219755f47) +++ dialin/hd/system_record.py (.../system_record.py) (revision 5b95fe318aeec36597d8fbbdbba1d54b1d48f380) @@ -195,7 +195,7 @@ result = OrderedDict() groups_byte_size = 0 # create a list of the functions of the sub dictionaries - functions = [self._prepare_hd_system_record()] + functions = [self._prepare_hd_system_group()] for function in functions: # Update the groups bytes size so far to be use to padding later @@ -221,7 +221,7 @@ return result - def _prepare_hd_system_record(self): + def _prepare_hd_system_group(self): """ Handles creating the system record dictionary. Index: tests/peter/test_hd_records.py =================================================================== diff -u -rc4776c1885f259b231532ef5ba7e904178cd0005 -r5b95fe318aeec36597d8fbbdbba1d54b1d48f380 --- tests/peter/test_hd_records.py (.../test_hd_records.py) (revision c4776c1885f259b231532ef5ba7e904178cd0005) +++ tests/peter/test_hd_records.py (.../test_hd_records.py) (revision 5b95fe318aeec36597d8fbbdbba1d54b1d48f380) @@ -81,11 +81,13 @@ hd = HD(log_level="DEBUG") if hd.cmd_log_in_to_hd(resend=False): - #hd.calibration_record.cmd_reset_hd_calibration_record() + hd.calibration_record.cmd_reset_hd_calibration_record() + print(hd.calibration_record.hd_calibration_record) hd.system_record.cmd_reset_hd_system_record() - #hd.service_record.cmd_reset_hd_service_record() + hd.service_record.cmd_reset_hd_service_record() + def test_hd_system_record(): hd = HD(log_level="DEBUG") if hd.cmd_log_in_to_hd(resend=False): @@ -100,8 +102,8 @@ with open("/home/fw/projects/dialin/tests/peter/hd_sys_record_old.log", 'w') as f: f.write(record_old_formatted) - hd.system_record.hd_system_record["system_record"]["top_level_pn"][1] = "ASD-S1234" - hd.system_record.hd_system_record["system_record"]["top_level_sn"][1] = "ASD-S1234" + hd.system_record.hd_system_record['system_record']['top_level_pn'][1] = 'ASD-S123' + hd.system_record.hd_system_record["system_record"]["top_level_sn"][1] = 'ASD-S1234' hd.system_record.hd_system_record["system_record"]["mfg_location"][1] = 9 hd.system_record.hd_system_record["system_record"]["crc"][1] = \ NVOpsUtils.get_group_record_crc(hd.system_record.hd_system_record["system_record"]) Index: tests/test_hd_dg_fans.py =================================================================== diff -u --- tests/test_hd_dg_fans.py (revision 0) +++ tests/test_hd_dg_fans.py (revision 5b95fe318aeec36597d8fbbdbba1d54b1d48f380) @@ -0,0 +1,27 @@ + +from dialin import HD +from dialin.hd.temperatures import HDTemperaturesNames + + +def test_fans_info(): + info = ('Target_fans_DC, {:5.3f}, Inlet1_RPM, {:5.3f}, Board_temp, {:5.3f}, Power_supply_temp, {:5.3f} ' + ' FPGA_temp, {:5.3f}, Venous_temp, {:5.3f}, pba_adc_temp, {:5.3f}, ' + .format(hd.fans.target_duty_cycle, hd.fans.inlet_1_rpm, + hd.temperatures.hd_temperatures[HDTemperaturesNames.THERMISTOR_ONBOARD_NTC.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.THERMISTOR_POWER_SUPPLY_1.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_FPGA_BOARD.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_VENOUS_PRESS_TEMP.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_PBA_ADC_SENSOR.name])) + return info + + +if __name__ == "__main__": + + # Create an instance of the DG Class + hd = HD(log_level='DEBUG') + + if hd.cmd_log_in_to_hd() == 0: + exit(1) + + fans = test_fans_info() + print(fans) \ No newline at end of file