Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -r6f6b6c076ce638b404534b2bf04cb3f986ee6b26 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 6f6b6c076ce638b404534b2bf04cb3f986ee6b26) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,20 +1,21 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 DialysateGenerator.py +# @file dialysate_generator.py # -# @date 31-Mar-2019 -# @author P. Lucia +# @author (last) Quang Nguyen +# @date (last) 09-Sep-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief This class allows sending to and receiving from the DG device. -# ############################################################################ import struct from .accelerometer import DGAccelerometer +from .alarms import DGAlarms from .drain_pump import DGDrainPump from .hd_proxy import DGHDProxy from .load_cells import DGLoadCells @@ -24,13 +25,11 @@ from .ro_pump import DGROPump from .heaters import Heaters from .temperature_sensors import TemperatureSensors -from ..protocols.CAN import (DenaliCanMessenger, - DenaliMessage, - DenaliChannels) +from .conductivity_sensors import ConductivitySensors +from ..protocols.CAN import (DenaliCanMessenger, DenaliMessage, DenaliChannels) +from ..utils.base import _AbstractSubSystem, _publish, _LogManager -from ..utils.base import _AbstractSubSystem, _publish - class DG(_AbstractSubSystem): """ Dialysate Generator (DG) Dialin object API. It provides the basic interface to communicate with @@ -63,6 +62,16 @@ START_POS_BUILD = END_POS_MICRO END_POS_BUILD = START_POS_BUILD + 2 + # FPGA + START_POS_FPGA_ID = END_POS_BUILD + END_POS_FPGA_ID = START_POS_FPGA_ID + 1 + START_POS_FPGA_MAJOR = END_POS_FPGA_ID + END_POS_FPGA_MAJOR = START_POS_FPGA_MAJOR + 1 + START_POS_FPGA_MINOR = END_POS_FPGA_MAJOR + END_POS_FPGA_MINOR = START_POS_FPGA_MINOR + 1 + START_POS_FPGA_LAB = END_POS_FPGA_MINOR + END_POS_FPGA_LAB = START_POS_FPGA_LAB + 1 + # DG operation modes DG_OP_MODE_FAULT = 0 DG_OP_MODE_SERVICE = 1 @@ -86,20 +95,28 @@ DG_POST_STATE_FAILED = 6 # POST failed state NUM_OF_DG_POST_STATES = 7 # Number of initialize & POST mode states - def __init__(self, can_interface="can0"): + def __init__(self, can_interface="can0", log_level=None): """ Initializes the DG object + For example: dg_object = DG(can_interface='can0') or - dg_object = DG('can0') + dg_object = DG(can_interface="can0", log_level="DEBUG") + Possible log levels: + ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "CAN_ONLY", "PRINT_ONLY"] + @param can_interface: string with can bus name, e.g. "can0" """ super().__init__() + self._log_manager = _LogManager(log_level=log_level, log_filepath=self.__class__.__name__+".log") + self.logger = self._log_manager.logger # Create listener - self.can_interface = DenaliCanMessenger(can_interface=can_interface) + self.can_interface = DenaliCanMessenger(can_interface=can_interface, + logger=self.logger, + log_can=self._log_manager.log_level == "CAN_ONLY") self.can_interface.start() # register handler for HD operation mode broadcast messages @@ -114,21 +131,23 @@ # initialize variables that will be populated by DG version response self.dg_version = None + self.fpga_version = None # create properties self.dg_operation_mode = self.DG_OP_MODE_INIT_POST self.dg_operation_sub_mode = 0 # Create command groups - self.accel = DGAccelerometer(self.can_interface) - self.hd_proxy = DGHDProxy(self.can_interface) - self.load_cells = DGLoadCells(self.can_interface) - self.pressures = DGPressures(self.can_interface) - self.reservoirs = DGReservoirs(self.can_interface) - self.valves = DGValves(self.can_interface) - self.ro_pump = DGROPump(self.can_interface) - self.drain_pump = DGDrainPump(self.can_interface) - self.heaters = Heaters(self.can_interface) - self.temperature_sensors = TemperatureSensors(self.can_interface) + self.hd_proxy = DGHDProxy(self.can_interface, self.logger) + self.load_cells = DGLoadCells(self.can_interface, self.logger) + self.pressures = DGPressures(self.can_interface, self.logger) + self.reservoirs = DGReservoirs(self.can_interface, self.logger) + self.valves = DGValves(self.can_interface, self.logger) + self.ro_pump = DGROPump(self.can_interface, self.logger) + self.drain_pump = DGDrainPump(self.can_interface, self.logger) + self.heaters = Heaters(self.can_interface, self.logger) + self.temperature_sensors = TemperatureSensors(self.can_interface, self.logger) + self.conductivity_sensors = ConductivitySensors(self.can_interface, self.logger) + self.alarms = DGAlarms(self.can_interface, self.logger) def get_version(self): """ @@ -138,6 +157,22 @@ """ return self.dg_version + def get_fpga_version(self): + """ + Gets the fpga version from the DG + + @return: The FPGA version + """ + return self.fpga_version + + def get_version(self): + """ + Gets the DG fpga version + + @return: The fpga version + """ + return self.dg_version + def get_operation_mode(self): """ Gets the operation mode @@ -154,7 +189,7 @@ """ return self.dg_operation_sub_mode - @_publish(["dg_version"]) + @_publish(["dg_version", "fpga_version"]) def _handler_dg_version(self, message): """ Handler for response from DG regarding its version. @@ -176,11 +211,22 @@ build = struct.unpack('H', bytearray( message['message'][self.START_POS_BUILD:self.END_POS_BUILD])) - if len(major) > 0 and len(minor) > 0 and len(micro) > 0 and len(build) > 0: + fpga_id = struct.unpack('B', bytearray( + message['message'][self.START_POS_FPGA_ID:self.END_POS_FPGA_ID])) + fpga_major = struct.unpack('B', bytearray( + message['message'][self.START_POS_FPGA_MAJOR:self.END_POS_FPGA_MAJOR])) + fpga_minor = struct.unpack('B', bytearray( + message['message'][self.START_POS_FPGA_MINOR:self.END_POS_FPGA_MINOR])) + fpga_lab = struct.unpack('B', bytearray( + message['message'][self.START_POS_FPGA_LAB:self.END_POS_FPGA_LAB])) + + if all([len(each) > 0 for each in [major, minor, micro, build]]): self.dg_version = f"v{major[0]}.{minor[0]}.{micro[0]}-{build[0]}" - print(self.dg_version) + self.logger.debug(f"DG VERSION: {self.dg_version}") - return self.dg_version + if all([len(each) > 0 for each in [fpga_major, fpga_minor, fpga_id, fpga_lab]]): + self.fpga_version = f"ID: {fpga_id[0]} v{fpga_major[0]}.{fpga_minor[0]}.{fpga_lab[0]}" + self.logger.debug(f"DG FPGA VERSION: {self.fpga_version}") @_publish(["dg_operation_mode", "dg_operation_sub_mode"]) def _handler_dg_op_mode_sync(self, message): @@ -212,19 +258,19 @@ message_id=self.MSG_ID_LOGIN_TO_DG, payload=list(map(int, map(ord, self.DG_LOGIN_PASSWORD)))) - print("login") + self.logger.info("Logging in to the DG...") # Send message received_message = self.can_interface.send(message) if received_message is not None: if received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] == 1: - print("Logged In") + self.logger.info("Successfully logged in to the DG.") else: - print("Log In Failed.") + self.logger.error("Log In Failed.") return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.error("Timeout!!!!") return False def cmd_ui_request_dg_version(self): @@ -236,7 +282,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=self.MSG_ID_DG_REQUEST_DG_VERSION) - print("Sending Dialin request for version to DG") + self.logger.debug("Sending Dialin request for version to DG") self.can_interface.send(message, 0) @@ -252,18 +298,18 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=self.MSG_ID_DG_SAFETY_SHUTDOWN_OVERRIDE) - print("overriding DG safety shutdown") + self.logger.debug("overriding DG safety shutdown") # Send message received_message = self.can_interface.send(message) if received_message is not None: if received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] == 1: - print("Safety shutdown signal overridden") + self.logger.debug("Safety shutdown signal overridden") else: - print("Safety shutdown signal override failed.") + self.logger.debug("Safety shutdown signal override failed.") return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/dg/drain_pump.py =================================================================== diff -u -r6f6b6c076ce638b404534b2bf04cb3f986ee6b26 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/dg/drain_pump.py (.../drain_pump.py) (revision 6f6b6c076ce638b404534b2bf04cb3f986ee6b26) +++ dialin/dg/drain_pump.py (.../drain_pump.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,25 +1,25 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 drain_pump.py +# @file drain_pump.py # -# @date 14-Apr-2020 -# @author S. Nash +# @author (last) Peter Lucia +# @date (last) 31-Aug-2020 +# @author (original) Sean +# @date (original) 14-Apr-2020 # -# @brief -# -# ############################################################################ import struct from ..utils.conversions import integer_to_bytearray from .constants import RESET, NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGDrainPump(_AbstractSubSystem): @@ -30,21 +30,21 @@ # Drain pump message IDs MSG_ID_DG_DRAIN_PUMP_PUBLISHED_DATA = 0x0024 MSG_ID_DG_DRAIN_PUMP_SET_SPEED_OVERRIDE = 0xA00B - MSG_ID_DG_DRAIN_PUMP_BROADAST_INTERVAL_OVERRIDE = 0xA00C, + MSG_ID_DG_DRAIN_PUMP_BROADAST_INTERVAL_OVERRIDE = 0xA00C # Drain pump broadcast message field positions START_POS_SET_SPD = DenaliMessage.PAYLOAD_START_INDEX END_POS_SET_SPD = START_POS_SET_SPD + 4 START_POS_DAC = END_POS_SET_SPD END_POS_DAC = START_POS_DAC + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ DGDrainPump constructor """ super().__init__() - self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id @@ -107,24 +107,24 @@ message_id=self.MSG_ID_DG_DRAIN_PUMP_SET_SPEED_OVERRIDE, payload=payload) - print("override drain pump speed set point") + self.logger.debug("override drain pump speed set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Drain pump set point overridden to " + str_res + " RPM: " + + self.logger.debug("Drain pump set point overridden to " + str_res + " RPM: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_drain_pump_data_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -147,23 +147,23 @@ message_id=self.MSG_ID_DG_DRAIN_PUMP_BROADAST_INTERVAL_OVERRIDE, payload=payload) - print("override drain pump data broadcast interval") + self.logger.debug("override drain pump data broadcast interval") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(mis) - print( + self.logger.debug( "Drain pump 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/dg/hd_proxy.py =================================================================== diff -u -r2cfc646e14640e82c5f6989a572737ce8256caa5 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 2cfc646e14640e82c5f6989a572737ce8256caa5) +++ dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,23 +1,23 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 hd_proxy.py +# @file hd_proxy.py # -# @date 14-Apr-2020 -# @author S. Nash +# @author (last) Peter Lucia +# @date (last) 26-Aug-2020 +# @author (original) Sean +# @date (original) 15-Apr-2020 # -# @brief -# -# ############################################################################ from ..utils.conversions import integer_to_bytearray from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGHDProxy(_AbstractSubSystem): @@ -39,13 +39,14 @@ RESERVOIR1 = 0 RESERVOIR2 = 1 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ @param can_interface: Denali CAN Messenger object """ super().__init__() self.can_interface = can_interface + self.logger = logger def cmd_switch_reservoirs(self, reservoirID=RESERVOIR1): """ @@ -69,7 +70,7 @@ message_id=self.MSG_ID_HD_SWITCH_RESERVOIRS_CMD, payload=payload) - print("switch reservoirs cmd sent to DG") + self.logger.debug("switch reservoirs cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -79,7 +80,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_fill(self, volume=1500): @@ -100,7 +101,7 @@ message_id=self.MSG_ID_HD_FILL_CMD, payload=payload) - print("fill cmd sent to DG") + self.logger.debug("fill cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -110,7 +111,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_drain(self, volume=200): @@ -131,7 +132,7 @@ message_id=self.MSG_ID_HD_DRAIN_CMD, payload=payload) - print("drain cmd sent to DG") + self.logger.debug("drain cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -141,7 +142,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_start_stop_dg(self, start=True): @@ -167,7 +168,7 @@ message_id=self.MSG_ID_HD_START_STOP_DG_CMD, payload=payload) - print(str+"DG cmd sent to DG") + self.logger.debug(str+"DG cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -177,7 +178,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_start_stop_trimmer_heater(self, start=True): @@ -200,7 +201,7 @@ message_id=self.MSG_ID_HD_START_STOP_DG_TRIMMER_HEATER, payload=payload) - print(str+"DG trimmer heater cmd sent to DG") + self.logger.debug(str+"DG trimmer heater cmd sent to DG") # Send message received_message = self.can_interface.send(message) @@ -210,7 +211,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_start_heat_disinfection(self): Index: dialin/dg/ro_pump.py =================================================================== diff -u -r2cfc646e14640e82c5f6989a572737ce8256caa5 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/dg/ro_pump.py (.../ro_pump.py) (revision 2cfc646e14640e82c5f6989a572737ce8256caa5) +++ dialin/dg/ro_pump.py (.../ro_pump.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,25 +1,25 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 ro_pump.py +# @file ro_pump.py # -# @date 14-Apr-2020 -# @author S. Nash +# @author (last) Peter Lucia +# @date (last) 26-Aug-2020 +# @author (original) Sean +# @date (original) 14-Apr-2020 # -# @brief -# -# ############################################################################ import struct from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET, NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGROPump(_AbstractSubSystem): @@ -50,14 +50,14 @@ RAMP_UP_STATE = 0 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ DGROPump constructor """ super().__init__() - self.can_interface = can_interface + self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id @@ -152,25 +152,25 @@ message_id=self.MSG_ID_RO_PUMP_SET_PT_OVERRIDE, payload=payload) - print("override RO pump pressure set point") + self.logger.debug("override RO pump pressure set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(pressure) - print( + self.logger.debug( "RO pump pressure set point overridden to " + str_res + " PSI: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_ro_flow_rate_override(self, flow, reset=NO_RESET): @@ -192,25 +192,25 @@ message_id=self.MSG_ID_RO_PUMP_SET_PT_OVERRIDE, payload=payload) - print("override RO pump pressure set point") + self.logger.debug("override RO pump pressure set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(flo) - print( + self.logger.debug( "RO flow rate overridden to " + str_res + " L/min: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_ro_pump_data_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -233,24 +233,24 @@ message_id=self.MSG_ID_DG_RO_PUMP_BROADCAST_INTERVAL_OVERRIDE, payload=payload) - print("override RO pump data broadcast interval") + self.logger.debug("override RO pump data broadcast interval") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(mis) - print( + self.logger.debug( "RO pump 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/dg/valves.py =================================================================== diff -u -r6f6b6c076ce638b404534b2bf04cb3f986ee6b26 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/dg/valves.py (.../valves.py) (revision 6f6b6c076ce638b404534b2bf04cb3f986ee6b26) +++ dialin/dg/valves.py (.../valves.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,25 +1,25 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 valves.py +# @file valves.py # -# @date 6-May-2020 -# @author P. Montazemi +# @author (last) Peter Lucia +# @date (last) 26-Aug-2020 +# @author (original) Peman Montazemi +# @date (original) 19-May-2020 # -# @brief -# -# ############################################################################ import struct from ..utils.conversions import integer_to_bytearray from .constants import NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger # Valve states ENERGIZED = True @@ -55,16 +55,15 @@ VALVE_RESERVOIR_2 = 11 # VR2 VALVE_PRODUCTION_DRAIN = 12 # VPD - - def __init__(self, can_interface=None): + 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.dg_sync_broadcast_ch_id @@ -123,29 +122,32 @@ self.valve_state_VPD.get("state", None) ] - def sort_by_id(self, observation): + @staticmethod + def sort_by_id(observation): """ Converts a published dictionary of valve state information to an ordered list of tuples. For example: >>> dg = DG() >>> observation = {'datetime': datetime.datetime(2020, 7, 13, 10, 43, 27, 433357), - 'valve_state_VBF': {'id': 5, 'state': True}, - 'valve_state_VDR': {'id': 7, 'state': True}, - 'valve_state_VPD': {'id': 12, 'state': True}, - 'valve_state_VPI': {'id': 8, 'state': True}, - 'valve_state_VPO': {'id': 4, 'state': True}, - 'valve_state_VR1': {'id': 10, 'state': True}, - 'valve_state_VR2': {'id': 11, 'state': True}, - 'valve_state_VRC': {'id': 6, 'state': True}, - 'valve_state_VRD': {'id': 2, 'state': True}, - 'valve_state_VRF': {'id': 0, 'state': True}, - 'valve_state_VRI': {'id': 1, 'state': True}, - 'valve_state_VRO': {'id': 3, 'state': True}, - 'valve_state_VSP': {'id': 9, 'state': True}, - 'valve_states_all': 8191} - >>> print(dg.valves.sort_by_id(observation)) + + 'valve_state_VBF': {'id': 5, 'state': True}, + 'valve_state_VDR': {'id': 7, 'state': True}, + 'valve_state_VPD': {'id': 12, 'state': True}, + 'valve_state_VPI': {'id': 8, 'state': True}, + 'valve_state_VPO': {'id': 4, 'state': True}, + 'valve_state_VR1': {'id': 10, 'state': True}, + 'valve_state_VR2': {'id': 11, 'state': True}, + 'valve_state_VRC': {'id': 6, 'state': True}, + 'valve_state_VRD': {'id': 2, 'state': True}, + 'valve_state_VRF': {'id': 0, 'state': True}, + 'valve_state_VRI': {'id': 1, 'state': True}, + 'valve_state_VRO': {'id': 3, 'state': True}, + 'valve_state_VSP': {'id': 9, 'state': True}, + 'valve_states_all': 8191} + >>> self.logger.debug(dg.valves.sort_by_id(observation)) + ('valve_state_VRF', 0, True) ('valve_state_VRI', 1, True) ('valve_state_VRD', 2, True) @@ -261,7 +263,7 @@ message_id=self.MSG_ID_DG_VALVE_STATE_OVERRIDE, payload=payload) - print("override valve state") + self.logger.debug("override valve state") # Send message received_message = self.can_interface.send(message) @@ -271,7 +273,7 @@ # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_valve_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -295,7 +297,7 @@ message_id=self.MSG_ID_DG_VALVES_STATES_PUBLISH_INTERVAL_OVERRIDE, payload=payload) - print("override valves states publish interval") + self.logger.debug("override valves states publish interval") # Send message received_message = self.can_interface.send(message) @@ -305,5 +307,5 @@ # Response payload is OK or not return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/hd/alarms.py =================================================================== diff -u -r50e6e3b5859850f154cbd59976f0f94565efcddc -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/hd/alarms.py (.../alarms.py) (revision 50e6e3b5859850f154cbd59976f0f94565efcddc) +++ dialin/hd/alarms.py (.../alarms.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,17 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 alarms.py +# @file alarms.py # -# @date 2-Apr-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 26-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# ############################################################################ from ..protocols.CAN import (DenaliMessage, DenaliChannels) @@ -20,6 +20,8 @@ from .constants import RESET, NO_RESET from collections import OrderedDict import struct +from logging import Logger +from ..common.alarm_defs import AlarmList class HDAlarms(_AbstractSubSystem): @@ -127,12 +129,13 @@ ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH = 58 ALARM_ID_INLET_WATER_TEMPERATURE_OUT_OF_RANGE = 59 - def __init__(self, can_interface): + 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_alarm_broadcast_ch_id @@ -160,10 +163,10 @@ self.alarm_states = [False] * 500 self.ids = OrderedDict() - for attr in dir(self): - if not callable(getattr(self, attr)) and attr.startswith("ALARM_ID"): - self.ids[attr] = getattr(self, attr) - self.ids = OrderedDict(sorted(self.ids.items(), key=lambda key: key[1])) + for attr in dir(AlarmList): + if not callable(getattr(AlarmList, attr)) and attr.startswith("ALARM_ID"): + self.ids[attr] = getattr(AlarmList, attr) + self.ids = OrderedDict(sorted(self.ids.items(), key=lambda key: key[1].value)) def get_alarm_states(self): """ @@ -173,19 +176,6 @@ """ return self.alarm_states - def get_alarms_state(self): - """ - Gets the alarms state - - None = 0 \n - Low = 1 \n - Medium = 2 \n - High = 3 \n - - @return: The alarms state - """ - return self.alarms_state - def get_alarms_top(self): """ Gets the top alarm @@ -214,6 +204,26 @@ """ Gets the alarms flags + Extract each flag from the flags int using bit-masking. E.g. + + System Fault = result & 1 + Stop = result & 2 + No Clear = result & 4 + No Resume = result & 8 + No Rinseback = result & 16 + No End Treatment = result & 32 + No New Treatment = result & 64 + Bypass Dialyzer = result & 128 + Alarms to Escalate = result & 256 + Alarms Silenced = result & 512 + TBD = result & 1024 + TBD = result & 2048 + TBD = result & 4096 + TBD = result & 8192 + TBD = result & 16384 + TBD = result & 32768 + TBD = result & 65536 + @return: (int) The alarms flags value """ return self.alarms_flags @@ -304,7 +314,7 @@ # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: @@ -335,24 +345,24 @@ message_id=self.MSG_ID_HD_ALARM_TIME_OVERRIDE, payload=payload) - print("override alarm time since activated") + self.logger.debug("override alarm time since activated") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(time_ms) - print("Alarm time since activated overridden to " + str_res + " ms: " + str( + self.logger.debug("Alarm time since activated 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: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_alarm_lamp_pattern_override(self, pattern, reset=NO_RESET): @@ -383,14 +393,14 @@ message_id=self.MSG_ID_HD_ALARM_LAMP_OVERRIDE, payload=payload) - print("Override Alarm Lamp Pattern") + self.logger.debug("Override Alarm Lamp Pattern") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - print(received_message) + self.logger.debug(received_message) if reset == RESET: str_pat = "reset back to normal" elif pattern == self.HD_ALARM_LAMP_PATTERN_OFF: @@ -407,19 +417,20 @@ str_pat = "low" else: str_pat = "manual" - print("Alarm lamp pattern overridden to " + str_pat + ":" + + self.logger.debug("Alarm lamp pattern overridden to " + str_pat + ":" + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def get_current_alarms_state(self): """ Gets the current alarms state. + None, Low, Medium, or High - @return: the current alarms state in text form. + @return: (str) the current alarms state in text form. """ result = "" if self.alarms_state == self.HD_ALARM_STATE_NONE: Index: dialin/hd/blood_flow.py =================================================================== diff -u -rd134777c4f35ca58a14720a668c155bed3b0c124 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/hd/blood_flow.py (.../blood_flow.py) (revision d134777c4f35ca58a14720a668c155bed3b0c124) +++ dialin/hd/blood_flow.py (.../blood_flow.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,18 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 bloodflow.py +# @file blood_flow.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 26-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# -# ############################################################################ from ..protocols.CAN import (DenaliMessage, DenaliChannels) @@ -21,6 +20,7 @@ from .constants import PUMP_CONTROL_MODE_CLOSED_LOOP, PUMP_CONTROL_MODE_OPEN_LOOP from ..utils.base import _AbstractSubSystem, _publish import struct +from logging import Logger class HDBloodFlow(_AbstractSubSystem): @@ -58,13 +58,13 @@ START_POS_PWM_DC = END_POS_MEAS_MC_CURR END_POS_PWM_DC = START_POS_PWM_DC + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HD_BloodFlow 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 @@ -114,17 +114,17 @@ def get_measured_blood_pump_mc_speed(self): """ - Gets the measured blood pump mc speed + Gets the measured blood pump motor controller speed - @return: The measured blood pump mc speed + @return: The measured blood pump motor controller speed """ return self.measured_blood_pump_mc_speed def get_measured_blood_pump_mc_current(self): """ - Gets the measured blood pump mc current + Gets the measured blood pump motor controller current - @return: the measured blood pump mc current + @return: the measured blood pump motor controller current """ return self.measured_blood_pump_mc_current @@ -197,29 +197,27 @@ message_id=self.MSG_ID_HD_BLOOD_FLOW_SET_RATE_OVERRIDE, payload=payload) - print("override blood flow set point") + self.logger.debug("override blood flow set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(flow) - if mode == PUMP_CONTROL_MODE_OPEN_LOOP: - str_mode = " (open loop): " - else: - str_mode = " (closed loop): " - print( - "Blood flow set point overridden to " + str_res + " mL/min" + str_mode + + + self.logger.debug( + "Blood flow set point overridden to " + str_res + " mL/min: " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_blood_flow_measured_override(self, flow, reset=NO_RESET): @@ -241,24 +239,24 @@ message_id=self.MSG_ID_HD_BLOOD_FLOW_MEAS_RATE_OVERRIDE, payload=payload) - print("override measured blood flow") + self.logger.debug("override measured blood flow") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(flow) - print("Blood flow (measured)) overridden to " + str_res + " mL/min: " + + self.logger.debug("Blood flow (measured)) overridden to " + str_res + " mL/min: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_blood_pump_mc_measured_speed_override(self, speed, reset=NO_RESET): @@ -281,29 +279,29 @@ message_id=self.MSG_ID_HD_BLOOD_PUMP_MC_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured blood pump motor controller speed") + self.logger.debug("override measured blood pump motor controller speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Blood pump MC speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Blood pump MC speed (measured) overridden to " + str_res + " RPM: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False - def cmd_blood_pump_measured_current_override(self, curr, reset=NO_RESET): + def cmd_measured_blood_pump_mc_current_override(self, curr, reset=NO_RESET): """ - Constructs and sends the measured blood pump motor current override command + Constructs and sends the measured blood pump motor controller current override command Constraints: Must be logged into HD. @@ -320,24 +318,24 @@ message_id=self.MSG_ID_HD_BLOOD_PUMP_MC_MEAS_CURRENT_OVERRIDE, payload=payload) - print("override measured blood pump motor controller current") + self.logger.debug("override measured blood pump motor controller current") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(curr) - print("Blood pump MC current (measured) overridden to " + str_res + " mA: " + + self.logger.debug("Blood pump MC current (measured) overridden to " + str_res + " mA: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_blood_pump_measured_speed_override(self, speed, reset=NO_RESET): @@ -360,27 +358,27 @@ message_id=self.MSG_ID_HD_BLOOD_PUMP_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured blood pump speed") + self.logger.debug("override measured blood pump speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Blood pump speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Blood pump speed (measured) overridden to " + str_res + " RPM: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False - def cmd_blood_pump_rotor_measured_speed_override(self, speed, reset=NO_RESET): + def cmd_blood_pump_measured_rotor_speed_override(self, speed, reset=NO_RESET): """ Constructs and sends the measured blood pump rotor speed override \n command. @@ -400,24 +398,24 @@ message_id=self.MSG_ID_HD_BLOOD_PUMP_ROTOR_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured blood pump rotor speed") + self.logger.debug("override measured blood pump rotor speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Blood pump rotor speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Blood pump rotor speed (measured) overridden to " + str_res + " RPM: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_blood_flow_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -440,24 +438,24 @@ message_id=self.MSG_ID_HD_BLOOD_FLOW_PUBLISH_INTERVAL_OVERRIDE, payload=payload) - print("override blood flow broadcast interval") + self.logger.debug("override blood flow broadcast interval") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal: " else: str_res = str(ms) + " ms: " - print("Blood flow broadcast interval overridden to " + str_res + + self.logger.debug("Blood flow broadcast interval overridden to " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_set_blood_flow_calibration(self, gain, offset): Index: dialin/hd/constants.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/hd/constants.py (.../constants.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/constants.py (.../constants.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -16,5 +16,9 @@ RESET = 1 NO_RESET = 0 + BUTTON_PRESSED = 1 BUTTON_RELEASED = 0 + +PUMP_CONTROL_MODE_CLOSED_LOOP = 0 +PUMP_CONTROL_MODE_OPEN_LOOP = 1 Index: dialin/hd/dialysate_inlet_flow.py =================================================================== diff -u -rd134777c4f35ca58a14720a668c155bed3b0c124 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/hd/dialysate_inlet_flow.py (.../dialysate_inlet_flow.py) (revision d134777c4f35ca58a14720a668c155bed3b0c124) +++ dialin/hd/dialysate_inlet_flow.py (.../dialysate_inlet_flow.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,18 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 dialysate_inlet_flow.py +# @file dialysate_inlet_flow.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 26-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# -# ############################################################################ import struct from ..protocols.CAN import (DenaliMessage, @@ -21,6 +20,7 @@ from .constants import RESET, NO_RESET from .constants import PUMP_CONTROL_MODE_CLOSED_LOOP, PUMP_CONTROL_MODE_OPEN_LOOP from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDDialysateInletFlow(_AbstractSubSystem): """ @@ -57,13 +57,14 @@ START_POS_PWM_DC = END_POS_MEAS_MC_CURR END_POS_PWM_DC = START_POS_PWM_DC + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HD_DialysateFlow 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 @@ -197,29 +198,27 @@ message_id=self.MSG_ID_HD_DIAL_IN_FLOW_SET_RATE_OVERRIDE, payload=payload) - print("override dialysate flow set point") + self.logger.debug("override dialysate flow set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(flow) - if mode == PUMP_CONTROL_MODE_OPEN_LOOP: - str_mode = " (open loop): " - else: - str_mode = " (closed loop): " - print( - "Dialysate flow set point overridden to " + str_res + " mL/min" + str_mode + + + self.logger.debug( + "Dialysate flow set point overridden to " + str_res + " mL/min: " + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_flow_measured_override(self, flow, reset=NO_RESET): @@ -241,24 +240,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_FLOW_MEAS_RATE_OVERRIDE, payload=payload) - print("override measured dialysate flow") + self.logger.debug("override measured dialysate flow") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(flow) - print("Dialysate flow (measured)) overridden to " + str_res + " mL/min: " + + self.logger.debug("Dialysate flow (measured)) overridden to " + str_res + " mL/min: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_pump_mc_measured_speed_override(self, speed, reset=NO_RESET): @@ -281,24 +280,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_PUMP_MC_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump motor controller speed") + self.logger.debug("override measured dialysate inlet pump motor controller speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Dialysate pump MC speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Dialysate pump MC speed (measured) overridden to " + str_res + " RPM: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_pump_measured_current_override(self, curr, reset=NO_RESET): @@ -320,24 +319,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_PUMP_MC_MEAS_CURRENT_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump motor controller current") + self.logger.debug("override measured dialysate inlet pump motor controller current") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(curr) - print("Dialysate inlet pump MC current (measured) overridden to " + str_res + " mA: " + + self.logger.debug("Dialysate inlet pump MC current (measured) overridden to " + str_res + " mA: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_pump_measured_speed_override(self, speed, reset=NO_RESET): @@ -360,24 +359,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_PUMP_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump speed") + self.logger.debug("override measured dialysate inlet pump speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Dialysate inlet pump speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Dialysate inlet pump speed (measured) overridden to " + str_res + " RPM: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_pump_rotor_measured_speed_override(self, speed, reset=NO_RESET): @@ -400,24 +399,24 @@ message_id=self.MSG_ID_HD_DIAL_IN_PUMP_ROTOR_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump rotor speed") + self.logger.debug("override measured dialysate inlet pump rotor speed") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) - print("Dialysate inlet pump rotor speed (measured) overridden to " + str_res + " RPM: " + + self.logger.debug("Dialysate inlet pump rotor speed (measured) overridden to " + str_res + " RPM: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_inlet_flow_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -440,7 +439,7 @@ message_id=self.MSG_ID_HD_DIAL_IN_FLOW_PUBLISH_INTERVAL_OVERRIDE, payload=payload) - print("override dialysate inlet flow broadcast interval") + self.logger.debug("override dialysate inlet flow broadcast interval") # Send message received_message = self.can_interface.send(message) @@ -451,12 +450,12 @@ str_res = "reset back to normal: " else: str_res = str(ms) + " ms: " - print("Dialysate inlet flow broadcast interval overridden to " + str_res + + self.logger.debug("Dialysate inlet flow broadcast interval overridden to " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_set_dialysate_flow_calibration(self, gain, offset): Index: dialin/hd/dialysate_outlet_flow.py =================================================================== diff -u -rd134777c4f35ca58a14720a668c155bed3b0c124 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/hd/dialysate_outlet_flow.py (.../dialysate_outlet_flow.py) (revision d134777c4f35ca58a14720a668c155bed3b0c124) +++ dialin/hd/dialysate_outlet_flow.py (.../dialysate_outlet_flow.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,18 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 dialysate_outlet_flow.py +# @file dialysate_outlet_flow.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 26-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# -# ############################################################################ import struct from ..protocols.CAN import (DenaliMessage, @@ -21,6 +20,7 @@ from .constants import RESET, NO_RESET from .constants import PUMP_CONTROL_MODE_CLOSED_LOOP, PUMP_CONTROL_MODE_OPEN_LOOP from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDDialysateOutletFlow(_AbstractSubSystem): @@ -57,12 +57,13 @@ START_POS_PWM_DC = END_POS_MEAS_MC_CURR END_POS_PWM_DC = START_POS_PWM_DC + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HDDialysateFlow 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 @@ -239,25 +240,25 @@ message_id=self.MSG_ID_HD_DIAL_OUT_UF_REF_VOLUME_OVERRIDE, payload=payload) - print("override UF reference volume with " + str(refvol) + "mL.") + self.logger.debug("override UF reference volume with " + str(refvol) + "mL.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(refvol) + " mL. " - print( + self.logger.debug( "UF reference volume " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_measured_uf_volume_override(self, measvol, reset=NO_RESET): @@ -279,24 +280,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_UF_MEAS_VOLUME_OVERRIDE, payload=payload) - print("override measured UF volume with " + str(measvol) + " mL.") + self.logger.debug("override measured UF volume with " + str(measvol) + " mL.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(measvol) + " mL. " - print("UF measured volume " + str_res + + self.logger.debug("UF measured volume " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_mc_measured_speed_override(self, speed, reset=NO_RESET): @@ -319,24 +320,24 @@ message_id=self.measured_dialysate_outlet_pump_mc_speed, payload=payload) - print("override measured dialysate outlet pump motor controller speed to " + str(spd) + " RPM.") + self.logger.debug("override measured dialysate outlet pump motor controller speed to " + str(spd) + " RPM.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate outlet pump MC speed (measured) " + str_res + + self.logger.debug("Dialysate outlet pump MC speed (measured) " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_measured_current_override(self, curr, reset=NO_RESET): @@ -358,24 +359,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_MC_MEAS_CURRENT_OVERRIDE, payload=payload) - print("override measured dialysate outlet pump motor controller current") + self.logger.debug("override measured dialysate outlet pump motor controller current") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(curr) + " mA. " - print("Dialysate outlet pump MC current (measured) " + str_res + + self.logger.debug("Dialysate outlet pump MC current (measured) " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_measured_speed_override(self, speed, reset=NO_RESET): @@ -398,24 +399,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate outlet pump speed to " + str(speed) + " RPM.") + self.logger.debug("override measured dialysate outlet pump speed to " + str(speed) + " RPM.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate outlet pump speed (measured) " + str_res + + self.logger.debug("Dialysate outlet pump speed (measured) " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_rotor_measured_speed_override(self, speed, reset=NO_RESET): @@ -438,24 +439,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_ROTOR_MEAS_SPEED_OVERRIDE, payload=payload) - print("override measured dialysate outlet pump rotor speed to " + str(speed) + " RPM.") + self.logger.debug("override measured dialysate outlet pump rotor speed to " + str(speed) + " RPM.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate outlet pump rotor speed (measured) " + str_res + + self.logger.debug("Dialysate outlet pump rotor speed (measured) " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_flow_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -478,24 +479,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_FLOW_PUBLISH_INTERVAL_OVERRIDE, payload=payload) - print("override dialysate outlet flow broadcast interval to " + str(ms) + " ms.") + self.logger.debug("override dialysate outlet flow broadcast interval to " + str(ms) + " ms.") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(ms) + " ms. " - print("Dialysate outlet flow broadcast interval " + str_res + + self.logger.debug("Dialysate outlet flow broadcast interval " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_dialysate_outlet_pump_load_cell_weight_override(self, weight, sensor, reset=NO_RESET): @@ -526,24 +527,24 @@ message_id=self.MSG_ID_HD_DIAL_OUT_LOAD_CELL_WEIGHT_OVERRIDE, payload=payload) - print("override measured load cell weight to " + str(weight) + " grams for load cell # " + str(sensor)) + self.logger.debug("override measured load cell weight to " + str(weight) + " grams for load cell # " + str(sensor)) # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - # print(received_message) + # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal. " else: str_res = "overridden to " + str(weight) + " grams. " - print("Load cell # " + str(sensor) + " " + str_res + + self.logger.debug("Load cell # " + str(sensor) + " " + str_res + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_set_load_cell_weights(self, r1p, r1b, r2p, r2b): @@ -567,7 +568,7 @@ message_id=self.MSG_ID_HD_LOAD_CELL_READINGS, payload=payload) - print("measured load cell weights set.") + self.logger.debug("measured load cell weights set.") # Send message self.can_interface.send(message, 0) Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -r6f6b6c076ce638b404534b2bf04cb3f986ee6b26 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 6f6b6c076ce638b404534b2bf04cb3f986ee6b26) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,18 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 hemodialysis_device.py +# @file hemodialysis_device.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 26-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief This class provides the basic interface to communicate with -# the HD board. -# ############################################################################ import struct from .accelerometer import HDAccelerometer @@ -29,7 +28,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliCanMessenger, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, _LogManager from .constants import NO_RESET from ..utils.conversions import integer_to_bytearray @@ -43,6 +42,7 @@ MSG_ID_HD_OPERATION_MODE_BROADCAST = 0x0025 MSG_ID_LOGIN_TO_HD = 0x8000 MSG_ID_HD_SAFETY_SHUTDOWN_OVERRIDE = 0x8026 + MSG_ID_POWEROFF_NOTIFY = 0x0020 # broadcast message field positions START_POS_HD_OP_MODE = DenaliMessage.PAYLOAD_START_INDEX @@ -66,19 +66,27 @@ def __init__(self, can_interface="can0", log_level=None): """ - HD constructor using can bus + HD object provides test/service commands for the HD sub-system. + >> hd_object = HD('can0') + >> hd_object = HD(can_interface='can0', log_level="DEBUG") + + Possible log levels: + ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "CAN_ONLY", "PRINT_ONLY"] + @param can_interface: (str) CANBus interface name, e.g. "can0" - @return: HD object provides test/service commands for the HD sub-system. + @param log_level: (str) Logging level, defaults to None - >> hd_object = HD(can_interface='can0') - >> hd_object = HD('can0') """ super().__init__() + self._log_manager = _LogManager(log_level=log_level, log_filepath=self.__class__.__name__+".log") + self.logger = self._log_manager.logger # Create listener - self.can_interface = DenaliCanMessenger(can_interface=can_interface, log_level=log_level) + self.can_interface = DenaliCanMessenger(can_interface=can_interface, + logger=self.logger, + log_can=self._log_manager.log_level == "CAN_ONLY") self.can_interface.start() # register handler for HD operation mode broadcast messages @@ -93,17 +101,16 @@ self.hd_operation_sub_mode = 0 # Create command groups - self.accel = HDAccelerometer(self.can_interface) - self.alarms = HDAlarms(self.can_interface) - self.buttons = HDButtons(self.can_interface) - self.ui = HDUIProxy(self.can_interface) - self.rtc = HDRTC(self.can_interface) - self.watchdog = HDWatchdog(self.can_interface) - self.bloodflow = HDBloodFlow(self.can_interface) - self.dialysate_inlet_flow = HDDialysateInletFlow(self.can_interface) - self.dialysate_outlet_flow = HDDialysateOutletFlow(self.can_interface) - self.treatment = HDTreatment(self.can_interface) - self.pressure_occlusion = HDPressureOcclusion(self.can_interface) + self.alarms = HDAlarms(self.can_interface, self.logger) + self.buttons = HDButtons(self.can_interface, self.logger) + self.ui = HDUIProxy(self.can_interface, self.logger) + self.rtc = HDRTC(self.can_interface, self.logger) + self.watchdog = HDWatchdog(self.can_interface, self.logger) + self.bloodflow = HDBloodFlow(self.can_interface, self.logger) + self.dialysate_inlet_flow = HDDialysateInletFlow(self.can_interface, self.logger) + self.dialysate_outlet_flow = HDDialysateOutletFlow(self.can_interface, self.logger) + self.treatment = HDTreatment(self.can_interface, self.logger) + self.pressure_occlusion = HDPressureOcclusion(self.can_interface, self.logger) def get_operation_mode(self): """ @@ -142,19 +149,19 @@ message_id=self.MSG_ID_LOGIN_TO_HD, payload=list(map(int, map(ord, self.HD_LOGIN_PASSWORD)))) - print("Logging in...") + self.logger.debug("Logging in...") # Send message received_message = self.can_interface.send(message) if received_message is not None: if received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] == 1: - print("Success: Logged In") + self.logger.debug("Success: Logged In") else: - print("Failure: Log In Failed.") + self.logger.debug("Failure: Log In Failed.") return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Login Timeout!!!!") + self.logger.debug("Login Timeout!!!!") return False def cmd_hd_safety_shutdown_override(self, active=True, reset=NO_RESET): @@ -183,17 +190,17 @@ message_id=self.MSG_ID_HD_SAFETY_SHUTDOWN_OVERRIDE, payload=payload) - print("overriding HD safety shutdown") + self.logger.debug("overriding HD safety shutdown") # Send message received_message = self.can_interface.send(message) if received_message is not None: if received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] == 1: - print("Safety shutdown signal overridden") + self.logger.debug("Safety shutdown signal overridden") else: - print("Safety shutdown signal override failed.") + self.logger.debug("Safety shutdown signal override failed.") return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/hd/rtc.py =================================================================== diff -u -r4c82155574ae155fcb658f4c81ca852f65b71193 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/hd/rtc.py (.../rtc.py) (revision 4c82155574ae155fcb658f4c81ca852f65b71193) +++ dialin/hd/rtc.py (.../rtc.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,24 +1,24 @@ ########################################################################### # -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# Copyright (c) 2019-2020 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. +# 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 rtc.py +# @file rtc.py # -# @date 31-Mar-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 21-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief -# -# ############################################################################ import ctypes from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.conversions import integer_to_bytearray from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDRTC(_AbstractSubSystem): @@ -34,15 +34,15 @@ START_POS_SET_PT = DenaliMessage.PAYLOAD_START_INDEX END_POS_SET_PT = START_POS_SET_PT + 4 - def __init__(self, can_interface=None): + 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 @@ -72,37 +72,45 @@ byteorder=DenaliMessage.BYTE_ORDER) self.rtc_epoch = ctypes.c_uint32(epoch) - def cmd_set_rtc_time_and_date(self, secs, mins, hours, days, months, years): + def cmd_set_rtc_time_and_date(self, second: int, minute: int, hour: int, day: int, month: int, year: int): """ - Constructs and sends the time and date to be written to rtc + Sets the RTC time and date from the provided - @return: 1 if successful, zero otherwise + @param second: (int) Second + @param minute: (int) Minute + @param hour: (int) Hour + @param day: (int) Day + @param month: (int) Month + @param year: (int) Year + @return: 1 if Successful, False otherwise """ - sec = bytes([secs]) - mint = bytes([mins]) - hour = bytes([hours]) - day = bytes([days]) - month = bytes([months]) - year = integer_to_bytearray(years) + sec = bytes([second]) + mint = bytes([minute]) + hour = bytes([hour]) + day = bytes([day]) + month = bytes([month]) + year = integer_to_bytearray(year) payload = sec + mint + hour + day + month + year message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, message_id=self.MSG_ID_SET_RTC_DATE_TIME, payload=payload) - print("Setting time and date to rtc") + self.logger.debug("Setting time and date to rtc") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - print(received_message) - print("Time and Date in rtc set to seconds: " + str(secs) + " minutes: " + str(mins) + " hours: " + - str(hours) + " days: " + str(days) + " months: " + str(months) + " years: " + str(years) + + + self.logger.debug(received_message) + # str_res = str(flow) + self.logger.debug("Time and Date in rtc set to seconds: " + str(sec) + " minutes: " + str(min) + " hours: " + + str(hour) + " days: " + str(day) + " months: " + str(month) + " years: " + str(year) + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False Index: dialin/squish/unittests.py =================================================================== diff -u -r63f32da409c04f95d4dfc788f1a30d6299e85273 -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- dialin/squish/unittests.py (.../unittests.py) (revision 63f32da409c04f95d4dfc788f1a30d6299e85273) +++ dialin/squish/unittests.py (.../unittests.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1,12 +1,44 @@ +# -*- coding: utf-8 -*- +########################################################################### +# +# Copyright (c) 2019-2020 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 unittests.py +# +# @author (last) Peter Lucia +# @date (last) 10-Jul-2020 +# @author (original) Peter Lucia +# @date (original) 09-Jul-2020 +# +############################################################################ +## +# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# copyright +# 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 unittests.py +# date 2019/11/20 +# author Behrouz NematiPour +# import test import sys -from .crc import calcCRC8 +from subprocess import check_output +from dialin.squish import crc +MICRO = [8, 9] + + def test_python_version(): - test.compare(sys.version_info.major,3) - test.compare(sys.version_info.minor,6) - test.compare(sys.version_info.micro in [8,9], True) + test.compare(sys.version_info.major, 3) + test.compare(sys.version_info.minor, 6) + + test.compare(sys.version_info.micro in MICRO, True) def test_crc8(): strByte1 = ( "4B 43 09 00 14 00 00" @@ -31,7 +63,19 @@ "00 00" #7F ) - test.compare(calcCRC8(strByte1, ' '), '9D') - test.compare(calcCRC8(strByte2, ' '), '55') - test.compare(calcCRC8(strByte3, ' '), '4F') - test.compare(calcCRC8(strByte4, ' '), '7F') + test.compare(crc.calcCRC8(strByte1, ' '), '9D') + test.compare(crc.calcCRC8(strByte2, ' '), '55') + test.compare(crc.calcCRC8(strByte3, ' '), '4F') + test.compare(crc.calcCRC8(strByte4, ' '), '7F') + +def test_can0(): + canid = "can0" + ipa = "ip a" + ipa = check_output(ipa, shell=True) + loc = str(ipa).find(canid) + fnd = loc >= 0 + if (fnd): + msg = "can device '{}' found".format(canid) + else: + msg = "No can device registered as '{}'".format(canid) + test.compare(loc >= 0, True, msg) Index: version.py =================================================================== diff -u -r5818c70699fbe02a31d136f440baee0d9f2cb39d -ra2add7d5c768ab21eba0c61e5ec5c7e84b75eeab --- version.py (.../version.py) (revision 5818c70699fbe02a31d136f440baee0d9f2cb39d) +++ version.py (.../version.py) (revision a2add7d5c768ab21eba0c61e5ec5c7e84b75eeab) @@ -1 +1,69 @@ -dialin/version.py \ No newline at end of file +########################################################################### +# +# Copyright (c) 2019-2020 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 version.py +# +# @author (last) Peter Lucia +# @date (last) 01-Sep-2020 +# @author (original) Peter Lucia +# @date (original) 16-Jun-2020 +# +############################################################################ +import subprocess + +VERSION = "0.7.0" + + +def get_branch(): + """ + Gets the current branch name in the current git repository + + @return: The current branch name, None if it can't be determined + """ + + try: + subprocess.check_output("git rev-parse --abbrev-ref HEAD", shell=True).decode("utf-8").strip() + except subprocess.CalledProcessError: + return None + + +def get_last_commit(): + """ + Gets the latest commit in the current git repository + + @return: (str) the latest commit in the current git repository, None if it can't be determined + """ + try: + return subprocess.check_output("git rev-parse --short=7 HEAD", shell=True).decode("utf-8").strip() + except subprocess.CalledProcessError: + return None + + +def check_if_git_repo(): + """ + Checks if we're in a git repo or not to know if we can get the git branch and commit + + @return: True if in a git repo, False otherwise + """ + + return subprocess.call(["git", "branch"], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) == 0 + + +branch = None +commit = None + +DEV_VERSION = VERSION + +if check_if_git_repo(): + branch = get_branch() + commit = get_last_commit() + DEV_VERSION += "-{0}".format(branch) + DEV_VERSION += "-{0}".format(commit) + + +if __name__ == '__main__': + print(VERSION)