Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -27,7 +27,7 @@ DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, _LogManager class DG(_AbstractSubSystem): @@ -85,20 +85,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 @@ -118,15 +126,15 @@ self.dg_operation_sub_mode = 0 # Create command groups - 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) def get_version(self): """ @@ -176,7 +184,7 @@ if len(major) > 0 and len(minor) > 0 and len(micro) > 0 and len(build) > 0: self.dg_version = f"v{major[0]}.{minor[0]}.{micro[0]}-{build[0]}" - print(self.dg_version) + self.logger.debug(self.dg_version) return self.dg_version @@ -210,19 +218,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): @@ -234,7 +242,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) @@ -251,18 +259,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 -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/drain_pump.py (.../drain_pump.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/drain_pump.py (.../drain_pump.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,6 +19,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGDrainPump(_AbstractSubSystem): @@ -37,15 +38,14 @@ 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 - @param outer_instance: reference to the DG (outer) class. """ 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 @@ -106,24 +106,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): @@ -143,23 +143,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 -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -17,6 +17,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGHDProxy(_AbstractSubSystem): @@ -36,13 +37,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): """ @@ -63,7 +65,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) @@ -73,7 +75,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): @@ -91,7 +93,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) @@ -101,7 +103,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): @@ -119,7 +121,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) @@ -129,7 +131,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): @@ -152,7 +154,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) @@ -162,7 +164,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): @@ -185,7 +187,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) @@ -195,6 +197,6 @@ # 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/heaters.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/heaters.py (.../heaters.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/heaters.py (.../heaters.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -20,7 +20,9 @@ from .constants import NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger + class Heaters(_AbstractSubSystem): MSG_ID_DG_HEATERS_DATA = 0x2C @@ -36,11 +38,12 @@ START_POS_TRIMMER_HEATER = END_POS_SMALL_PRI_HEATER END_POS_TRIMMER_HEATER = START_POS_TRIMMER_HEATER + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): super().__init__() - self.can_interface = can_interface + self.logger = logger + self.main_primary_heater_pwm = 0 self.small_primary_heater_pwm = 0 self.trimmer_heater_pwm = 0 @@ -81,7 +84,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=self.MSG_ID_START_STOP_PRIMARY_HEATER, payload=payload) - print("Starting the Primary heater") + self.logger.debug("Starting the Primary heater") self.can_interface.send(message, 0) def cmd_stop_primary_heater(self): @@ -95,7 +98,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=self.MSG_ID_START_STOP_PRIMARY_HEATER, payload=payload) - print("Stopping the Primary heater") + self.logger.debug("Stopping the Primary heater") self.can_interface.send(message, 0) def cmd_start_trimmer_heater(self): @@ -109,7 +112,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=self.MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD, payload=payload) - print("Starting the Trimmer heater") + self.logger.debug("Starting the Trimmer heater") self.can_interface.send(message, 0) def cmd_stop_trimmer_heater(self): @@ -123,7 +126,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=self.MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD, payload=payload) - print("Stopping the Trimmer heater") + self.logger.debug("Stopping the Trimmer heater") self.can_interface.send(message, 0) def cmd_set_dialysate_target_temperature(self, pirmary_target_temp=37.0, trimmer_target_temp=38.0): @@ -140,7 +143,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=self.MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS, payload=payload) - print("Setting Primary Heater to {} C and Trimmer Heater to {} C".format(pirmary_target_temp, trimmer_target_temp)) + self.logger.debug("Setting Primary Heater to {} C and Trimmer Heater to {} C".format(pirmary_target_temp, trimmer_target_temp)) self.can_interface.send(message, 0) def cmd_heaters_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -159,7 +162,7 @@ message_id=self.MSG_ID_HEATERS_PUBLISH_INTERVAL_ORVERRIDE, payload=payload) - print("Sending {} ms publish interval to the Heaters module".format(ms)) + self.logger.debug("Sending {} ms publish interval to the Heaters module".format(ms)) # Send message received_message = self.can_interface.send(message) @@ -168,7 +171,7 @@ # 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/dg/load_cells.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/load_cells.py (.../load_cells.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/load_cells.py (.../load_cells.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,6 +19,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGLoadCells(_AbstractSubSystem): @@ -49,14 +50,14 @@ LOAD_CELL_B1 = 2 LOAD_CELL_B2 = 3 - 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 @@ -126,7 +127,7 @@ message_id=self.MSG_ID_DG_LOAD_CELL_OVERRIDE, payload=payload) - print("override load cell weight value for sensor " + str(sensor)) + self.logger.debug("override load cell weight value for sensor " + str(sensor)) # Send message received_message = self.can_interface.send(message) @@ -136,7 +137,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_load_cell_data_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -156,7 +157,7 @@ message_id=self.MSG_ID_DG_LOAD_CELL_DATA_BROADCAST_INTERVAL_OVERRIDE, payload=payload) - print("override DG load cell broadcast interval") + self.logger.debug("override DG load cell broadcast interval") # Send message received_message = self.can_interface.send(message) @@ -167,11 +168,11 @@ str_res = "reset back to normal: " else: str_res = str(ms) + " ms: " - print("Load cell data broadcast interval overridden to " + str_res + + self.logger.debug("Load cell data 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 Index: dialin/dg/pressures.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/pressures.py (.../pressures.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/pressures.py (.../pressures.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,7 +19,9 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger + class DGPressures(_AbstractSubSystem): """ DG interface containing pressure related commands. @@ -46,15 +48,15 @@ PRESSURE_SENSOR_DRAIN_PUMP_INLET = 2 PRESSURE_SENSOR_DRAIN_PUMP_OUTLET = 3 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ @param can_interface: The DenaliCANMessenger 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 @@ -132,7 +134,7 @@ message_id=self.MSG_ID_DG_PRESSURE_OVERRIDE, payload=payload) - print("override pressure sensor") + self.logger.debug("override pressure sensor") # Send message received_message = self.can_interface.send(message) @@ -142,7 +144,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_pressure_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -163,7 +165,7 @@ message_id=self.MSG_ID_DG_PRESSURE_DATA_BROADCAST_INTERVAL_OVERRIDE, payload=payload) - print("override pressure data broadcast interval") + self.logger.debug("override pressure data broadcast interval") # Send message received_message = self.can_interface.send(message) @@ -173,5 +175,5 @@ # 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/reservoirs.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/reservoirs.py (.../reservoirs.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/reservoirs.py (.../reservoirs.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -17,6 +17,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGReservoirs(_AbstractSubSystem): @@ -39,15 +40,15 @@ RESERVOIR1 = 0 RESERVOIR2 = 1 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ @param can_interface: The DenaliCANMessenger 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 Index: dialin/dg/ro_pump.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/ro_pump.py (.../ro_pump.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/ro_pump.py (.../ro_pump.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,6 +19,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class DGROPump(_AbstractSubSystem): @@ -42,14 +43,14 @@ START_POS_PWM = END_POS_MEAS_FLOW END_POS_PWM = START_POS_PWM + 4 - 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 @@ -124,25 +125,25 @@ message_id=self.MSG_ID_DG_RO_PUMP_PRESSURE_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): @@ -162,25 +163,25 @@ message_id=self.MSG_ID_DG_RO_FLOW_RATE_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): @@ -200,24 +201,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/temperature_sensors.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/temperature_sensors.py (.../temperature_sensors.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/temperature_sensors.py (.../temperature_sensors.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,7 +19,9 @@ from .constants import NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger + class TemperatureSensors(_AbstractSubSystem): MSG_ID_DG_TEMPERATURE_DATA = 0x2D @@ -63,12 +65,12 @@ START_POS_TRI_INTERNAL_TEMP = END_POS_PRI_INTERNAL_TEMP END_POS_TRI_INTERNAL_TEMP = START_POS_TRI_INTERNAL_TEMP + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): super().__init__() self.can_interface = can_interface - + self.logger = logger self.inlet_primary = 0.0 self.outlet_primary = 0.0 self.cd1 = 0.0 @@ -160,7 +162,7 @@ message_id=self.MSG_ID_TEMPERATURE_SENSORS_PUBLISH_INTERVAL_OVERRIDE, payload=payload) - print("Sending {} ms publish interval to the Temperature Sensors module".format(ms)) + self.logger.debug("Sending {} ms publish interval to the Temperature Sensors module".format(ms)) # Send message received_message = self.can_interface.send(message) @@ -169,7 +171,7 @@ # Response payload is OK or not return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: - print("Timeout!!!!") + self.logger.debug("Timeout!!!!") return False def cmd_temperature_sensors_override_value(self, sensor_index, sensor_value, reset=NO_RESET): @@ -190,7 +192,7 @@ message_id=self.MSG_ID_TEMPERATURE_SENSORS_VALUE_OVERRIDE, payload=payload) - print("Setting sensor {} to {} C".format(sensor_index, sensor_value)) + self.logger.debug("Setting sensor {} to {} C".format(sensor_index, sensor_value)) # Send message received_message = self.can_interface.send(message) @@ -200,6 +202,6 @@ # 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/dg/valves.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/dg/valves.py (.../valves.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/dg/valves.py (.../valves.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,6 +19,7 @@ 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 @@ -54,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 @@ -122,7 +122,8 @@ 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. @@ -144,7 +145,7 @@ '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)) + >>> self.logger.debug(dg.valves.sort_by_id(observation)) ('valve_state_VRF', 0, True) ('valve_state_VRI', 1, True) ('valve_state_VRD', 2, True) @@ -257,7 +258,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) @@ -267,7 +268,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): @@ -288,7 +289,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) @@ -298,5 +299,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 -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/alarms.py (.../alarms.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/alarms.py (.../alarms.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -20,6 +20,7 @@ from .constants import RESET, NO_RESET from collections import OrderedDict import struct +from logging import Logger class HDAlarms(_AbstractSubSystem): @@ -127,12 +128,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 @@ -308,7 +310,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: @@ -336,24 +338,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): @@ -381,14 +383,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: @@ -405,12 +407,12 @@ 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): Index: dialin/hd/blood_flow.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/blood_flow.py (.../blood_flow.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/blood_flow.py (.../blood_flow.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,6 +19,7 @@ from .constants import RESET, NO_RESET from ..utils.base import _AbstractSubSystem, _publish import struct +from logging import Logger class HDBloodFlow(_AbstractSubSystem): @@ -55,15 +56,15 @@ 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 @param outer_instance: reference to the HD (outer) class. """ 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 @@ -191,25 +192,25 @@ 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) - print( + 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): @@ -229,24 +230,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): @@ -267,24 +268,24 @@ 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): @@ -304,24 +305,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): @@ -342,24 +343,24 @@ 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): @@ -380,24 +381,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): @@ -417,22 +418,22 @@ 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 Index: dialin/hd/buttons.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/buttons.py (.../buttons.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/buttons.py (.../buttons.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -14,10 +14,12 @@ # ############################################################################ from ..protocols.CAN import (DenaliMessage, + DenaliCanMessenger, DenaliChannels) from ..utils.conversions import integer_to_bytearray from .constants import RESET, NO_RESET from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDButtons(_AbstractSubSystem): @@ -29,17 +31,43 @@ MSG_ID_HD_OFF_BUTTON_OVERRIDE = 0x8002 MSG_ID_HD_STOP_BUTTON_OVERRIDE = 0x8003 - def __init__(self, can_interface): + MSG_ID_HD_POWEROFF_TIMEOUT = 0x000E + + PRESSED = 1 + RELEASED = 0 + + def __init__(self, can_interface: DenaliCanMessenger, logger: Logger): """ HD_Buttons constructor @param can_interface: the denali can interface object """ super().__init__() - self.can_interface = can_interface + self.logger = logger + self.poweroff_timeout_expired = False + self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_ui_ch_id, + self.MSG_ID_HD_POWEROFF_TIMEOUT, + self._handler_poweroff_timeout_occurred) + + def get_power_timeout_expired(self): + """ + Gets the poweroff timeout expired status + + @return: True if expired, False otherwise + """ + + return self.poweroff_timeout_expired + + @_publish(["poweroff_timeout_expired"]) + def _handler_poweroff_timeout_occurred(self): + pass + + + + def cmd_off_button_override(self, state, reset=NO_RESET): """ Constructs and sends the Off button override command @@ -58,7 +86,7 @@ message_id=self.MSG_ID_HD_OFF_BUTTON_OVERRIDE, payload=payload) - print("override off button") + self.logger.debug("override off button") # Send message received_message = self.can_interface.send(message) @@ -70,12 +98,12 @@ else: str_res = ("pressed" if state != 0 else "released") - print("Off button overridden to " + str_res + ":" + + self.logger.debug("Off button 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_stop_button_override(self, state, reset=NO_RESET): @@ -96,7 +124,7 @@ message_id=self.MSG_ID_HD_STOP_BUTTON_OVERRIDE, payload=payload) - print("override stop button") + self.logger.debug("override stop button") # Send message received_message = self.can_interface.send(message) @@ -107,11 +135,11 @@ str_res = "reset back to normal" else: str_res = ("pressed" if state != 0 else "released") - print("Stop button overridden to " + str_res + ":" + + self.logger.debug("Stop button 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 Index: dialin/hd/dialysate_inlet_flow.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/dialysate_inlet_flow.py (.../dialysate_inlet_flow.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/dialysate_inlet_flow.py (.../dialysate_inlet_flow.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,6 +19,7 @@ from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET, NO_RESET from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDDialysateInletFlow(_AbstractSubSystem): """ @@ -54,13 +55,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 @@ -189,25 +191,25 @@ 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) - print( + 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): @@ -227,24 +229,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): @@ -265,24 +267,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): @@ -302,24 +304,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): @@ -340,24 +342,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): @@ -378,24 +380,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): @@ -415,7 +417,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) @@ -426,10 +428,10 @@ 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 Index: dialin/hd/dialysate_outlet_flow.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/dialysate_outlet_flow.py (.../dialysate_outlet_flow.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/dialysate_outlet_flow.py (.../dialysate_outlet_flow.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,6 +19,7 @@ from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET, NO_RESET from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDDialysateOutletFlow(_AbstractSubSystem): @@ -54,12 +55,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 @@ -187,25 +189,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): @@ -225,24 +227,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): @@ -263,24 +265,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): @@ -300,24 +302,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): @@ -338,24 +340,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): @@ -376,24 +378,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): @@ -413,24 +415,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): @@ -458,24 +460,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): @@ -499,7 +501,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 -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -27,7 +27,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliCanMessenger, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, _LogManager class HD(_AbstractSubSystem): @@ -40,6 +40,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 @@ -63,19 +64,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 @@ -90,16 +99,16 @@ self.hd_operation_sub_mode = 0 # Create command groups - 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): """ @@ -138,19 +147,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): @@ -168,17 +177,17 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, message_id=self.MSG_ID_HD_SAFETY_SHUTDOWN_OVERRIDE) - 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/pressure_occlusion.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/pressure_occlusion.py (.../pressure_occlusion.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/pressure_occlusion.py (.../pressure_occlusion.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -19,6 +19,7 @@ from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET, NO_RESET from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDPressureOcclusion(_AbstractSubSystem): @@ -47,13 +48,14 @@ START_POS_DOP_OCCL = END_POS_DIP_OCCL END_POS_DOP_OCCL = START_POS_DOP_OCCL + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HDPressureOcclusion 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 @@ -156,7 +158,7 @@ message_id=self.MSG_ID_HD_PRESSURE_ARTERIAL_OVERRIDE, payload=payload) - print("override measured arterial pressure") + self.logger.debug("override measured arterial pressure") # Send message received_message = self.can_interface.send(message) @@ -167,12 +169,12 @@ str_res = "reset back to normal. " else: str_res = str(pres) + " mmHg. " - print("Arterial pressure (measured)) overridden to " + str_res + + self.logger.debug("Arterial pressure (measured)) 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_venous_pressure_measured_override(self, pres, reset=NO_RESET): @@ -193,7 +195,7 @@ message_id=self.MSG_ID_HD_PRESSURE_VENOUS_OVERRIDE, payload=payload) - print("override measured venous pressure") + self.logger.debug("override measured venous pressure") # Send message received_message = self.can_interface.send(message) @@ -204,12 +206,12 @@ str_res = "reset back to normal. " else: str_res = str(pres) + " mmHg. " - print("Venous pressure (measured) overridden to " + str_res + + self.logger.debug("Venous pressure (measured) 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_blood_pump_measured_occlusion_override(self, occl, reset=NO_RESET): @@ -229,7 +231,7 @@ message_id=self.MSG_ID_HD_OCCLUSION_BLOOD_PUMP_OVERRIDE, payload=payload) - print("override measured blood pump occlusion pressure") + self.logger.debug("override measured blood pump occlusion pressure") # Send message received_message = self.can_interface.send(message) @@ -240,12 +242,12 @@ str_res = "reset back to normal. " else: str_res = str(occl) + " mmHg. " - print("Blood pump occlusion pressure (measured) overridden to " + str_res + + self.logger.debug("Blood pump occlusion pressure (measured) 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_dialysate_inlet_pump_measured_occlusion_override(self, occl, reset=NO_RESET): @@ -266,7 +268,7 @@ message_id=self.MSG_ID_HD_OCCLUSION_DIAL_IN_PUMP_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump occlusion pressure") + self.logger.debug("override measured dialysate inlet pump occlusion pressure") # Send message received_message = self.can_interface.send(message) @@ -277,12 +279,12 @@ str_res = "reset back to normal. " else: str_res = str(occl) + " mmHg. " - print("Dialysate inlet pump occlusion pressure (measured) overridden to " + str_res + + self.logger.debug("Dialysate inlet pump occlusion pressure (measured) 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_dialysate_outlet_pump_measured_occlusion_override(self, occl, reset=NO_RESET): @@ -303,7 +305,7 @@ message_id=self.MSG_ID_HD_OCCLUSION_DIAL_OUT_PUMP_OVERRIDE, payload=payload) - print("override measured dialysate outlet pump occlusion pressure") + self.logger.debug("override measured dialysate outlet pump occlusion pressure") # Send message received_message = self.can_interface.send(message) @@ -314,12 +316,12 @@ str_res = "reset back to normal. " else: str_res = str(occl) + " mmHg. " - print("Dialysate outlet pump occlusion pressure (measured) overridden to " + str_res + + self.logger.debug("Dialysate outlet pump occlusion pressure (measured) 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_pressure_occlusion_broadcast_interval_override(self, ms, reset=NO_RESET): @@ -339,7 +341,7 @@ message_id=self.MSG_ID_HD_PRES_OCCL_SEND_INTERVAL_OVERRIDE, payload=payload) - print("override pressure/occlusion broadcast interval") + self.logger.debug("override pressure/occlusion broadcast interval") # Send message received_message = self.can_interface.send(message) @@ -350,12 +352,12 @@ str_res = "reset back to normal: " else: str_res = str(ms) + " ms: " - print("Pressure/occlusion broadcast interval overridden to " + str_res + + self.logger.debug("Pressure/occlusion 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 # TEST CODE *************************************** Index: dialin/hd/rtc.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/rtc.py (.../rtc.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/rtc.py (.../rtc.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -18,6 +18,7 @@ DenaliChannels) from ..utils.conversions import integer_to_bytearray from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDRTC(_AbstractSubSystem): @@ -33,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 @@ -89,20 +90,20 @@ 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) + self.logger.debug(received_message) # str_res = str(flow) - print("Time and Date in rtc set to seconds: " + str(sec) + " minutes: " + str(min) + " hours: " + + 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/hd/treatment.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/treatment.py (.../treatment.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/treatment.py (.../treatment.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -17,6 +17,7 @@ from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDTreatment(_AbstractSubSystem): @@ -46,14 +47,14 @@ START_POS_SALINE_BOLUS_IN_PROGRESS = END_POS_UF_STATE END_POS_SALINE_BOLUS_IN_PROGRESS = START_POS_SALINE_BOLUS_IN_PROGRESS + 4 - def __init__(self, can_interface=None): + def __init__(self, can_interface, logger: Logger): """ HDTreatment 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 Index: dialin/hd/ui_proxy.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -18,6 +18,8 @@ from ..utils.conversions import integer_to_bytearray, float_to_bytearray import struct from ..utils.base import _AbstractSubSystem, _publish +from collections import OrderedDict +from logging import Logger class HDUIProxy(_AbstractSubSystem): @@ -48,6 +50,24 @@ RESPONSE_REJECTED = 0 RESPONSE_ACCEPTED = 1 + REQUEST_REJECT_REASON_NONE = 0 + REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE = 1 + REQUEST_REJECT_REASON_TIMEOUT_WAITING_FOR_USER_CONFIRM = 2 + REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE = 3 + REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE = 4 + REQUEST_REJECT_REASON_TREATMENT_TOO_CLOSE_TO_FINISHED = 5 + REQUEST_REJECT_REASON_TREATMENT_TIME_OUT_OF_RANGE = 6 + REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT = 7 + REQUEST_REJECT_REASON_BLOOD_FLOW_OUT_OF_RANGE = 8 + REQUEST_REJECT_REASON_DIAL_FLOW_OUT_OF_RANGE = 9 + REQUEST_REJECT_REASON_DIAL_VOLUME_OUT_OF_RANGE = 10 + REQUEST_REJECT_REASON_UF_VOLUME_OUT_OF_RANGE = 11 + REQUEST_REJECT_REASON_UF_RATE_OUT_OF_RANGE = 12 + REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_MINIMUM = 13 + REQUEST_REJECT_REASON_UF_NOT_IN_PROGESS = 14 + REQUEST_REJECT_REASON_UF_NOT_PAUSED = 15 + REQUEST_REJECT_REASON_SALINE_BOLUS_IN_PROGRESS = 16 + # HD version message field positions START_POS_MAJOR = DenaliMessage.PAYLOAD_START_INDEX END_POS_MAJOR = START_POS_MAJOR + 1 @@ -122,15 +142,15 @@ START_POS_BLD_DIAL_CHG_RSP_DIAL_RATE = END_POS_BLD_DIAL_CHG_RSP_BLD_RATE END_POS_BLD_DIAL_CHG_RSP_DIAL_RATE = START_POS_BLD_DIAL_CHG_RSP_DIAL_RATE + 4 - def __init__(self, can_interface): + def __init__(self, can_interface, logger: Logger): """ @param can_interface: the denali can interface object """ super().__init__() - self.can_interface = can_interface + self.logger = logger # register function to handle HD response to UF change requests if self.can_interface is not None: @@ -181,6 +201,12 @@ self.target_blood_flow_rate = 0 self.target_dialysate_flow_rate = 0 + self.reject_reasons = OrderedDict() + for attr in dir(self): + if not callable(getattr(self, attr)) and attr.startswith("REQUEST_REJECT"): + self.reject_reasons[attr] = getattr(self, attr) + self.reject_reasons = OrderedDict(sorted(self.reject_reasons.items(), key=lambda key: key[1])) + def get_hd_version(self): """ Gets the hd version @@ -253,6 +279,14 @@ """ return self.duration_change_reject_reason + def get_reject_reasons(self): + """ + Gets all possible reject reasons + + @return: OrderedDict(), {"": ... } + """ + return self.reject_reasons + def get_duration_change_time_min(self): """ Gets the duration change time @@ -273,7 +307,7 @@ """ Gets the uf change succeeded status - @return: The uf change succeeded status + @return: True if succeeded, False otherwise """ return self.uf_change_succeeded @@ -381,7 +415,7 @@ if len(major) > 0 and len(minor) > 0 and len(micro) > 0 and len(build) > 0: self.hd_version = f"v{major[0]}.{minor[0]}.{micro[0]}-{build[0]}" - print(self.hd_version) + self.logger.debug(self.hd_version) return self.hd_version @_publish([ @@ -597,7 +631,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, message_id=self.MSG_ID_UI_CHECKIN_WITH_HD) - print("Sending ui checkin w/ HD") + self.logger.debug("Sending ui checkin w/ HD") self.can_interface.send(message, 0) @@ -612,7 +646,7 @@ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, message_id=self.MSG_ID_UI_REQUEST_HD_VERSION) - print("Sending ui request for version to HD") + self.logger.debug("Sending ui request for version to HD") self.can_interface.send(message, 0) @@ -634,7 +668,7 @@ str_cmd = "pause" else: str_cmd = "resume" - print("Sending UF " + str_cmd + " command.") + self.logger.debug("Sending UF " + str_cmd + " command.") self.can_interface.send(message, 0) @@ -657,7 +691,7 @@ message_id=self.MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER, payload=volume) - print("Sending UF settings change request.") + self.logger.debug("Sending UF settings change request.") self.can_interface.send(message, 0) @@ -684,7 +718,7 @@ message_id=self.MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER, payload=payload) - print("Sending UF settings change request.") + self.logger.debug("Sending UF settings change request.") self.can_interface.send(message, 0) @@ -711,7 +745,7 @@ message_id=self.MSG_ID_UF_SETTINGS_CHANGE_CONFIRMED_BY_USER, payload=payload) - print("Sending UF settings change confirmation.") + self.logger.debug("Sending UF settings change confirmation.") self.can_interface.send(message, 0) @@ -731,7 +765,7 @@ message_id=self.MSG_ID_TREATMENT_DURATION_SETTING_CHANGE_REQUEST, payload=payload) - print("Sending treatment duration setting change request.") + self.logger.debug("Sending treatment duration setting change request.") # Send message self.can_interface.send(message, 0) @@ -755,7 +789,7 @@ message_id=self.MSG_ID_BLOOD_DIALYSATE_FLOW_SETTING_CHANGE_REQUEST_BY_USER, payload=payload) - print("Sending blood & dialysate flow rate settings change request.") + self.logger.debug("Sending blood & dialysate flow rate settings change request.") self.can_interface.send(message, 0) Index: dialin/hd/watchdog.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/hd/watchdog.py (.../watchdog.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/hd/watchdog.py (.../watchdog.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -18,6 +18,7 @@ from ..utils.conversions import integer_to_bytearray from .constants import RESET, NO_RESET from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger class HDWatchdog(_AbstractSubSystem): @@ -28,15 +29,15 @@ # watchdog message IDs MSG_ID_HD_WD_CHECKIN_OVERRIDE = 0x8005 - def __init__(self, can_interface): + def __init__(self, can_interface, logger: Logger): """ @param can_interface: the denali can interface object """ super().__init__() - self.can_interface = can_interface + self.logger = logger def cmd_watchdog_task_check_in_override(self, state, task, reset=NO_RESET): """ @@ -57,22 +58,22 @@ message_id=self.MSG_ID_HD_WD_CHECKIN_OVERRIDE, payload=payload) - print("override watchdog task check-in state") + self.logger.debug("override watchdog task check-in state") # 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 = ("checked in" if state != 0 else "not checked in") - print("watchdog task check-in overridden to " + str_res + ":" + + self.logger.debug("watchdog task check-in 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 Index: dialin/protocols/CAN.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/protocols/CAN.py (.../CAN.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/protocols/CAN.py (.../CAN.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -17,11 +17,9 @@ import threading import can import math -import time from time import sleep import sys -import logging -import os +from logging import Logger class DenaliMessage: @@ -342,15 +340,19 @@ START_BYTE = DenaliMessage.START_BYTE DIALIN_MSG_RESP_TO = 0.1 # number of seconds to wait for a response to a sent command - def __init__(self, can_interface='can0', log_level=None): + def __init__(self, can_interface: str, logger: Logger, log_can=False): """ DenaliCanMessenger constructor @param can_interface - string containing the can interface, e.g., 'can0" @return: DialityCanMessenger object """ + super().__init__() + self.bus = can.interfaces.socketcan.SocketcanBus(channel=can_interface) + self.logger = logger + self.log_can = log_can self.listener_buffer = can.BufferedReader() self.notifier = can.Notifier(self.bus, [self.listener_buffer]) self.send_packet_request_id = -1 @@ -363,36 +365,13 @@ self.response_channel_id = -1 self.run = False self.sync_response_dictionary = {} - self.logging_enabled = log_level is not None and log_level.upper() in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] - self.log_can_separate = log_level is not None and log_level.upper() in ["CAN_ONLY"] - self.log_can_file = "Dialin_CAN_Sent.log" - if os.path.exists(self.log_can_file): - os.remove(self.log_can_file) - if self.logging_enabled: - numeric_level = getattr(logging, log_level.upper(), logging.ERROR) - self.logger = logging.getLogger("Dialin") - self.logger.setLevel(numeric_level) - - fh = logging.FileHandler("Dialin.log") - fh.setLevel(numeric_level) - ch = logging.StreamHandler() - ch.setLevel(numeric_level) - formatter = logging.Formatter(fmt='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s', - datefmt='%m-%d-%Y:%H:%M:%S') - fh.setFormatter(formatter) - ch.setFormatter(formatter) - - self.logger.addHandler(fh) - self.logger.addHandler(ch) - - if self.bus is not None: self.serial_listener_thread = threading.Thread(target=self.listener, daemon=True) else: self.serial_listener_thread = None - self.print_and_log("Can connection is not valid") + self.logger.debug("Can connection is not valid") def start(self): """ @@ -401,23 +380,23 @@ """ if self.bus is None: - self.print_and_log("Cannot start can listener.") + self.logger.debug("Cannot start can listener.") return else: self.run = True if self.serial_listener_thread is not None: self.serial_listener_thread.start() - self.print_and_log("Can listener has started.") + self.logger.debug("Can listener has started.") else: - self.print_and_log("Cannot start listener...") + self.logger.debug("Cannot start listener...") def stop(self): """ Stop listening the can interface """ self.run = False - self.print_and_log("\nCan listener has stopped.") + self.logger.debug("\nCan listener has stopped.") def listener(self): """ @@ -427,7 +406,6 @@ while self.run: message = self.listener_buffer.get_message(0.0) - self.print_and_log("Message = {}".format(message)) if message is not None: @@ -437,8 +415,8 @@ channel_id = message.arbitration_id message_length = can_data[DenaliMessage.PAYLOAD_LENGTH_INDEX] - self.print_and_log(str(time.time()) + " " + str(channel_id) + " " + str(can_data), - log_level=logging.INFO) + if self.log_can: + self.do_log_can(message, style="candump", channel=self.bus.channel, send=False) # if we are building a long message, then proceed to push it to the channel dictionary if channel_id in self.long_msg_channel_id_set: @@ -486,7 +464,7 @@ self.messages, DenaliMessage.get_crc(complete_dialin_message), DenaliMessage.crc8(self.messages))) - if message_valid == True: + if message_valid: # We first check if this is a response to a send request that is pending if dialin_msg_id == self.send_packet_request_id: @@ -562,9 +540,8 @@ data=packet, is_extended_id=False) - self.print_and_log(packet, log_level=logging.CRITICAL) - if self.log_can_separate: - self.do_log_can(packet) + if self.log_can: + self.do_log_can(packet, style="candump", channel=self.bus.channel, send=True) self.bus.send(packet, 0) # 0.1) # Sending @@ -582,49 +559,41 @@ msg_sent = True else: # msg_sent = False - self.print_and_log("No response. Re-sending message.") + self.logger.debug("No response. Re-sending message.") # We are ready to send again. Reset request ID appropriately self.send_packet_request_id = -1 # This value is None or it has a message depending of the listener return self.command_response_message - def do_log_can(self, packet, style="candump"): + def do_log_can(self, packet: can.Message, style="candump", channel="can0", send=True): + """ + Logs all packets sent or received by dialin in candump, or non-candump style format + + @param packet: (can.Message) The packet to log + @param style: (str) The style to log in (candump, non-candump) + @param channel: (str) The channel send or received on + @param send: (bool) Whether we're sending or receiving this packet + @return: None + """ + filename = "Dialin_CAN_Send.log" + if not send: + filename = "Dialin_CAN_Receive.log" if style == "candump": - with open(self.log_can_file, 'a') as f: + with open(filename, 'a') as f: tmp = str(packet) - f.write("{0} {1} [{2}] {3}\n".format(self.bus.channel, - hex(packet.arbitration_id)[2:], - packet.dlc, tmp[-23:].upper())) + if send: + f.write("{0} {1} [{2}] {3}\n".format(channel, + hex(packet.arbitration_id)[2:], + packet.dlc, + tmp[-23:].upper())) + else: + f.write("{0} {1} [{2}] {3}\n".format(channel, + hex(packet.arbitration_id)[2:], + packet.dlc, + tmp[-41:-18].upper())) else: - with open(self.log_can_file, 'a') as f: + with open(filename, 'a') as f: f.write("{0}\n".format(packet)) - - def print_and_log(self, message, log_level=logging.DEBUG): - """ - Prints a message if its severity is >= the current log level. - Also logs the message. - - @param message: The message to print and log - @param log_level: The logging level, indicates the severity of the message - - @return:: None - """ - if not self.logging_enabled: - return - - if self.logger.getEffectiveLevel() <= log_level: - print(message) - - if log_level == logging.DEBUG: - self.logger.debug(message) - elif log_level == logging.INFO: - self.logger.info(message) - elif log_level == logging.WARNING: - self.logger.warning(message) - elif log_level == logging.ERROR: - self.logger.error(message) - elif log_level == logging.CRITICAL: - self.logger.critical(message) Index: dialin/utils/base.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- dialin/utils/base.py (.../base.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ dialin/utils/base.py (.../base.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -15,8 +15,55 @@ ############################################################################ from abc import ABC, abstractmethod from datetime import datetime +import os +import logging +def create_logger(log_path: str = "/tmp/DialinScript.log", level: str = "ERROR"): + """ + Convenience function to create a logger for external Dialin scripts + + @param log_path: (str) The full path to the output log file. + @param level: (str) The logging level (e.g. INFO, WARN, DEBUG, ERROR, CRITICAL) + @return: (logging.Logger) The logger object + """ + + numeric_level = getattr(logging, level, logging.ERROR) + + logger = logging.getLogger("DialinScript") + logger.setLevel(numeric_level) + + fh = logging.FileHandler(log_path) + fh.setLevel(numeric_level) + ch = logging.StreamHandler() + ch.setLevel(numeric_level) + formatter = logging.Formatter(fmt=_LogManager.LOG_FMT, + datefmt=_LogManager.LOG_DT_FMT) + fh.setFormatter(formatter) + ch.setFormatter(formatter) + + logger.addHandler(fh) + logger.addHandler(ch) + return logger + + +def find_variables_in_object(obj, value, starts_with: str = ""): + """ + Returns a list of variable names that in the object that match the searched value + + @param obj: (object) The object to search through + @param value: (object) The value to lookup + @param starts_with: (str) The + @return: (List[str]) A list of variable names matching the searched value + """ + result = [] + for attr in dir(obj): + if not callable(getattr(obj, attr)) and attr.startswith(starts_with): + if value == getattr(obj, attr): + result.append(attr) + return result + + class AbstractObserver(ABC): """ Publicly accessible parent class for all observers. @@ -32,13 +79,183 @@ pass -# abstract base class requires all abstract methods are overridden by children classes -class _AbstractSubSystem(ABC): +class _FauxLogger: + def __init__(self, printing_enabled=False): + self.printing_enabled = printing_enabled + + def debug(self, msg): + if self.printing_enabled: + print("DEBUG: {0}".format(msg)) + + def info(self, msg): + if self.printing_enabled: + print("INFO: {0}".format(msg)) + + def warn(self, msg): + if self.printing_enabled: + print("WARN: {0}".format(msg)) + + def warning(self, msg): + if self.printing_enabled: + print("WARNING: {0}".format(msg)) + + def error(self, msg): + if self.printing_enabled: + print("ERROR: {0}".format(msg)) + + def critical(self, msg): + if self.printing_enabled: + print("CRITICAL: {0}".format(msg)) + + +class _LogManager(ABC): + + LOG_FMT = '%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s' + LOG_DT_FMT = '%m-%d-%Y:%H:%M:%S' + + def __init__(self, log_level=None, log_filepath="Dialin.log"): + """ + + @param log_level: (str) or (None) if not set, contains the logging level + @param log_filepath: (str) the log filepath + """ + + self.log_level = log_level + self.logging_enabled = self.log_level_enables_logging(log_level) + self.log_filepath = self.get_available_log_path(log_filepath) + self.logger = None + self.configure_logging(self.log_filepath) + + def log_level_enables_logging(self, log_level:str): + """ + Check if the log level string is a valid logging level + + @param log_level: (str) the logging level + @return: True if the log level is valid, False otherwise + """ + return log_level is not None and log_level.upper() in self.get_logging_levels() + + @staticmethod + def get_logging_levels(): + """ + Gets all possible logging levels + + @return: All possible logging levels + """ + return ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "CAN_ONLY", "PRINT_ONLY"] + + def request_new_log_path(self, path:str): + """ + Clears the logger, gets a new log filepath + and configures the logger to use it. + + @param path: the requested log filepath + @return: The new log filepath + """ + self.clear_logger() + self.log_filepath = self.get_available_log_path(path) + self.configure_logging(self.log_filepath) + return self.log_filepath + + def clear_logger(self): + """ + If the logger has been created, clear its handlers + + @return: True if successful, False otherwise + """ + + # remove existing handlers + if self.logger is not None: + for handler in self.logger.handlers: + self.logger.removeHandler(handler) + return True + return False + + def configure_logging(self, log_path): + """ + Sets up the logger to use the provided log path + + @param log_path: Path to the log file + @return: True if success, False otherwise + """ + if self.logger is not None: + print("Logger already configured. Please clear the logger first.") + return False + + # configure the logging + if self.logging_enabled and self.log_level not in ["PRINT_ONLY", "CAN_ONLY"]: + numeric_level = getattr(logging, self.log_level.upper(), logging.ERROR) + self.logger = logging.getLogger("Dialin") + self.logger.setLevel(numeric_level) + + fh = logging.FileHandler(log_path) + fh.setLevel(numeric_level) + ch = logging.StreamHandler() + ch.setLevel(numeric_level) + formatter = logging.Formatter(fmt=self.LOG_FMT, + datefmt=self.LOG_DT_FMT) + fh.setFormatter(formatter) + ch.setFormatter(formatter) + + self.logger.addHandler(fh) + self.logger.addHandler(ch) + else: + self.logger = _FauxLogger(printing_enabled=self.log_level == "PRINT_ONLY") + + return True + + def print_and_log(self, message, log_level=logging.DEBUG): + """ + Prints a message if its severity is >= the current log level. + Also logs the message. + + @param message: The message to print and log + @param log_level: The logging level, indicates the severity of the message + + @return:: None + """ + if not self.logging_enabled: + return + + if log_level == logging.DEBUG: + self.logger.debug(message) + elif log_level == logging.INFO: + self.logger.info(message) + elif log_level == logging.WARNING: + self.logger.warning(message) + elif log_level == logging.ERROR: + self.logger.error(message) + elif log_level == logging.CRITICAL: + self.logger.critical(message) + + @staticmethod + def get_available_log_path(filepath:str): + """ + Gets an available log path from filepath + appends integer to the end if file already exists. + + @param filepath: The full path to the file + @return: (str) The available log filepath + """ + + if not os.path.exists(filepath): + return filepath + + path, ext = os.path.splitext(filepath) + i = 0 + while os.path.exists("{0}{1}{2}".format(path, i, ext)): + i += 1 + return "{0}{1}{2}".format(path, i, ext) + + +class _AbstractSubSystem: + @abstractmethod def __init__(self): """ Initialization function for the sub system + # The abstract base class requires all abstract methods are overridden by children classes """ self._observers = [] @@ -82,6 +299,7 @@ return None result["datetime"] = datetime.now() + result["subsystem"] = self.__class__.__name__ for key in keys: result[key] = getattr(self, key) @@ -92,3 +310,5 @@ return _wrapper return _decorator + + Index: tests/test_can_xmit.py =================================================================== diff -u -rfb9052e39fb778d3d029eda4d6917a0a1fcb9cbd -r8d1f61499650e23dac6f857e48daad42180db949 --- tests/test_can_xmit.py (.../test_can_xmit.py) (revision fb9052e39fb778d3d029eda4d6917a0a1fcb9cbd) +++ tests/test_can_xmit.py (.../test_can_xmit.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -1,17 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2019 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_TestScript.py +# @file can_xmit_test.py # -# @date 19-Nov-2019 -# @author S. Nash +# @author (last) Sean Nash +# @date (last) 21-May-2020 +# @author (original) Sean Nash +# @date (original) 20-May-2020 # -# @brief This is an example test script for the HD. -# ############################################################################ import sys Index: tests/test_demo.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- tests/test_demo.py (.../test_demo.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ tests/test_demo.py (.../test_demo.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -18,6 +18,7 @@ from dialin.dg.dialysate_generator import DG from dialin.hd.hemodialysis_device import HD from dialin.hd.constants import RESET, NO_RESET, BUTTON_PRESSED, BUTTON_RELEASED +from dialin.utils.base import find_variables_in_object import time @@ -114,5 +115,11 @@ print(dg.valves.get_valve_states()) +def test_reverse_lookup(): + hd = HD() + + print(find_variables_in_object(hd.ui, 2, "REQUEST_")) + + if __name__ == '__main__': - test_valves() + test_reverse_lookup() Index: tests/test_dg.py =================================================================== diff -u -rfb9052e39fb778d3d029eda4d6917a0a1fcb9cbd -r8d1f61499650e23dac6f857e48daad42180db949 --- tests/test_dg.py (.../test_dg.py) (revision fb9052e39fb778d3d029eda4d6917a0a1fcb9cbd) +++ tests/test_dg.py (.../test_dg.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -1,17 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2019 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_tests_script.py +# @file dg_test_script.py # -# @date 7-Apr-2019 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 29-Apr-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief This is an example test script for the HD. -# ############################################################################ import sys sys.path.append("..") Index: tests/test_dg_valves_observer.py =================================================================== diff -u -rfb9052e39fb778d3d029eda4d6917a0a1fcb9cbd -r8d1f61499650e23dac6f857e48daad42180db949 --- tests/test_dg_valves_observer.py (.../test_dg_valves_observer.py) (revision fb9052e39fb778d3d029eda4d6917a0a1fcb9cbd) +++ tests/test_dg_valves_observer.py (.../test_dg_valves_observer.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -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 dg_valves_test1.py +# @file dg_valves_test_observer.py # -# @date 01-June-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 24-Jun-2020 +# @author (original) Peter Lucia +# @date (original) 24-Jun-2020 # -# @brief This development test script shows how to use the AbstractObserver class -# ############################################################################ import sys Index: tests/test_gen_requirements.py =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- tests/test_gen_requirements.py (.../test_gen_requirements.py) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ tests/test_gen_requirements.py (.../test_gen_requirements.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -83,13 +83,12 @@ return result +def generate_requirements(): + """ + Generates requires for both HD and DG -def gen_dg_requirements(): - pass - - - -if __name__ == '__main__': + @return: None + """ hd = HD() result = {} @@ -128,3 +127,7 @@ gen_publish_requirements(modules) gen_cmd_requirements(modules) + + +if __name__ == '__main__': + generate_requirements() Index: tests/test_hd.py =================================================================== diff -u -rfb9052e39fb778d3d029eda4d6917a0a1fcb9cbd -r8d1f61499650e23dac6f857e48daad42180db949 --- tests/test_hd.py (.../test_hd.py) (revision fb9052e39fb778d3d029eda4d6917a0a1fcb9cbd) +++ tests/test_hd.py (.../test_hd.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -1,17 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2019 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_tests_script.py +# @file hd_test_script.py # -# @date 7-Apr-2019 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 07-Apr-2020 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 # -# @brief This is an example test script for the HD. -# ############################################################################ import sys sys.path.append("..") Index: tests/test_uf.py =================================================================== diff -u -rfb9052e39fb778d3d029eda4d6917a0a1fcb9cbd -r8d1f61499650e23dac6f857e48daad42180db949 --- tests/test_uf.py (.../test_uf.py) (revision fb9052e39fb778d3d029eda4d6917a0a1fcb9cbd) +++ tests/test_uf.py (.../test_uf.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -1,17 +1,17 @@ ########################################################################### # -# Copyright (c) 2019-2019 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_UFTest.py +# @file uf_test.py # -# @date 28-Jan-2020 -# @author S. Nash +# @author (last) Peter Lucia +# @date (last) 02-Jun-2020 +# @author (original) Sean Nash +# @date (original) 20-May-2020 # -# @brief This script simulates 300 grams of load cell increase over 15 minutes (20 mL/min). -# ############################################################################ import sys Index: tests/unit_tests/test_dg_valves.py =================================================================== diff -u -r82615ab9d1757ef67810f9fc267cd89a19a2e4c8 -r8d1f61499650e23dac6f857e48daad42180db949 --- tests/unit_tests/test_dg_valves.py (.../test_dg_valves.py) (revision 82615ab9d1757ef67810f9fc267cd89a19a2e4c8) +++ tests/unit_tests/test_dg_valves.py (.../test_dg_valves.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -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 test_imports.py +# @file unit_tests.py # -# @date 29-Apr-2020 -# @author P. Lucia +# @author (last) Peter Lucia +# @date (last) 13-Jul-2020 +# @author (original) Peter Lucia +# @date (original) 13-Jul-2020 # -# @brief Tests imports of all available modules -# ############################################################################ import unittest import sys Index: tools/document.sh =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- tools/document.sh (.../document.sh) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ tools/document.sh (.../document.sh) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -17,7 +17,12 @@ CURR_DIR=$(pwd) if [[ "$@" == "*--setup*" ]]; then - sudo apt-get install python3-sphinx + if [[ $(dpkg-query -W -f='${Status}' python3-sphinx | grep -c "ok installed") -eq 0 ]]; then + echo "Please run the following required packages: " + echo "sudo apt-get install python3-sphinx" + echo "Exiting..." + exit 1 + fi mkdir -p ../docs/ cd ../docs/ Index: tools/setup_canbus.sh =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- tools/setup_canbus.sh (.../setup_canbus.sh) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ tools/setup_canbus.sh (.../setup_canbus.sh) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -14,7 +14,15 @@ # @date (original) 01-Apr-2020 # ############################################################################ +iface="can0" +if [ "$#" -gt 1 ]; then + echo "Please provide only one can interface." + echo "Usage (defaults to can0): setup_canbus.sh " + echo " Use instead: setup_canbus.sh " + exit 1 +elif [ "$#" -eq 1 ]; then + iface="$1" +fi -sudo ifconfig can0 down -sudo ip link set can0 up type can bitrate 250000 restart-ms 100 +sudo ip link set "$iface" up type can bitrate 250000 restart-ms 100 Index: tools/setup_virtual_can.sh =================================================================== diff -u -r4bdb012848d1b59be5edc31d677b77b9d95f6190 -r8d1f61499650e23dac6f857e48daad42180db949 --- tools/setup_virtual_can.sh (.../setup_virtual_can.sh) (revision 4bdb012848d1b59be5edc31d677b77b9d95f6190) +++ tools/setup_virtual_can.sh (.../setup_virtual_can.sh) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -14,17 +14,19 @@ # @date (original) 01-Apr-2020 # ############################################################################ -sudo ifconfig vcan0 down -sudo ifconfig vcan1 down -sudo ip link delete dev vcan0 -sudo ip link delete dev vcan1 +iface="can0" +if [ "$#" -gt 1 ]; then + echo "Please provide only one can interface." + echo "Usage (defaults to can0): ./bring_can_iface_down.sh " + echo " Use instead: setup_canbus.sh " + exit 1 +elif [ "$#" -eq 1 ]; then + iface="$1" +fi -sudo ip link add dev vcan0 type vcan -sudo ip link add dev vcan1 type vcan +sudo ip link add dev "$iface" type vcan -sudo ip link set vcan0 up -sudo ifconfig vcan0 txqueuelen 10000 +sudo ip link set "$iface" up +sudo ifconfig "$iface" txqueuelen 10000 -sudo ip link set vcan1 up -sudo ifconfig vcan1 txqueuelen 10000 Index: version.py =================================================================== diff -u -r5818c70699fbe02a31d136f440baee0d9f2cb39d -r8d1f61499650e23dac6f857e48daad42180db949 --- version.py (.../version.py) (revision 5818c70699fbe02a31d136f440baee0d9f2cb39d) +++ version.py (.../version.py) (revision 8d1f61499650e23dac6f857e48daad42180db949) @@ -1 +1,42 @@ -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) 18-Jun-2020 +# @author (original) Peter Lucia +# @date (original) 16-Jun-2020 +# +############################################################################ +import subprocess + + +def get_branch(): + """ + Gets the current branch name in the current git repository + + @return: The current branch name + """ + + return subprocess.check_output("git rev-parse --abbrev-ref HEAD", shell=True).decode("utf-8").strip() + + +def get_last_commit(): + """ + Gets the latest commit in the current git repository + + @return: (str) the latest commit in the current git repository + """ + return subprocess.check_output("git rev-parse --short=7 HEAD", shell=True).decode("utf-8").strip() + + +VERSION = "0.5.0-{0}-{1}".format(get_branch(), get_last_commit()) + + +if __name__ == '__main__': + print(VERSION)