Index: leahi_dialin/common/msg_ids.py =================================================================== diff -u -radd1665bb756188ddca1b7e26728a6a80598d0da -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/common/msg_ids.py (.../msg_ids.py) (revision add1665bb756188ddca1b7e26728a6a80598d0da) +++ leahi_dialin/common/msg_ids.py (.../msg_ids.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -64,21 +64,21 @@ MSG_ID_DD_LEVEL_DATA = 0x29 MSG_ID_TD_AIR_TRAP_DATA = 0x2A MSG_ID_TD_VALVES_DATA = 0x2B - MSG_ID_RO_EVENT = 0x2C - MSG_ID_RO_ALARM_INFO_DATA= 0x2D + MSG_ID_FP_EVENT = 0x2C + MSG_ID_FP_ALARM_INFO_DATA= 0x2D MSG_ID_DD_BAL_CHAMBER_DATA = 0x2E MSG_ID_DD_GEN_DIALYSATE_MODE_DATA = 0x2F MSG_ID_DD_GEN_DIALYSATE_REQUEST_DATA = 0x30 - MSG_ID_RO_VALVES_STATES_DATA = 0x31 - MSG_ID_RO_PUMP_DATA = 0x32 - MSG_ID_RO_OP_MODE_DATA = 0x33 - MSG_ID_RO_PRESSURES_DATA = 0x34 - MSG_ID_RO_LEVEL_DATA = 0x35 - MSG_ID_RO_FLOW_DATA = 0x36 - MSG_ID_RO_CONDUCTIVITY_DATA = 0x37 - MSG_ID_DD_RO_START_STOP_CMD_REQUEST = 0x38 - MSG_ID_RO_TEMPERATURE_DATA = 0x39 - MSG_ID_RO_HEATER_DATA = 0x3A + MSG_ID_FP_VALVES_STATES_DATA = 0x31 + MSG_ID_FP_RO_PUMP_DATA = 0x32 + MSG_ID_FP_OP_MODE_DATA = 0x33 + MSG_ID_FP_PRESSURES_DATA = 0x34 + MSG_ID_FP_LEVEL_DATA = 0x35 + MSG_ID_FP_FLOW_DATA = 0x36 + MSG_ID_FP_CONDUCTIVITY_DATA = 0x37 + MSG_ID_DD_FP_START_STOP_CMD_REQUEST = 0x38 + MSG_ID_FP_TEMPERATURE_DATA = 0x39 + MSG_ID_FP_HEATER_DATA = 0x3A MSG_ID_TD_TREATMENT_TIME_DATA = 0x3B MSG_ID_TD_TREATMENT_STATE_DATA = 0x3C MSG_ID_TD_SALINE_BOLUS_DATA = 0x3D @@ -93,18 +93,23 @@ MSG_ID_TD_RESP_INITIATE_TREATMENT_WORKFLOW = 0x46 MSG_ID_UI_UF_PAUSE_RESUME_REQUEST = 0x47 MSG_ID_TD_UF_PAUSE_RESUME_RESPONSE = 0x48 - MSG_ID_RO_GEN_PERMEATE_MODE_DATA = 0x49 + MSG_ID_FP_GEN_PERMEATE_MODE_DATA = 0x49 MSG_ID_DD_PRE_GEN_DIALYSATE_STATE_DATA = 0x4A MSG_ID_DD_POST_GEN_DIALYSATE_STATE_DATA = 0x4B MSG_ID_DD_PRE_GEN_DIALYSATE_REQUEST_DATA = 0x4C - MSG_ID_RO_PRE_GEN_WATER_MODE_DATA = 0x4D + MSG_ID_FP_PRE_GEN_WATER_MODE_DATA = 0x4D MSG_ID_TD_EJECTOR_DATA = 0x4E MSG_ID_TD_TREATMENT_SET_POINTS = 0x4F - MSG_ID_RO_BOOST_PUMP_DATA = 0x50 + MSG_ID_FP_BOOST_PUMP_DATA = 0x50 MSG_ID_TD_SERIAL_RESPONSE = 0x51 MSG_ID_DD_SERIAL_RESPONSE = 0x52 MSG_ID_TD_TEMPERATURE_DATA = 0x53 MSG_ID_TD_BATTERY_DATA = 0x54 + MSG_ID_FP_FILTER_FLUSH_DATA = 0x55 + MSG_ID_FP_PERMEATE_FLUSH_DATA = 0x56 + MSG_ID_FP_CONCENTRATE_FLUSH_DATA = 0x57 + MSG_ID_FP_GENP_DEF_DATA = 0x58 + MSG_ID_FP_PRE_GEN_DEF_DATA = 0x59 MSG_ID_DD_PISTON_PUMP_CONTROL_DATA = 0xF0 @@ -213,7 +218,7 @@ MSG_ID_DD_CONCENTRATE_PUMPS_START_STOP_OVERRIDE_REQUEST = 0xA02D MSG_ID_DD_HEATERS_START_STOP_OVERRIDE_REQUEST = 0xA02E MSG_ID_DD_VALVES_OPEN_CLOSE_STATE_OVERRIDE_REQUEST = 0xA02F - MSD_ID_DD_RO_COMMUNICATION_STATUS_OVERRIDE_REQUEST = 0xA030 + MSD_ID_DD_FP_COMMUNICATION_STATUS_OVERRIDE_REQUEST = 0xA030 MSG_ID_DD_BAL_CHAMBER_DATA_PUBLISH_OVERRIDE_REQUEST = 0xA031 MSG_ID_DD_BAL_CHAMBER_SWITCH_FREQ_OVERRIDE_REQUEST = 0xA032 MSG_ID_DD_DIAL_DELIVERY_IN_PROGRESS_OVERRIDE_REQUEST = 0xA033 @@ -231,47 +236,55 @@ MSG_ID_DD_START_PRE_GEN_DIALYSATE_MODE_OVERRIDE_REQUEST = 0xA03F MSG_ID_DD_STOP_PRE_GEN_DIALYSATE_MODE_OVERRIDE_REQUEST = 0xA040 MSG_ID_DD_STOP_GEN_DIALYSATE_MODE_OVERRIDE_REQUEST = 0xA041 + MSG_ID_DD_SAFETY_SHUTDOWN_OVERRIDE_REQUEST = 0xA042 MSG_ID_DD_PISTON_PUMP_DATA_PUBLISH_OVERRIDE_REQUEST = 0xAF00 MSG_ID_DD_PISTON_PUMP_START_STOP_OVERRIDE_REQUEST = 0xAF01 MSG_ID_DD_PISTON_PUMP_FILL_AFTER_DISPENSE_OVERRIDE_REQUEST = 0xAF02 - MSG_ID_RO_TESTER_LOGIN_REQUEST = 0xB000 - MSG_ID_RO_SOFTWARE_RESET_REQUEST = 0xB001 - MSG_ID_RO_SEND_TEST_CONFIGURATION = 0xB002 - MSG_ID_RO_VALVE_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB003 - MSG_ID_RO_VALVE_CMD_STATE_OVERRIDE_REQUEST = 0xB004 - MSG_ID_RO_VALVE_SENSED_STATE_OVERRIDE_REQUEST = 0xB005 - MSG_ID_RO_BOOST_PUMP_SET_PWM_REQUEST = 0xB006 - MSG_ID_RO_BOOST_PUMP_READ_PWM_OVERRIDE_REQUEST = 0xB007 - MSG_ID_RO_BOOST_PUMP_SPEED_OVERRIDE_REQUEST = 0xB008 - MSG_ID_RO_BOOST_PUMPS_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB009 - MSG_ID_RO_PRESSURE_OVERRIDE_REQUEST = 0xB00A - MSG_ID_RO_PRESSURE_TEMP_OVERRIDE_REQUEST = 0xB00B - MSG_ID_RO_PRESSURE_READ_COUNT_OVERRIDE_REQUEST = 0xB00C - MSG_ID_RO_PRESSURE_ERROR_COUNT_OVERRIDE_REQUEST = 0xB00D - MSG_ID_RO_PRESSURE_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB00E - MSG_ID_RO_LEVEL_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB00F - MSG_ID_RO_LEVEL_OVERRIDE_REQUEST = 0xB010 - MSG_ID_RO_FLOWS_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB011 - MSG_ID_RO_FLOW_RATE_OVERRIDE_REQUEST = 0xB012 - MSG_ID_RO_FLOW_TEMP_OVERRIDE_REQUEST = 0xB013 - MSG_ID_RO_CONDUCTIVITY_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB014 - MSG_ID_RO_CONDUCTIVITY_OVERRIDE_REQUEST = 0xB015 - MSG_ID_RO_CONDUCTIVITY_TEMP_OVERRIDE_REQUEST = 0xB016 - MSG_ID_RO_CONDUCTIVITY_READ_COUNT_OVERRIDE_REQUEST = 0xB017 - MSG_ID_RO_CONDUCTIVITY_ERROR_COUNT_OVERRIDE_REQUEST = 0xB018 - MSG_ID_RO_TEMPERATURE_OVERRIDE_REQUEST = 0xB019 - MSG_ID_RO_FILTERED_FLOW_RATE_OVERRIDE_REQUEST = 0xB01A - MSG_ID_RO_FILTERED_FLOW_TEMP_OVERRIDE_REQUEST = 0xB01B - MSG_ID_RO_PRE_GEN_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB01C - MSG_ID_RO_SET_OP_MODE_REQUEST = 0xB01D - MSG_ID_RO_OPERATION_MODE_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB01E - MSG_ID_RO_TEMPERATURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB01F + MSG_ID_FP_TESTER_LOGIN_REQUEST = 0xB000 + MSG_ID_FP_SOFTWARE_RESET_REQUEST = 0xB001 + MSG_ID_FP_SEND_TEST_CONFIGURATION = 0xB002 + MSG_ID_FP_VALVE_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB003 + MSG_ID_FP_VALVE_CMD_STATE_OVERRIDE_REQUEST = 0xB004 + MSG_ID_FP_VALVE_SENSED_STATE_OVERRIDE_REQUEST = 0xB005 + MSG_ID_FP_FLUID_PUMP_SET_PWM_REQUEST = 0xB006 + MSG_ID_FP_FLUID_PUMP_READ_PWM_OVERRIDE_REQUEST = 0xB007 + MSG_ID_FP_FLUID_PUMP_SPEED_OVERRIDE_REQUEST = 0xB008 + MSG_ID_FP_RO_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB009 + MSG_ID_FP_PRESSURE_OVERRIDE_REQUEST = 0xB00A + MSG_ID_FP_PRESSURE_TEMP_OVERRIDE_REQUEST = 0xB00B + MSG_ID_FP_PRESSURE_READ_COUNT_OVERRIDE_REQUEST = 0xB00C + MSG_ID_FP_PRESSURE_ERROR_COUNT_OVERRIDE_REQUEST = 0xB00D + MSG_ID_FP_PRESSURE_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB00E + MSG_ID_FP_LEVEL_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB00F + MSG_ID_FP_LEVEL_OVERRIDE_REQUEST = 0xB010 + MSG_ID_FP_FLOWS_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB011 + MSG_ID_FP_FLOW_RATE_OVERRIDE_REQUEST = 0xB012 + MSG_ID_FP_FLOW_TEMP_OVERRIDE_REQUEST = 0xB013 + MSG_ID_FP_CONDUCTIVITY_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB014 + MSG_ID_FP_CONDUCTIVITY_OVERRIDE_REQUEST = 0xB015 + MSG_ID_FP_CONDUCTIVITY_TEMP_OVERRIDE_REQUEST = 0xB016 + MSG_ID_FP_CONDUCTIVITY_READ_COUNT_OVERRIDE_REQUEST = 0xB017 + MSG_ID_FP_CONDUCTIVITY_ERROR_COUNT_OVERRIDE_REQUEST = 0xB018 + MSG_ID_FP_TEMPERATURE_OVERRIDE_REQUEST = 0xB019 + MSG_ID_FP_FILTERED_FLOW_RATE_OVERRIDE_REQUEST = 0xB01A + MSG_ID_FP_FILTERED_FLOW_TEMP_OVERRIDE_REQUEST = 0xB01B + MSG_ID_FP_PRE_GEN_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB01C + MSG_ID_FP_SET_OP_MODE_REQUEST = 0xB01D + MSG_ID_FP_OPERATION_MODE_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB01E + MSG_ID_FP_TEMPERATURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB01F + MSG_ID_FP_RO_PUMP_TARGET_PRESSURE_OVERRIDE_REQUEST = 0xB020 + MSG_ID_FP_RO_PUMP_TARGET_FLOW_OVERRIDE_REQUEST = 0xB021 + MSG_ID_FP_RO_PUMP_TARGET_PWM_OVERRIDE_REQUEST = 0xB022 + MSG_ID_FP_BOOST_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST = 0xB023 + MSG_ID_FP_BOOST_PUMP_TARGET_PRESSURE_OVERRIDE_REQUEST = 0xB024 + MSG_ID_FP_BOOST_PUMP_TARGET_FLOW_OVERRIDE_REQUEST = 0xB025 + MSG_ID_FP_BOOST_PUMP_TARGET_PWM_OVERRIDE_REQUEST = 0xB026 MSG_ID_TD_DEBUG_EVENT = 0xFFF1 MSG_ID_DD_DEBUG_EVENT = 0xFFF2 - MSG_ID_RO_DEBUG_EVENT = 0xFFF3 + MSG_ID_FP_DEBUG_EVENT = 0xFFF3 MSG_ID_ACK_MESSAGE_THAT_REQUIRES_ACK = 0xFFFF \ No newline at end of file Index: leahi_dialin/dd/modules/piston_pump.py =================================================================== diff -u -ra313166ac02fdc81a9d2b24eca45cded18fd468e -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/dd/modules/piston_pump.py (.../piston_pump.py) (revision a313166ac02fdc81a9d2b24eca45cded18fd468e) +++ leahi_dialin/dd/modules/piston_pump.py (.../piston_pump.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -97,6 +97,8 @@ message['message'][MsgFieldPositions.START_POS_FIELD_9:MsgFieldPositions.END_POS_FIELD_9]))[0] self.dd_piston_pump_timestamp = timestamp + + def cmd_piston_pump_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends the piston pump data broadcast interval override command Index: leahi_dialin/dd/proxies/ro_proxy.py =================================================================== diff -u -rad1d08ef189799e3f31dcf4e630c21d9f98c33d7 -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/dd/proxies/ro_proxy.py (.../ro_proxy.py) (revision ad1d08ef189799e3f31dcf4e630c21d9f98c33d7) +++ leahi_dialin/dd/proxies/ro_proxy.py (.../ro_proxy.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -42,7 +42,7 @@ def cmd_dd_send_ro_start_stop_request(self, cmdID: int = 0, start: bool = 0, ro_rate: float = 0): """ - Constructs and sends a DD command response to the RO. + Constructs and sends a DD command request to the RO. @param: cmd_id: The DD command ID @param: rejected: 0 for acceptance, 1 for rejection Index: leahi_dialin/fp/filtration_purification.py =================================================================== diff -u -rf5ff90469cd1520361a823923ad0b58ab4a23a45 -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/fp/filtration_purification.py (.../filtration_purification.py) (revision f5ff90469cd1520361a823923ad0b58ab4a23a45) +++ leahi_dialin/fp/filtration_purification.py (.../filtration_purification.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -15,15 +15,18 @@ ############################################################################ import struct +from .modules.boost_pump import FPBoostPump from .modules.conductivity_sensors import FPConductivitySensors from .modules.constants import NO_RESET, RESET from .modules.flow_sensors import FPFlowSensors from .modules.levels import FPLevels from .modules.pressure_sensors import FPPressureSensors +from .modules.ro_pump import FPROPump from .modules.temperatures import FPTemperatureSensors from .modules.valves import FPValves from .modules.water_pumps import FPPumps +from .proxies.dd_proxy import DDProxy from ..common.msg_defs import MsgIds, MsgFieldPositions from ..common.fp_defs import FPOpModes @@ -84,12 +87,12 @@ # register handler for FP operation mode broadcast messages if self.can_interface is not None: channel_id = DenaliChannels.fp_sync_broadcast_ch_id - msg_id = MsgIds.MSG_ID_RO_OP_MODE_DATA.value + msg_id = MsgIds.MSG_ID_FP_OP_MODE_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_fp_op_mode_sync) self.can_interface.register_receiving_publication_function(channel_id, - MsgIds.MSG_ID_RO_DEBUG_EVENT.value, + MsgIds.MSG_ID_FP_DEBUG_EVENT.value, self._handler_fp_debug_event_sync) # create properties @@ -106,15 +109,18 @@ self.fp_last_debug_event = '' # Create command groups + self.boost_pump = FPBoostPump(self.can_interface, self.logger) self.conductivity = FPConductivitySensors(self.can_interface, self.logger) self.flows = FPFlowSensors(self.can_interface, self.logger) self.pumps = FPPumps(self.can_interface, self.logger) - self.flows = FPFlowSensors(self.can_interface, self.logger) self.levels = FPLevels(self.can_interface, self.logger) self.pressures = FPPressureSensors(self.can_interface, self.logger) + self.ro_pump = FPROPump(self.can_interface, self.logger) self.temperatures = FPTemperatureSensors(self.can_interface, self.logger) self.valves = FPValves(self.can_interface, self.logger) + self.dd_proxy = DDProxy(self.can_interface, self.logger) + @publish(["fp_debug_events_timestamp","fp_debug_events"]) def _handler_fp_debug_event_sync(self, message, timestamp = 0.0): """ @@ -179,7 +185,7 @@ """ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_TESTER_LOGIN_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_TESTER_LOGIN_REQUEST.value, payload=list(map(int, map(ord, self.FP_LOGIN_PASSWORD)))) self.logger.debug("Logging in...") @@ -217,7 +223,7 @@ payload = integer_to_bytearray(new_mode) message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_SET_OP_MODE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_SET_OP_MODE_REQUEST.value, payload=payload) self.logger.debug("Requesting FP mode change to " + str(new_mode)) @@ -246,7 +252,7 @@ """ message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_SOFTWARE_RESET_REQUEST.value) + message_id=MsgIds.MSG_ID_FP_SOFTWARE_RESET_REQUEST.value) self.logger.debug("requesting FP software reset") @@ -275,7 +281,7 @@ payload = rst + mis message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_OPERATION_MODE_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_OPERATION_MODE_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("override op mode broadcast interval") Index: leahi_dialin/fp/modules/boost_pump.py =================================================================== diff -u --- leahi_dialin/fp/modules/boost_pump.py (revision 0) +++ leahi_dialin/fp/modules/boost_pump.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,242 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file boost_pump.py +# +# @author (last) Micahel Garthwaite +# @date (last) 17-Aug-2023 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 +# +############################################################################ +import struct +from enum import unique +from logging import Logger +from enum import unique + +from leahi_dialin.utils.base import DialinEnum +from .constants import RESET, NO_RESET +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish, DialinEnum +from leahi_dialin.utils.checks import check_broadcast_interval_override_ms +from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray + +class FPBoostPump(AbstractSubSystem): + """ + Dialin API sub-class for FP Boost pump controller related commands. + """ + + def __init__(self, can_interface, logger: Logger): + """ + FPBoostPump constructor + """ + super().__init__() + self.can_interface = can_interface + self.logger = logger + + if self.can_interface is not None: + channel_id = DenaliChannels.fp_sync_broadcast_ch_id + msg_id = MsgIds.MSG_ID_FP_BOOST_PUMP_DATA.value + self.can_interface.register_receiving_publication_function(channel_id, msg_id, + self._handler_pump_sync) + self.boost_pump_timestamp = 0.0 + self.p40_pump_state = 0 + self.p40_pump_duty_cycle = 0 + self.p40_pump_fb_duty_cycle = 0 + self.p40_pump_speed = 0.0 + self.p40_target_pressure = 0.0 + self.p40_target_flow = 0.0 + self.p40_target_duty_cycle = 0.0 + + + + @publish(["ro_pump_timestamp", "p40_pump_state", "p40_pump_duty_cycle", "p40_pump_fb_duty_cycle", + "p40_pump_speed", "p40_target_pressure", "p40_target_flow", "p40_target_duty_cycle"]) + def _handler_pump_sync(self, message, timestamp=0.0): + """ + Handles published FP ro pump data messages. FP ro pump data is captured + for reference. + + @param message: published FP ro pump data message + @return: none + """ + + self.p40_pump_state = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + self.p40_pump_duty_cycle = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + self.p40_pump_fb_duty_cycle = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + self.p40_pump_speed = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] + self.p40_target_pressure = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] + self.p40_target_flow = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] + self.p40_target_duty_cycle = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] + + self.boost_pump_timestamp = timestamp + + def cmd_boost_pump_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the FP boost pump broadcast interval override command + Constraints: + Must be logged into FP. + Given interval must be non-zero and a multiple of the FP general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_FP_BOOST_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("override FP boost pump broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # self.logger.debug(received_message) + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(mis) + + self.logger.debug("broadcast overridden to " + str_res) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_boost_pump_target_pressure_override(self, pressure: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends the target pressure override for the boost pump. This will drive + the boost pump in a closed loop to the pressure. + Constraints: + Must be logged into FP. + + @param pressure: float - target pressure in PSI + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + rst = integer_to_bytearray(reset) + prs = float_to_bytearray(pressure) + payload = rst + prs + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_FP_BOOST_PUMP_TARGET_PRESSURE_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("override boost pump target pressure") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(pressure) + + self.logger.debug("boost target pressure overridden to " + str_res) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_boost_pump_target_flow_override(self, flow: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the target flow override for the boost pump. This will drive + the boost pump in a closed loop to the flow. + Constraints: + Must be logged into FP. + + @param flow: float - target flow in mL/min + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + rst = integer_to_bytearray(reset) + flw = integer_to_bytearray(flow) + payload = rst + flw + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_FP_BOOST_PUMP_TARGET_FLOW_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("override BOOST pump target flow") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(flow) + + self.logger.debug("BOOST target flow overridden to " + str_res) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_boost_pump_target_pwm_override(self, duty_cycle: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends the target duty cycle override for the boost pump. This will drive + the boost pump in an open loop to the pwm. + Constraints: + Must be logged into FP. + + @param pressure: float - target duty cycle between 0 - 0.99 + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + rst = integer_to_bytearray(reset) + pwm = float_to_bytearray(duty_cycle) + payload = rst + pwm + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_FP_BOOST_PUMP_TARGET_PWM_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("override boost pump target pwm") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(duty_cycle) + + self.logger.debug("boost target pwm overridden to " + str_res) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + Index: leahi_dialin/fp/modules/conductivity_sensors.py =================================================================== diff -u -r5b9473d9ca6a66d4d03c509fae6051710895b498 -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/fp/modules/conductivity_sensors.py (.../conductivity_sensors.py) (revision 5b9473d9ca6a66d4d03c509fae6051710895b498) +++ leahi_dialin/fp/modules/conductivity_sensors.py (.../conductivity_sensors.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -47,7 +47,7 @@ if self.can_interface is not None: channel_id = DenaliChannels.fp_sync_broadcast_ch_id - msg_id = MsgIds.MSG_ID_RO_CONDUCTIVITY_DATA.value + msg_id = MsgIds.MSG_ID_FP_CONDUCTIVITY_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_conductivity_sensors_sync) @@ -79,7 +79,7 @@ Constructs and sends the FP conductivity sensor data broadcast interval override command Constraints: Must be logged into FP. - Given interval must be non-zero and a multiple of the RO general task interval (50 ms). + Given interval must be non-zero and a multiple of the FP general task interval (50 ms). @param ms: integer - interval (in ms) to override with @param reset: integer - 1 to reset a previous override, 0 to override @@ -94,7 +94,7 @@ payload = reset_byte_array + ms_byte_array message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_CONDUCTIVITY_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_CONDUCTIVITY_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("override FP conductivity sensor broadcast interval") @@ -135,7 +135,7 @@ payload = reset_byte_array + cond_byte_array + sensor_byte_array message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_CONDUCTIVITY_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_CONDUCTIVITY_OVERRIDE_REQUEST.value, payload=payload) if reset == RESET: @@ -172,7 +172,7 @@ payload = reset_byte_array + read_byte_array + sensor_byte_array message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_CONDUCTIVITY_READ_COUNT_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_CONDUCTIVITY_READ_COUNT_OVERRIDE_REQUEST.value, payload=payload) if reset == RESET: @@ -209,7 +209,7 @@ payload = reset_byte_array + error_byte_array + sensor_byte_array message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_CONDUCTIVITY_ERROR_COUNT_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_CONDUCTIVITY_ERROR_COUNT_OVERRIDE_REQUEST.value, payload=payload) if reset == RESET: Index: leahi_dialin/fp/modules/flow_sensors.py =================================================================== diff -u -rad1d08ef189799e3f31dcf4e630c21d9f98c33d7 -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/fp/modules/flow_sensors.py (.../flow_sensors.py) (revision ad1d08ef189799e3f31dcf4e630c21d9f98c33d7) +++ leahi_dialin/fp/modules/flow_sensors.py (.../flow_sensors.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -50,7 +50,7 @@ if self.can_interface is not None: channel_id = DenaliChannels.fp_sync_broadcast_ch_id - msg_id = MsgIds.MSG_ID_RO_FLOW_DATA.value + msg_id = MsgIds.MSG_ID_FP_FLOW_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_flow_sensor_sync) @@ -101,7 +101,7 @@ payload = reset_value + interval_value message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_FLOWS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_FLOWS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("Sending {} ms publish interval to the FP flow sensor module".format(ms)) @@ -131,7 +131,7 @@ sts = float_to_bytearray(rate) payload = reset_value + sts + lvl message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_FLOW_RATE_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_FLOW_RATE_OVERRIDE_REQUEST.value, payload=payload) # Send message @@ -160,7 +160,7 @@ sts = float_to_bytearray(temp) payload = reset_value + sts + lvl message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_FLOW_TEMP_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_FLOW_TEMP_OVERRIDE_REQUEST.value, payload=payload) # Send message Index: leahi_dialin/fp/modules/levels.py =================================================================== diff -u -r72c423da1d07c40699f40b5da5bee6d992d3082c -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/fp/modules/levels.py (.../levels.py) (revision 72c423da1d07c40699f40b5da5bee6d992d3082c) +++ leahi_dialin/fp/modules/levels.py (.../levels.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -28,8 +28,8 @@ @unique class FPFloaterLevels(DialinEnum): LEVEL_STATE_LOW = 0 - LEVEL_STATE_HIGH = 1 - LEVEL_STATE_MEDIUM = 2 + LEVEL_STATE_MEDIUM = 1 + LEVEL_STATE_HIGH = 2 LEVEL_STATE_ILLEGAL = 3 @@ -52,7 +52,7 @@ if self.can_interface is not None: channel_id = DenaliChannels.fp_sync_broadcast_ch_id - msg_id = MsgIds.MSG_ID_RO_LEVEL_DATA.value + msg_id = MsgIds.MSG_ID_FP_LEVEL_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_levels_sync) self.p25_level = 0 @@ -91,7 +91,7 @@ payload = reset_value + interval_value message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_LEVEL_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_LEVEL_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("Sending {} ms publish interval to the FP Levels module".format(ms)) @@ -119,7 +119,7 @@ sts = integer_to_bytearray(status) payload = reset_value + sts message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_LEVEL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_LEVEL_OVERRIDE_REQUEST.value, payload=payload) # Send message Index: leahi_dialin/fp/modules/pressure_sensors.py =================================================================== diff -u -r80f84ad5638667894e9df2161b9c5d9b8f27ed9b -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/fp/modules/pressure_sensors.py (.../pressure_sensors.py) (revision 80f84ad5638667894e9df2161b9c5d9b8f27ed9b) +++ leahi_dialin/fp/modules/pressure_sensors.py (.../pressure_sensors.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -55,7 +55,7 @@ if self.can_interface is not None: channel_id = DenaliChannels.fp_sync_broadcast_ch_id - msg_id = MsgIds.MSG_ID_RO_PRESSURES_DATA.value + msg_id = MsgIds.MSG_ID_FP_PRESSURES_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_pressure_sync) @@ -158,7 +158,7 @@ payload = rst + prs + sen message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_PRESSURE_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_PRESSURE_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("override FP pressure sensor") @@ -200,7 +200,7 @@ payload = rst + mis message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_PRESSURE_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_PRESSURE_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("override FP pressure broadcast interval") Index: leahi_dialin/fp/modules/ro_pump.py =================================================================== diff -u --- leahi_dialin/fp/modules/ro_pump.py (revision 0) +++ leahi_dialin/fp/modules/ro_pump.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,242 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file ro_pump.py +# +# @author (last) Micahel Garthwaite +# @date (last) 17-Aug-2023 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 +# +############################################################################ +import struct +from enum import unique +from logging import Logger +from enum import unique + +from leahi_dialin.utils.base import DialinEnum +from .constants import RESET, NO_RESET +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish, DialinEnum +from leahi_dialin.utils.checks import check_broadcast_interval_override_ms +from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray + +class FPROPump(AbstractSubSystem): + """ + Dialin API sub-class for FP RO pump controller related commands. + """ + + def __init__(self, can_interface, logger: Logger): + """ + FPROPump constructor + """ + super().__init__() + self.can_interface = can_interface + self.logger = logger + + if self.can_interface is not None: + channel_id = DenaliChannels.fp_sync_broadcast_ch_id + msg_id = MsgIds.MSG_ID_FP_RO_PUMP_DATA.value + self.can_interface.register_receiving_publication_function(channel_id, msg_id, + self._handler_pump_sync) + self.ro_pump_timestamp = 0.0 + self.p12_pump_state = 0 + self.p12_pump_duty_cycle = 0 + self.p12_pump_fb_duty_cycle = 0 + self.p12_pump_speed = 0.0 + self.p12_target_pressure = 0.0 + self.p12_target_flow = 0.0 + self.p12_target_duty_cycle = 0.0 + + + + @publish(["ro_pump_timestamp", "p12_pump_state", "p12_pump_duty_cycle", "p12_pump_fb_duty_cycle", + "p12_pump_speed", "p12_target_pressure", "p12_target_flow", "p12_target_duty_cycle"]) + def _handler_pump_sync(self, message, timestamp=0.0): + """ + Handles published FP ro pump data messages. FP ro pump data is captured + for reference. + + @param message: published FP ro pump data message + @return: none + """ + + self.p12_pump_state = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + self.p12_pump_duty_cycle = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + self.p12_pump_fb_duty_cycle = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + self.p12_pump_speed = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] + self.p12_target_pressure = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] + self.p12_target_flow = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] + self.p12_target_duty_cycle = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] + + self.ro_pump_timestamp = timestamp + + def cmd_ro_pump_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the FP RO pump broadcast interval override command + Constraints: + Must be logged into FP. + Given interval must be non-zero and a multiple of the FP general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + if not check_broadcast_interval_override_ms(ms): + return False + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_FP_RO_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("override FP pump broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # self.logger.debug(received_message) + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(mis) + + self.logger.debug("broadcast overridden to " + str_res) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_ro_pump_target_pressure_override(self, pressure: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends the target pressure override for the RO pump. This will drive + the RO pump in a closed loop to the pressure. + Constraints: + Must be logged into FP. + + @param pressure: float - target pressure in PSI + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + rst = integer_to_bytearray(reset) + prs = float_to_bytearray(pressure) + payload = rst + prs + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_FP_RO_PUMP_TARGET_PRESSURE_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("override RO pump target pressure") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(pressure) + + self.logger.debug("RO target pressure overridden to " + str_res) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_ro_pump_target_flow_override(self, flow: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends the target flow override for the RO pump. This will drive + the RO pump in a closed loop to the flow. + Constraints: + Must be logged into FP. + + @param flow: float - target flow in mL/min + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + rst = integer_to_bytearray(reset) + flw = integer_to_bytearray(flow) + payload = rst + flw + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_FP_RO_PUMP_TARGET_FLOW_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("override RO pump target flow") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(flow) + + self.logger.debug("RO target flow overridden to " + str_res) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_ro_pump_target_pwm_override(self, duty_cycle: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends the target duty cycle override for the RO pump. This will drive + the RO pump in an open loop to the pwm. + Constraints: + Must be logged into FP. + + @param pressure: float - target duty cycle between 0 - 0.99 + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + rst = integer_to_bytearray(reset) + pwm = float_to_bytearray(duty_cycle) + payload = rst + pwm + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_FP_RO_PUMP_TARGET_PWM_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("override RO pump target pwm") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(duty_cycle) + + self.logger.debug("RO target pwm overridden to " + str_res) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + Index: leahi_dialin/fp/modules/temperatures.py =================================================================== diff -u -rad1d08ef189799e3f31dcf4e630c21d9f98c33d7 -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/fp/modules/temperatures.py (.../temperatures.py) (revision ad1d08ef189799e3f31dcf4e630c21d9f98c33d7) +++ leahi_dialin/fp/modules/temperatures.py (.../temperatures.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -43,7 +43,7 @@ if self.can_interface is not None: channel_id = DenaliChannels.fp_sync_broadcast_ch_id - msg_id = MsgIds.MSG_ID_RO_TEMPERATURE_DATA.value + msg_id = MsgIds.MSG_ID_FP_TEMPERATURE_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_temperature_sensors_sync) @@ -100,7 +100,7 @@ message = DenaliMessage.build_message( channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_TEMPERATURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_TEMPERATURE_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("Sending {} ms publish interval to the Temperature Sensors module".format(ms)) Index: leahi_dialin/fp/modules/valves.py =================================================================== diff -u -redc0210a1d529761e244dfb05ce9267cdbcbeb53 -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/fp/modules/valves.py (.../valves.py) (revision edc0210a1d529761e244dfb05ce9267cdbcbeb53) +++ leahi_dialin/fp/modules/valves.py (.../valves.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -72,7 +72,7 @@ if self.can_interface is not None: channel_id = DenaliChannels.fp_sync_broadcast_ch_id - msg_id = MsgIds.MSG_ID_RO_VALVES_STATES_DATA.value + msg_id = MsgIds.MSG_ID_FP_VALVES_STATES_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_valves_sync) self.valve_states_all = 0x0000 @@ -205,7 +205,7 @@ payload = rst + ste + vlv message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_VALVE_SENSED_STATE_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_VALVE_SENSED_STATE_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("Override valve sensed state") @@ -240,7 +240,7 @@ payload = rst + ste + vlv message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_VALVE_CMD_STATE_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_VALVE_CMD_STATE_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("Override valve state") @@ -277,7 +277,7 @@ payload = rst + ivl message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_VALVE_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_VALVE_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("override FP valves states publish interval") Index: leahi_dialin/fp/modules/water_pumps.py =================================================================== diff -u -r240bc21f723606645f4449688cb6d7ff0ca7dd64 -r68422d08c4141999a13496343264483a32314d37 --- leahi_dialin/fp/modules/water_pumps.py (.../water_pumps.py) (revision 240bc21f723606645f4449688cb6d7ff0ca7dd64) +++ leahi_dialin/fp/modules/water_pumps.py (.../water_pumps.py) (revision 68422d08c4141999a13496343264483a32314d37) @@ -32,7 +32,7 @@ class FPPumps(AbstractSubSystem): """ - Dialin API sub-class for RO pump related commands. + Dialin API sub-class for FP water pump driver related commands. """ def __init__(self, can_interface, logger: Logger): @@ -43,53 +43,8 @@ self.can_interface = can_interface self.logger = logger - if self.can_interface is not None: - channel_id = DenaliChannels.fp_sync_broadcast_ch_id - msg_id = MsgIds.MSG_ID_RO_PUMP_DATA.value - self.can_interface.register_receiving_publication_function(channel_id, msg_id, - self._handler_pump_sync) - self.ro_pump_timestamp = 0.0 - self.p12_pump_state = 0 - self.p12_pump_duty_cycle = 0.0 - self.p12_pump_fb_duty_cycle = 0.0 - self.p12_pump_speed = 0.0 - self.p40_pump_state = 0 - self.p40_pump_duty_cycle = 0.0 - self.p40_pump_fb_duty_cycle = 0.0 - self.p40_pump_speed = 0.0 + # no current registered call back methods - - @publish(["ro_pump_timestamp", "p12_pump_state", "p12_pump_duty_cycle", "p12_pump_fb_duty_cycle", - "p12_pump_speed", "p40_pump_state", "p40_pump_duty_cycle", - "p40_pump_fb_duty_cycle", "p40_pump_speed"]) - def _handler_pump_sync(self, message, timestamp=0.0): - """ - Handles published RO pump data messages. RO pump data is captured - for reference. - - @param message: published RO pump data message - @return: none - """ - - self.p12_pump_state = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] - self.p12_pump_duty_cycle = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] - self.p12_pump_fb_duty_cycle = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] - self.p12_pump_speed = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] - self.p40_pump_state = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] - self.p40_pump_duty_cycle = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] - self.p40_pump_fb_duty_cycle = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] - self.p40_pump_speed = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8]))[0] - - self.ro_pump_timestamp = timestamp - def cmd_pump_set_speed_rate_override(self, pump: int, rpm: int, reset: int = NO_RESET) -> int: """ Constructs and sends the boost pump set speed rate command @@ -105,7 +60,7 @@ payload = rst + rpm + pmp message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_BOOST_PUMP_SPEED_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_BOOST_PUMP_SPEED_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("override pump set speed rate point") @@ -129,7 +84,7 @@ def cmd_pump_set_pwm_request(self, pump: int, pwm: int) -> int: """ - Constructs and sends set pwm request for RO pumps \n + Constructs and sends set pwm request for FP pumps \n command. Constraints: Must be logged into FP. @@ -144,7 +99,7 @@ payload = pmp + spd message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_BOOST_PUMP_SET_PWM_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_BOOST_PUMP_SET_PWM_REQUEST.value, payload=payload) self.logger.debug("setting pump {} to pwm count {}".format(pump,pwm)) @@ -164,7 +119,7 @@ def cmd_pump_read_pwm_override(self, pump: int, pwm: float, reset: int = NO_RESET) -> int: """ - Constructs and sends the read pwm override for the RO pumps \n + Constructs and sends the read pwm override for the FP pumps \n command. Constraints: Must be logged into FP. @@ -180,7 +135,7 @@ payload = rst + rpwm + pmp message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_BOOST_PUMP_READ_PWM_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_BOOST_PUMP_READ_PWM_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("override read pwm for pump".format(pump)) @@ -204,7 +159,7 @@ def cmd_pump_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ - Constructs and sends the RO pump broadcast interval override command + Constructs and sends the FP pump broadcast interval override command Constraints: Must be logged into FP. Given interval must be non-zero and a multiple of the FP general task interval (50 ms). @@ -222,7 +177,7 @@ payload = rst + mis message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, - message_id=MsgIds.MSG_ID_RO_BOOST_PUMPS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + message_id=MsgIds.MSG_ID_FP_BOOST_PUMPS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) self.logger.debug("override FP pump broadcast interval") Index: leahi_dialin/fp/proxies/__init__.py =================================================================== diff -u --- leahi_dialin/fp/proxies/__init__.py (revision 0) +++ leahi_dialin/fp/proxies/__init__.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1 @@ \ No newline at end of file Index: leahi_dialin/fp/proxies/dd_proxy.py =================================================================== diff -u --- leahi_dialin/fp/proxies/dd_proxy.py (revision 0) +++ leahi_dialin/fp/proxies/dd_proxy.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,62 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file dd_proxy.py +# +# @author (last) Micahel Garthwaite +# @date (last) 18-Aug-2023 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 +# +############################################################################ +import struct +from logging import Logger + +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.protocols.CAN import DenaliMessage, DenaliCanMessenger, DenaliChannels +from leahi_dialin.utils.base import AbstractSubSystem, publish +from leahi_dialin.utils.conversions import integer_to_bytearray, byte_to_bytearray, float_to_bytearray + + +class DDProxy(AbstractSubSystem): + """ + Filtration Purification (FP) Dialin API sub-class for DD proxy ( injection ) related commands. + """ + + def __init__(self, can_interface: DenaliCanMessenger, logger: Logger): + """ + ROProxy constructor + + @param can_interface: the Denali CAN interface object + """ + + super().__init__() + self.can_interface = can_interface + self.logger = logger + + # no current registered call back methods + + def cmd_dd_send_ro_start_stop_request(self, cmdID: int = 0, start: bool = 0, ro_rate: float = 0): + """ + Constructs and sends a DD command request to the FP. + + @param: cmd_id: The DD command ID + @param: rejected: 0 for acceptance, 1 for rejection + @param: rejection_code: The rejection reason. + @return: none + """ + cmd = integer_to_bytearray(cmdID) + stt = integer_to_bytearray(start) + rtt = float_to_bytearray(ro_rate) + payload = cmd + stt + rtt + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_fp_ch_id, + message_id=MsgIds.MSG_ID_DD_FP_START_STOP_CMD_REQUEST.value, + payload=payload) + + self.logger.debug("Sending DD start stop request to FP.") + self.can_interface.send(message, 0) + Index: tests/data_capture_helpers/__init__.py =================================================================== diff -u --- tests/data_capture_helpers/__init__.py (revision 0) +++ tests/data_capture_helpers/__init__.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1 @@ \ No newline at end of file Index: tests/data_capture_helpers/fp_helpers.py =================================================================== diff -u --- tests/data_capture_helpers/fp_helpers.py (revision 0) +++ tests/data_capture_helpers/fp_helpers.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,243 @@ +import os +import glob +import pandas as pd +import shutil +from pandas.io.formats import excel +from time import sleep +from threading import Lock + + +from leahi_dialin import FP +from leahi_dialin.fp.modules.conductivity_sensors import FPConductivitySensorsEnum +from leahi_dialin.fp.modules.flow_sensors import FPFlowSensorNames +from leahi_dialin.fp.modules.pressure_sensors import FPPressureSensorNames +from leahi_dialin.fp.modules.levels import FPFloaterLevels +from leahi_dialin.fp.modules.valves import FPValveNames, FPValveStates +from leahi_dialin.fp.modules.temperatures import FPTemperaturesNames + +excel.ExcelFormatter.header_style = None +write_mutex = Lock() + +DEFAULT_LOG_DIR = "/tmp/FP_logs/" + + +def fp_combine_logs(logs_path = DEFAULT_LOG_DIR, output_path = "/home/denali/Desktop/"): + date_time_obj = pd.Timestamp.strftime(pd.Timestamp.now(),'%Y_%m_%d_%H_%M') + writer = pd.ExcelWriter('{}FP_Dianogistics_{}.xlsx'.format(output_path,date_time_obj, engine='openpyxl')) + + log_files = [f for f in glob.glob( logs_path + "*.log")] + if len(log_files) != 0: + for file in log_files: + df = pd.read_csv(file) + print("Adding {}".format(file)) + df.to_excel( writer, header = False,index=False, + sheet_name=os.path.split(file)[1], float_format = "%0.1f") + writer.close() + else: + print("no files found.") + +def fp_log_setup(logs_path = DEFAULT_LOG_DIR): + if os.path.exists(logs_path) and os.path.isdir(logs_path): + shutil.rmtree(logs_path) + + os.mkdir(DEFAULT_LOG_DIR) + +def fp_float_controller(fp:FP, interval: float = 0.5): + """ + Method to handle the float controllers of the permeate tank. Checks every half second. + Used in situations where the IOFP is not actively controlling the tank and water is flowing. + Constraints: + - Expected to be logged into the FP before call. + :param fp: FP class + :param interval: sleep time interval + :return: none + """ + # only manage if we know that the pump is running + while True: + if fp.levels.p25_level == FPFloaterLevels.LEVEL_STATE_HIGH.value: + if fp.valves.m4_valv != FPValveStates.VALVE_STATE_CLOSED.value: + fp.valves.cmd_valve_override(FPValveNames.M4_VALV.value, FPValveStates.VALVE_STATE_CLOSED.value) + + if fp.levels.p25_level == FPFloaterLevels.LEVEL_STATE_LOW.value: + if fp.valves.m4_valv != FPValveStates.VALVE_STATE_OPEN.value: + fp.valves.cmd_valve_override(FPValveNames.M4_VALV.value, FPValveStates.VALVE_STATE_OPEN.value) + sleep(interval) + +def fp_pressure_recorder(fp:FP, interval: float = 1.0, log_path : str = "{}FP_test_pressures.log".format(DEFAULT_LOG_DIR)): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + press = "{}, ".format(FPPressureSensorNames.M1_PRES.name) + '{}'.format(fp.pressures.m1_pres) + \ + ", {}, ".format(FPPressureSensorNames.M3_PRES.name) + '{}'.format(fp.pressures.m3_pres) + \ + ", {}, ".format(FPPressureSensorNames.P8_PRES.name) + '{}'.format(fp.pressures.p8_pres) + \ + ", {}, ".format(FPPressureSensorNames.P13_PRES.name) + '{}'.format(fp.pressures.p13_pres) + \ + ", {}, ".format(FPPressureSensorNames.P17_PRES.name) + '{}'.format(fp.pressures.p17_pres) + \ + ", {}, ".format(FPPressureSensorNames.X1_PRES.name) + '{}'.format(fp.pressures.x1_pres) + \ + ", {}, ".format(FPPressureSensorNames.X2_PRES.name) + '{}'.format(fp.pressures.x2_pres) + \ + ", {}, ".format(FPPressureSensorNames.X3_PRES.name) + '{}'.format(fp.pressures.x3_pres) + \ + ", {} ,".format(FPPressureSensorNames.X4_PRES.name) + '{}'.format(fp.pressures.x4_pres) + \ + ", {}\n".format(fp.pressures.fp_pressure_timestamp) + + f.write(press) + f.close() + write_mutex.release() + sleep(interval) + +def fp_temperature_recorder(fp:FP, interval: float = 1.0, log_path : str = "{}FP_test_temperatures.log".format(DEFAULT_LOG_DIR)): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + temp = "{}_TEMP, ".format(FPFlowSensorNames.P7_FLOW.name) + \ + '{}'.format(fp.flows.p7_temp) + \ + ", {}_TEMP, ".format(FPFlowSensorNames.P16_FLOW.name) + \ + '{}'.format(fp.flows.p16_temp) + \ + ", {}, ".format(FPTemperaturesNames.P23_TEMP.name) + \ + '{}'.format(fp.temperatures.fp_temperatures[FPTemperaturesNames.P23_TEMP.name]) + \ + ", {}, ".format(FPTemperaturesNames.P22_TEMP.name) + \ + '{}'.format(fp.temperatures.fp_temperatures[FPTemperaturesNames.P22_TEMP.name]) + \ + ", {}, ".format(FPTemperaturesNames.P10_TEMP.name) + \ + '{}'.format(fp.temperatures.fp_temperatures[FPTemperaturesNames.P10_TEMP.name]) + \ + ", {}, ".format(FPTemperaturesNames.P19_TEMP.name) + \ + '{}'.format(fp.temperatures.fp_temperatures[FPTemperaturesNames.P19_TEMP.name]) + \ + ", {}, ".format(FPTemperaturesNames.FP_BOARD_TEMP.name) + \ + '{}'.format(fp.temperatures.fp_temperatures[FPTemperaturesNames.FP_BOARD_TEMP.name]) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.M1_PRES.name) + \ + '{}'.format(fp.pressures.m1_pres_temp) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.M3_PRES.name) + \ + '{}'.format(fp.pressures.m3_pres_temp) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.P8_PRES.name) + \ + '{}'.format(fp.pressures.p8_pres_temp) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.P13_PRES.name) + \ + '{}'.format(fp.pressures.p13_pres_temp) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.P17_PRES.name) + \ + '{}'.format(fp.pressures.p17_pres_temp) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.X1_PRES.name) + \ + '{}'.format(fp.pressures.x1_pres_temp) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.X2_PRES.name) + \ + '{}'.format(fp.pressures.x2_pres_temp) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.X3_PRES.name) + \ + '{}'.format(fp.pressures.x3_pres_temp) + \ + ", {}_TEMP, ".format(FPPressureSensorNames.X4_PRES.name) + \ + '{}'.format(fp.pressures.x4_pres_temp) + \ + ", {}\n".format(fp.temperatures.fp_temperature_sensors_timestamp) + + f.write(temp) + f.close() + write_mutex.release() + sleep(interval) + +def fp_level_recorder(fp:FP, interval: float = 1.0, log_path : str = "{}FP_test_float.log".format(DEFAULT_LOG_DIR)): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + level = "p25_level, " + '{}'.format(fp.levels.p25_level) + \ + ", {}\n".format(fp.levels.fp_levels_timestamp) + + f.write(level) + f.close() + write_mutex.release() + sleep(interval) + +def fp_flow_recorder(fp:FP, interval: float = 1.0, log_path : str = "{}FP_test_flow.log".format(DEFAULT_LOG_DIR) ): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + flows = "{}, ".format(FPFlowSensorNames.P7_FLOW.name) + '{}'.format(fp.flows.p7_flow) + \ + ", {}, ".format(FPFlowSensorNames.P16_FLOW.name) + '{}'.format(fp.flows.p16_flow) + \ + ", {}\n".format(fp.flows.fp_flow_timestamp) + + f.write(flows) + f.close() + write_mutex.release() + sleep(interval) + +def fp_conductivity_recorder(fp:FP, interval: float = 1.0, log_path : str = "{}FP_test_conductivity.log".format(DEFAULT_LOG_DIR) ): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + cond = "{}, ".format(FPConductivitySensorsEnum.P9_COND.name) + '{}'.format(fp.conductivity.p9_cond) + \ + ", {}, ".format(FPConductivitySensorsEnum.P18_COND.name) + '{}'.format(fp.conductivity.p18_cond) + \ + ", {}\n".format(fp.conductivity.fp_conductivity_timestamp) + + f.write(cond) + f.close() + write_mutex.release() + sleep(interval) + +def fp_valve_recorder(fp:FP, interval: float = 1.0, log_path : str = "{}FP_test_valve.log".format(DEFAULT_LOG_DIR) ): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + list_of_states = fp.valves.get_valve_states() + valves = "{}, ".format(FPValveNames.M4_VALV.name) + '{}'.format(list_of_states[0]) + \ + ", {}, ".format(FPValveNames.P39_VALV.name) + '{}'.format(list_of_states[1]) + \ + ", {}, ".format(FPValveNames.P6_VALV.name) + '{}'.format(list_of_states[2]) + \ + ", {}, ".format(FPValveNames.P11_VALV.name) + '{}'.format(list_of_states[3]) + \ + ", {}, ".format(FPValveNames.P33_VALV.name) + '{}'.format(list_of_states[4]) + \ + ", {}, ".format(FPValveNames.P34_VALV.name) + '{}'.format(list_of_states[5]) + \ + ", {}, ".format(FPValveNames.P37_VALV.name) + '{}'.format(list_of_states[6]) + \ + ", {}, ".format(FPValveNames.M7_VALV.name) + '{}'.format(list_of_states[7]) + \ + ", {}, ".format(FPValveNames.P20_VALV.name) + '{}'.format(list_of_states[8]) + \ + ", {}\n".format(fp.valves.fp_valves_states_timestamp) + + f.write(valves) + f.close() + write_mutex.release() + sleep(interval) + +def fp_ro_pump_recorder(fp:FP, interval: float = 1.0, log_path: str = "{}FP_test_ro_pump.log".format(DEFAULT_LOG_DIR) ): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + ro = "p12_pump_state, ".format(FPValveNames.M4_VALV.name) + '{}'.format(fp.ro_pump.p12_pump_state) + \ + ", p12_pump_duty_cycle, ".format(FPValveNames.P39_VALV.name) + '{}'.format(fp.ro_pump.p12_pump_duty_cycle) + \ + ", p12_pump_fb_duty_cycle, ".format(FPValveNames.P6_VALV.name) + '{}'.format(fp.ro_pump.p12_pump_fb_duty_cycle) + \ + ", p12_pump_speed, ".format(FPValveNames.P11_VALV.name) + '{}'.format(fp.ro_pump.p12_pump_speed) + \ + ", p12_target_pressure, ".format(FPValveNames.P33_VALV.name) + '{}'.format(fp.ro_pump.p12_target_pressure) + \ + ", p12_target_flow, ".format(FPValveNames.P34_VALV.name) + '{}'.format(fp.ro_pump.p12_target_flow) + \ + ", p12_target_duty_cycle, ".format(FPValveNames.P37_VALV.name) + '{}'.format(fp.ro_pump.p12_target_duty_cycle) + \ + ", {}\n".format(fp.ro_pump.ro_pump_timestamp) + + f.write(ro) + f.close() + write_mutex.release() + sleep(interval) + +def fp_boost_pump_recorder(fp:FP, interval: float = 1.0, log_path : str = "{}FP_test_boost_pump.log".format(DEFAULT_LOG_DIR) ): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + boost = "p40_pump_state, " + '{}'.format(fp.boost_pump.p40_pump_state) + \ + ", p40_pump_duty_cycle, " + '{}'.format(fp.boost_pump.p40_pump_duty_cycle) + \ + ", p40_pump_fb_duty_cycle, " + '{}'.format(fp.boost_pump.p40_pump_fb_duty_cycle) + \ + ", p40_pump_speed, " + '{}'.format(fp.boost_pump.p40_pump_speed) + \ + " p40_target_pressure, " + '{}'.format(fp.boost_pump.p40_target_pressure) + \ + ", p40_target_flow, " + '{}'.format(fp.boost_pump.p40_target_flow) + \ + ", p40_target_duty_cycle, " + '{}'.format(fp.boost_pump.p40_target_duty_cycle) + \ + ", {}\n".format(fp.boost_pump.boost_pump_timestamp) + + f.write(boost) + f.close() + write_mutex.release() + sleep(interval) + +def fp_op_mode_recorder(fp:FP, interval: float = 1.0, log_path: str = "{}FP_test_op_mode.log".format(DEFAULT_LOG_DIR) ): + while True: + write_mutex.acquire() + with open(log_path, "a") as f: + # collect data and log it + ro = "op_mode, " + '{}'.format(fp.fp_operation_mode) + \ + ", sub_mode, " + '{}'.format(fp.fp_operation_mode) + \ + ", {}\n".format(fp.fp_op_mode_timestamp) + f.write(ro) + f.close() + write_mutex.release() + sleep(interval) \ No newline at end of file Index: tests/depreciated_tests/dg_hd_switches_test.py =================================================================== diff -u --- tests/depreciated_tests/dg_hd_switches_test.py (revision 0) +++ tests/depreciated_tests/dg_hd_switches_test.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,63 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file dg_hd_switches_test.py +# +# @author (last) Dara Navaei +# @date (last) 20-Apr-2022 +# @author (original) Dara Navaei +# @date (original) 29-Jul-2021 +# +############################################################################ + + +from dialin.dg.dialysate_generator import DG +from dialin.dg.switches import DGSwitchesName, DGSwitchStatus +from dialin.hd.switches import HDSwitchesNames, HDSwitchStatus +from dialin.hd.hemodialysis_device import HD +from time import sleep + + +def test_hd_switches(): + + hd = HD(log_level="DEBUG") + if hd.cmd_log_in_to_hd(resend=False): + print(hd.switches.get_switches_status()) + + #hd.switches.cmd_hd_switch_status_override(HDSwitchesNames.FRONT_DOOR.value, HDSwitchStatus.ON.value, reset=1) + #hd.switches.cmd_hd_switches_data_broadcast_interval_override(100, reset=1) + + while True: + print(hd.switches.get_switches_status()) + sleep(1) + + +def test_dg_switches(): + + dg = DG(log_level="DEBUG") + if dg.cmd_log_in_to_dg(resend=False): + #print(dg.switches.get_switches_status()) + + #dg.switches.cmd_dg_switch_status_override(DGSwitchesName.FLUID_DOOR.value, DGSwitchStatus.ON.value) + #dg.switches.cmd_dg_switch_status_override(DGSwitchesName.CONCENTRATE_CAP.value, DGSwitchStatus.OFF.value, reset=1) + + #dg.switches.cmd_dg_switches_data_broadcast_interval_override(100, reset=1)switch + + while True: + + print(dg.switches.get_switches_status()) + sleep(0.1) + + +if __name__ == "__main__": + + test_hd_switches() + #test_dg_switches() + + + + Index: tests/depreciated_tests/dg_heaters_test.py =================================================================== diff -u --- tests/depreciated_tests/dg_heaters_test.py (revision 0) +++ tests/depreciated_tests/dg_heaters_test.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,81 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file dg_heaters_test.py +# +# @author (last) Steve Jarpe +# @date (last) 30-Nov-2022 +# @author (original) Dara Navaei +# @date (original) 29-May-2020 +# +############################################################################ +import sys +sys.path.append("..") +from dialin.dg.dialysate_generator import DG +from time import sleep + +if __name__ == "__main__": + + dg = DG() + + dg.cmd_log_in_to_dg() + counter=0 + dg.cmd_ui_request_dg_version() + sleep(1) + print(dg.dg_version) + dg.heaters.cmd_start_stop_primary_heater() + + """ + hd.ro_pump.cmd_ro_pump_set_point_override(120) + + + hd.heaters.cmd_set_dialysate_target_temperature() + + sleep(1) + #hd.heaters.cmd_start_primary_heater() + #sleep(1) + hd.heaters.cmd_start_trimmer_heater() + sleep(1) + #hd.heaters.cmd_heaters_broadcast_interval_override(200) + #hd.temperature_sensors.cmd_temperature_sensors_override_value(0, 125.0, reset=1) + #hd.temperature_sensors.cmd_temperature_sensors_broadcast_interval_override(200, reset=1) + + #hd.ro_pump.cmd_ro_flow_rate_override(0.46) + + while True: + print("TPi: {}, TPo: {}, TD1: {}, TD2: {}, TRo: {}, TDi: {}".format(hd.temperature_sensors.inlet_primary, + hd.temperature_sensors.outlet_primary, + hd.temperature_sensors.cd1, + hd.temperature_sensors.cd2, + hd.temperature_sensors.outlet_redundancy, + hd.temperature_sensors.inlet_dialysate)) + #print("Main Primary Heater DC: {}".format(hd.heaters.mainPrimaryHeaterPWM)) + #print("Small Primary Heater DC: {}".format(hd.heaters.smallPrimaryHeaterPWM)) + #print("Trimmer Heater DC: {}".format(hd.heaters.trimmerHeaterPWM)) + sleep(1) + counter = counter + 1 + + if counter > 60: + #print(counter) + break + + hd.heaters.cmd_stop_trimmer_heater() + #hd.heaters.cmd_stop_primary_heater() + sleep(1) + + + while True: + print("Main Primary Heater DC: {}".format(hd.heaters.mainPrimaryHeaterPWM)) + print("Small Primary Heater DC: {}".format(hd.heaters.smallPrimaryHeaterPWM)) + print("Trimmer Heater DC: {}".format(hd.heaters.trimmerHeaterPWM)) + sleep(0.7) + """ + + + + + Index: tests/depreciated_tests/dg_nvm_scripts.py =================================================================== diff -u --- tests/depreciated_tests/dg_nvm_scripts.py (revision 0) +++ tests/depreciated_tests/dg_nvm_scripts.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,125 @@ +########################################################################### +# +# Copyright (c) 2022-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file dg_nvm_scripts.py +# +# @author (last) Dara Navaei +# @date (last) 02-Mar-2024 +# @author (original) Dara Navaei +# @date (original) 10-Feb-2022 +# +############################################################################ +from dialin import DG + + +def run_sw_configs_commands(): + # NOTE: For further details, please refer to 'Instructions to Change the Software Configurations Dynamically' in + # the development section of the DevOps OneNote file + + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_sw_config_record() to get the software configurations record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called DG_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + #dg.sw_configs.cmd_get_dg_sw_config_record() + + # Use cmd_set_dg_sw_config_record() set the changes back to firmware + # This function requires an address for the excel report. Use the absolute address of your excel report like the + # example below + dg.sw_configs.cmd_update_dg_sw_config_record('/home/fw/projects/DG_NV_Records/2023-07-20-DG-SW-CONFIGS-Record.xlsx') + + # Use this function to reset the configuration records to all be 0 + #dg.sw_configs.cmd_reset_dg_sw_config_record() + + +def run_calibration_commands(): + # NOTE: For further details, please refer to 'Instructions to Calibrate a Device Using the Calibration Report' + # in the development section of the DevOps OneNote file + + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_calibration_record_report() to get the calibration record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called DG_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in you computer. + #dg.calibration_record.cmd_get_dg_calibration_record_report() + + # Use cmd_set_dg_calibration_excel_to_fw() set the changes back to firmware + # This function requires an address for the excel report. Use the absolute address of your excel report like the + # example below + dg.calibration_record.cmd_set_dg_calibration_excel_to_fw('/home/fw/projects/DG_NV_Records/2024-03-02-DG-Record.xlsx') + + # For resetting the calibration record to benign values, use the function below + #dg.calibration_record.cmd_reset_dg_calibration_record() + + +def run_system_commands(): + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_system_record_report() to get the system record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called DG_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + dg.system_record.cmd_get_dg_system_record_report() + + #dg.system_record.cmd_set_dg_system_record_excel_to_fw('/home/fw/projects/DG_NV_Records/2023-02-04-DG-Record.xlsx') + + # For resetting the system record to benign values, use the function below + #dg.system_record.cmd_reset_dg_system_record() + + +def run_usage_info_commands(): + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_system_record_report() to get the system record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called DG_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + dg.usage_record.cmd_get_dg_usage_info_record() + + #dg.usage_record.cmd_set_dg_usage_info_excel_to_fw('/home/fw/projects/DG_NV_Records/2023-06-13-DG-Record.xlsx') + + #dg.usage_record.cmd_reset_dg_usage_info_record() + + +def run_service_commands(): + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_system_record_report() to get the system record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called DG_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + #dg.service_record.cmd_get_dg_service_record() + + dg.service_record.cmd_set_dg_service_record_excel_to_fw('/home/fw/projects/DG_NV_Records/2023-10-23-DG-Record.xlsx') + + #dg.service_record.cmd_reset_dg_service_record() + + +if __name__ == "__main__": + + dg = DG(log_level="DEBUG") + + if dg.cmd_log_in_to_dg(): + + #run_sw_configs_commands() + + run_calibration_commands() + + #run_system_commands() + + #run_usage_info_commands() + + #run_service_commands() + + Index: tests/depreciated_tests/dg_tests.py =================================================================== diff -u --- tests/depreciated_tests/dg_tests.py (revision 0) +++ tests/depreciated_tests/dg_tests.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,810 @@ +########################################################################### +# +# Copyright (c) 2022-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file dg_tests.py +# +# @author (last) Dara Navaei +# @date (last) 18-Mar-2024 +# @author (original) Dara Navaei +# @date (original) 16-Jan-2022 +# +############################################################################ +import os + +from dialin.dg.dialysate_generator import DG +from dialin.hd.hemodialysis_device import HD +from dialin.dg.load_cells import DGLoadCellNames +from dialin.ui.hd_simulator import HDSimulator +from dialin.common.dg_defs import DGHeatDisinfectStates, DGHeatDisinfectUIStates +from dialin.dg.heat_disinfect import HeatCancellationModes, NelsonSupportModes +from dialin.common.dg_defs import DGChemicalDisinfectStates, DGChemDisinfectUIStates +from dialin.common.dg_defs import DGChemDisinfectFlushStates, DGChemDisinfectFlushUIStates +from dialin.dg.chemical_disinfect import ChemCancellationModes +from dialin.dg.drain_pump import DrainPumpStates, DrainPumpRPMFeedBackSensors +from dialin.dg.thermistors import ThermistorsNames +from dialin.dg.temperatures import DGTemperaturesNames +from dialin.dg.dialysate_generator import DGOperationModes +from dialin.hd.temperatures import HDTemperaturesNames +from dialin.dg.concentrate_pumps import DGConcentratePumpsStates +from dialin.dg.uv_reactors import ReactorsNames +from dialin.common.hd_defs import HDOpModes, HDStandbyStates, PreTreatmentWetSelfTestStates, PostTreatmentStates, \ + PreTreatmentDrySelfTestsStates +from dialin.hd.post_treatment import HDPostTreatmentDrainStates +from dialin.common.dg_defs import DGEventList +from dialin.common.hd_defs import HDEventList +from dialin.hd.reservoirs import HDReservoirStates +from dialin.dg.reservoirs import DGReservoirsNames +from dialin.common.dg_defs import DGGenIdleModeBadFillSubStates +from dialin.common.alarm_defs import AlarmList +from dialin.dg.fans import DGFansNames +from dialin.dg.pressures import DGPressures +from dialin.dg.conductivity_sensors import ConductivitySensorsEnum +from dialin.dg.voltages import DGMonitoredVoltages +from dialin.dg.valves import DGValveNames +from dialin.hd.valves import HDValves +from dialin.hd.voltages import HDMonitoredVoltages +from dialin.hd.pretreatment import PreTreatmentRsrvrState +from dialin.common.dg_defs import DGFlushStates, DGHeatDisinfectActiveCoolStates, DGROPermeateSampleStates +from dialin.dg.ro_permeate_sample import ROPermeateDispenseMsgStatus +from dialin.common.test_config_defs import DGTestConfigOptions, HDTestConfigOptions +from dialin.hd.blood_leak import EmbModeCommands +from time import sleep, time +from datetime import datetime +import sys + +sys.path.append("..") + + +def get_chemical_disinfect_mode_info(): + state = 0 + state_elapsed_time = 0 + overall_elapsed_time = 0 + + if dg.dg_operation_mode == 10: + state = DGChemicalDisinfectStates(dg.chemical_disinfect.chemical_disinfect_state).name + overall_elapsed_time = dg.chemical_disinfect.overall_elapsed_time + state_elapsed_time = dg.chemical_disinfect.state_elapsed_time + elif dg.dg_operation_mode == 11: + state = DGChemDisinfectFlushStates(dg.chemical_disinfect_flush.flush_state).name + overall_elapsed_time = dg.chemical_disinfect_flush.overall_elapsed_time + state_elapsed_time = dg.chemical_disinfect_flush.state_elapsed_time + + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, Disinfect_elapsed_time, {}, ' + 'Cancellation_mode, {}, R1_level, {:5.3f}, R2_level, {:5.3f}, Current_rinse_count, {}, ' + 'Total_rinse_count, {}, Top_alarm, {}, chem_acid_avg_cond, {:5.3f}, ' + .format(state, overall_elapsed_time, state_elapsed_time, + dg.chemical_disinfect.chemical_disinfect_target_time, + ChemCancellationModes(dg.chemical_disinfect.cancellation_mode).name, dg.chemical_disinfect.r1_level, + dg.chemical_disinfect.r2_level, dg.chemical_disinfect_flush.rinse_count, + dg.chemical_disinfect_flush.rinse_count, hd.alarms.alarm_top, + dg.chemical_disinfect.acid_average_cond_us_per_cm)) + return info + + +def get_chemical_disinfect_flush_mode_info(): + state = 0 + state_elapsed_time = 0 + overall_elapsed_time = 0 + if dg.dg_operation_mode == 10: + state = DGChemDisinfectFlushStates(dg.chemical_disinfect_flush.flush_state).name + overall_elapsed_time = dg.chemical_disinfect.overall_elapsed_time + state_elapsed_time = dg.chemical_disinfect.state_elapsed_time + elif dg.dg_operation_mode == 11: + state = DGHeatDisinfectActiveCoolStates(dg.heat_disinfect_active_cool.heat_disinfect_active_cool_state).name + overall_elapsed_time = dg.heat_disinfect_active_cool.overall_elapsed_time + state_elapsed_time = dg.heat_disinfect_active_cool.state_elapsed_time + + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, r1, {:5.1f}, r2, {:5.1f}, ' + 'Target_rinse_count, {}, Rinse_count, {}, Top_alarm, {}, UI_state, {},' + .format(state, overall_elapsed_time, state_elapsed_time, + dg.chemical_disinfect_flush.r1, dg.chemical_disinfect_flush.r2, + dg.chemical_disinfect_flush.target_rinse_count, dg.chemical_disinfect_flush.rinse_count, + hd.alarms.alarm_top, dg.chemical_disinfect_flush.flush_UI_state)) + return info + + +def get_heat_disinfect_mode_info(): + state = 0 + state_elapsed_time = 0 + overall_elapsed_time = 0 + if dg.dg_operation_mode == 9: + state = DGHeatDisinfectStates(dg.heat_disinfect.heat_disinfect_state).name + overall_elapsed_time = dg.heat_disinfect.overall_elapsed_time + state_elapsed_time = dg.heat_disinfect.state_elapsed_time + elif dg.dg_operation_mode == 12: + state = DGHeatDisinfectActiveCoolStates(dg.heat_disinfect_active_cool.heat_disinfect_active_cool_state).name + overall_elapsed_time = dg.heat_disinfect_active_cool.overall_elapsed_time + state_elapsed_time = dg.heat_disinfect_active_cool.state_elapsed_time + + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, Disinfect_RO_77, {}, Disinfect_RO_82, {}, ' + 'Disinfect_R_77, {}, Disinfect_R_82, {}, R1_level, {:5.3f}, R2_level, {:5.3f}, Top_alarm, {}, UI_state, {},' + ' ' + .format(state, overall_elapsed_time, state_elapsed_time, dg.heat_disinfect.disinfect_ro_77_time_s, + dg.heat_disinfect.disinfect_ro_82_time_s, dg.heat_disinfect.disinfect_r_77_time_s, + dg.heat_disinfect.disinfect_r_82_time_s, dg.heat_disinfect.r1_level, dg.heat_disinfect.r2_level, + hd.alarms.alarm_top, DGHeatDisinfectUIStates(dg.heat_disinfect.heat_disinfect_ui_state).name)) + return info + + +def get_ro_permeate_sample_mode_info(): + state = DGROPermeateSampleStates(dg.ro_permeate_sample.ro_permeate_sample_state).name + overall_elapsed_time = dg.ro_permeate_sample.overall_elapsed_time + state_elapsed_time = dg.ro_permeate_sample.state_elapsed_time + + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, dispense_vol_ml, {:5.3f}, dispense_msg, {}, ' + 'dg_op_mode, {}, ' + .format(state, overall_elapsed_time, state_elapsed_time, dg.ro_permeate_sample.dispensed_volume_ml, + ROPermeateDispenseMsgStatus(dg.ro_permeate_sample.ro_permeate_dispense_message_status).name, + dg.dg_operation_mode)) + return info + + +def get_flush_mode_info(): + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, Drain_vol, {:5.3f}, Top_alarm, {}, ' + .format(DGFlushStates(dg.flush.flush_state).name, dg.flush.overall_elapsed_time, dg.flush.state_elapsed_time, + dg.flush.flush_drain_line_volume_l, hd.alarms.alarm_top)) + return info + + +def get_hd_run_info(): + info = ('HD_op_mode, {}, HD_sub_mode, {}, Top_alarm, {}, Target_UF_ml, {:5.3f}, Meas_UF_ml, {:5.3f}, ' + 'Wet_test_state, {}, Post_tx_state, {}, Post_tx_drain_state, {}, Prime_state, {}, Pre_Tx_rsrvr_state, {}, ' + 'Pre_Tx_dry_state, {}, ' + .format(HDOpModes(hd.hd_operation_mode).name, hd.hd_operation_sub_mode, hd.alarms.alarm_top, + hd.dialysate_outlet_flow.reference_dialysate_outlet_uf_volume, + hd.dialysate_outlet_flow.measured_dialysate_outlet_uf_volume, + PreTreatmentWetSelfTestStates(hd.pretreatment.pre_treatment_wet_self_test_state).name, + PostTreatmentStates(hd.post_treatment.post_treatment_sub_mode).name, + HDPostTreatmentDrainStates(hd.post_treatment.post_treatment_drain_state).name, + hd.pretreatment.pre_treatment_prime_state, + PreTreatmentRsrvrState(hd.pretreatment.pre_treatment_reservoir_state).name, + PreTreatmentDrySelfTestsStates(hd.pretreatment.pre_treatment_dry_self_test_state).name)) + return info + + +def get_hd_occlusion_pressures_info(): + info = ('Art_pres, {:5.3f}, Venous_pres, {:5.3f}, Blood_pump_pres, {:5.3f}, DialOut_pres, {}, ' + .format(hd.pressure_occlusion.arterial_pressure, hd.pressure_occlusion.venous_pressure, + hd.pressure_occlusion.blood_pump_occlusion, + hd.pressure_occlusion.dialysate_outlet_pump_occlusion)) + return info + + +def get_hd_reservoirs_info(): + info = ('HD_rsrvr_state, {}, Active_rsrvr, {}, Active_rsrvr_uf, {:5.3f}, Active_rsrvr_vol_spent, {:5.3f}, ' + 'Dilution_level_pct, {:5.3f}, Recirc_level_pct, {:5.3f}, Time_depletion, {}, Time_wait_to_fill, {}, ' + 'Target_fill_flow, {:5.3f}, ' + .format(HDReservoirStates(hd.hd_reservoirs.reservoir_state).name, + DGReservoirsNames(dg.reservoirs.active_reservoir).name, hd.hd_reservoirs.active_reservoir_uf_ml, + hd.hd_reservoirs.active_reservoir_spent_vol_ml, hd.hd_reservoirs.dilution_level_pct, + hd.hd_reservoirs.recirculation_level_pct, hd.hd_reservoirs.time_depletion, + hd.hd_reservoirs.time_wait_to_fill, hd.hd_reservoirs.temp_remove_fill_flow)) + return info + + +def get_dg_reservoirs_info(): + info = ('Time_rsrvr_cycle, {}, Time_rsrvr_fill_2_switch, {}, Time_uf_decay, {:5.3f}, Temp_uf_fill, {:5.3f}, ' + 'Temp_rsrvr_use_actual, {:5.3f}, Temp_rsrvr_end_fill, {:5.3}, Temp_avg_fill, {:5.3f}, ' + 'Temp_last_fill, {:5.3f}, Time_rsrvr_fill, {:5.3f}, ' + .format(dg.reservoirs.time_reservoir_cycle, dg.reservoirs.time_reservoir_fill_2_switch, + dg.reservoirs.time_uf_decay, dg.reservoirs.temp_uf_fill, dg.reservoirs.temp_reservoir_use_actual, + dg.reservoirs.temp_reservoir_end_fill, dg.reservoirs.temp_avg_fill, dg.reservoirs.temp_last_fill, + dg.reservoirs.time_rsrvr_fill)) + return info + + +def get_dg_run_info(): + info = ('DG_op_mode, {}, DG_op_mode_num, {}, DG_sub_mode, {}, '.format(DGOperationModes(dg.dg_operation_mode).name, + dg.dg_operation_mode, + dg.dg_operation_sub_mode)) + return info + + +def get_dg_valves_states(): + info = ('VPi, {}, VSP, {}, VPd, {}, VBf, {}, VPo, {}, VDr, {}, VRc, {}, VRo, {}, VRi, {}, VRf, {}, ' + 'VRD1, {}, VRD2, {}, ' + .format(dg.valves.valve_states_enum[DGValveNames.VALVE_PRESSURE_INLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_SAMPLING_PORT.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_PRODUCTION_DRAIN.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_BYPASS_FILTER.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_PRESSURE_OUTLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_DRAIN.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RECIRCULATE.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_OUTLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_INLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_FILL.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_DRAIN_1.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_DRAIN_2.value])) + return info + + +def get_drain_states_info(): + info = ('Drain, {}, DAC, {}, Tgt_RPM, {}, Curr_RPM, {}, PRd, {:5.3f}, PDr, {:5.3f}, Baro, {:5.3f}, ' + 'Drain_curr_A, {:5.3f}, Drain_dir, {}, Target_flow_lpm, {:5.3f}, Maxon_rpm, {}, ' + .format(DrainPumpStates(dg.drain_pump.drain_pump_state).name, dg.drain_pump.dac_value, + dg.drain_pump.target_drain_pump_rpm, + dg.drain_pump.current_drain_pump_rpm[DrainPumpRPMFeedBackSensors.DRAIN_PUMP_HALL_SNSR_FB.name], + dg.pressures.drain_pump_inlet_pressure, dg.pressures.drain_pump_outlet_pressure, + dg.pressures.barometric_pressure, dg.drain_pump.drain_pump_current_A, + dg.drain_pump.drain_pump_direction, dg.drain_pump.target_drain_pump_outlet_flow_lpm, + dg.drain_pump.current_drain_pump_rpm[DrainPumpRPMFeedBackSensors.DRAIN_PUMP_MAXON_SNSR_FB.name])) + return info + + +def get_load_cells_info(): + info = ('A1, {:5.3f}, A2, {:5.3f}, B1, {:5.3f}, B2, {:5.3f}, ' + .format(dg.load_cells.load_cell_A1, dg.load_cells.load_cell_A2, dg.load_cells.load_cell_B1, + dg.load_cells.load_cell_B2)) + return info + + +def get_ro_info(): + info = ('RO, {}, PPi, {:5.3f}, PPo, {:5.3f}, PWM, {:5.3f}, Flow, {:5.3f}, Tgt_flow, {:5.3f}, ' + 'Feedback_PWM, {:5.3f}, Flow_with_conc_pumps, {:5.3f}, Dialysate_flow, {:5.3f}, ' + .format(dg.ro_pump.ro_pump_state, dg.pressures.ro_pump_inlet_pressure, + dg.pressures.ro_pump_outlet_pressure, dg.ro_pump.pwm_duty_cycle_pct, + dg.flow_sensors.measured_ro_flow_LPM, dg.ro_pump.target_flow_lpm, + dg.ro_pump.feedback_duty_cycle_pct, + dg.flow_sensors.measured_ro_flow_with_cp_LPM, dg.flow_sensors.measured_dialysate_flow_LPM)) + return info + + +def get_heaters_with_no_temp_info(): + info = ('Pri_main_DC, {:5.3f}, Pri_state, {}, Trimmer_DC, {:5.3f}, Trim_state, {}, ' + 'Primary_target_temp, {:5.3f}, Trimmer_target_temp, {:5.3f}, '. + format(dg.heaters.main_primary_heater_duty_cycle, dg.heaters.primary_heater_state, + dg.heaters.trimmer_heater_duty_cycle, dg.heaters.trimmer_heater_state, + dg.heaters.primary_heaters_target_temperature, dg.heaters.trimmer_heater_target_temperature)) + return info + + +def get_heaters_info(): + info = ('Pri_main_DC, {:5.3f}, Pri_state, {}, Trimmer_DC, {:5.3f}, Trimmer_state, {}, ' + 'Primary_target_temp, {:5.3f}, Trimmer_target_temp, {:5.3f}, Primary_eff, {:5.3f}, ' + 'Primary_calc_temp, {:5.3f}, Trimmer_calc_temp, {:5.3f}, Primary_power, {:5.3f}, ' + 'Primary_volt, {:5.3f}, Primary_sec_volt, {:5.3f}, Trimmer_volt, {:5.3f}, Trimmer_use_last_dc, {}, ' + 'previous_flow , {:5.3f}, trimmer_ctrl_cntr, {}, ' + .format(dg.heaters.main_primary_heater_duty_cycle, dg.heaters.primary_heater_state, + dg.heaters.trimmer_heater_duty_cycle, dg.heaters.trimmer_heater_state, + dg.heaters.primary_heaters_target_temperature, dg.heaters.trimmer_heater_target_temperature, + dg.heaters.primary_efficiency, dg.heaters.primary_calc_target_temperature, + dg.heaters.trimmer_calc_target_temperature, + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_POWER_PRIM_HTR_V.value], + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_GND_MAIN_PRIM_HTR_V.value], + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_GND_SMALL_PRIM_HTR_V.value], + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_GND_TRIM_HTR_V.value], + dg.heaters.trimmer_use_last_duty_cycle, dg.heaters.previous_flow, dg.heaters.control_counter)) + return info + + +def get_temperature_sensors_info(): + info = ('TPi, {:5.3f}, THd, {:5.3f}, TPo, {:5.3f}, TD1, {:5.3f}, TD2, {:5.3f}, TRo, {:5.3f}, TDi, {:5.3f}, ' + 'Baro_temp, {:5.3f}, TDi_mving_avg, {:5.3f}, TRo_mving_avg, {:5.3f}, ' + .format(dg.temperatures.temperatures[DGTemperaturesNames.INLET_PRIMARY_HEATER.name], + dg.temperatures.temperatures[DGTemperaturesNames.HEAT_DISINFECT.name], + dg.temperatures.temperatures[DGTemperaturesNames.OUTLET_PRIMARY_HEATER.name], + dg.temperatures.temperatures[DGTemperaturesNames.CONDUCTIVITY_SENSOR_1.name], + dg.temperatures.temperatures[DGTemperaturesNames.CONDUCTIVITY_SENSOR_2.name], + dg.temperatures.temperatures[DGTemperaturesNames.OUTLET_DIALYSATE_REDUNDANT.name], + dg.temperatures.temperatures[DGTemperaturesNames.INLET_DIALYSATE.name], + dg.temperatures.temperatures[DGTemperaturesNames.BARO_TEMP_SENSOR.name], + dg.temperatures.dialysate_inlet_moving_avg, dg.temperatures.redundant_outlet_moving_avg)) + return info + + +def get_dg_fans_info(): + info = ('Target_fans_DC, {:5.3f}, Inlet1_RPM, {:5.3f}, Inlet2_RPM, {:5.3f}, Inlet3_RPM, {:5.3f}, ' + 'Outlet1_RPM, {:5.3f}, Outlet2_RPM, {:5.3f}, Outlet3_RPM, {:5.3f}, Board_temp, {:5.3f}, ' + 'Power_supply_1, {:5.3f}, Power_supply_2, {:5.3f}, FPGA_temp, {:5.3f}, Load_cell_A1_B1, {:5.3f}, ' + 'Load_cell_A2_B2, {:5.3f}, timeOffset, {}, ' + .format(dg.fans.dg_fans_duty_cycle, dg.fans.inlet_1_rpm, dg.fans.inlet_2_rpm, dg.fans.inlet_3_rpm, + dg.fans.outlet_1_rpm, dg.fans.outlet_2_rpm, dg.fans.outlet_3_rpm, + dg.thermistors.thermistors[ThermistorsNames.THERMISTOR_ONBOARD_NTC.name], + dg.thermistors.thermistors[ThermistorsNames.THERMISTOR_POWER_SUPPLY_1.name], + dg.thermistors.thermistors[ThermistorsNames.THERMISTOR_POWER_SUPPLY_2.name], + dg.temperatures.temperatures[DGTemperaturesNames.FPGA_BOARD_SENSOR.name], + dg.temperatures.temperatures[DGTemperaturesNames.LOAD_CELL_A1_B1.name], + dg.temperatures.temperatures[DGTemperaturesNames.LOAD_CELL_A2_B2.name], + dg.fans.rpm_alarm_time)) + return info + + +def get_hd_fans_info(): + info = ('HD_Fan_DC, {:5.3f}, Target_HD_RPM, {:5.3f}, Inlet1_RPM, {:5.3f}, HD_Board_temp, {:5.3f}, ' + 'HD_Power_supply, {:5.3f}, HD_FPGA_temp, {:5.3f}, Venous_temp, {:5.3f}, ' + 'Arterial_temp, {:5.3f}, RPM_time_offset, {}, ' + .format(hd.fans.duty_cycle, hd.fans.target_rpm, hd.fans.inlet_1_rpm, + hd.temperatures.hd_temperatures[HDTemperaturesNames.THERMISTOR_ONBOARD_NTC.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.THERMISTOR_POWER_SUPPLY_1.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_FPGA_BOARD.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_VENOUS_PRESS_TEMP.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_ARTERIAL_PRESS_TEMP.name], + hd.fans.rpm_alarm_time)) + return info + + +def get_uv_reactors_info(): + info = ('Inlet_status, {}, Outlet_status, {}, Inlet_health, {}, Outlet_health, {}, ' + .format(dg.uv_reactors.inlet_uv_reactor_state, dg.uv_reactors.outlet_uv_reactor_state, + dg.uv_reactors.inlet_uv_reactor_health, dg.uv_reactors.outlet_uv_reactor_health)) + return info + + +def get_concentrate_pumps_info(): + info = ('Bicarb_curr_speed, {:5.3f}, Bicarb_speed, {:5.3f}, Acid_curr_speed, {:5.3f}, Acid_speed, {:5.3f}, ' + 'CPi, {:5.3f}, CPo, {:5.3f}, CD1, {:5.3f}, CD2, {:5.3f}, CP1_state, {}, CP2_state, {}, CPi_status, {}, ' + 'CPo_status, {}, CD1_status, {}, CD2_status, {}, CP1_pulse, {:5.3f}, CP2_pulse, {:5.3f}, ' + 'Acid_tgt_speed, {:5.3f}, Bicarb_tgt_speed, {:5.3f}, CP1_parked, {}, CP1_park_fault, {}, CP2_parked, {}, ' + 'CP2_park_fault, {}, ' + .format(dg.concentrate_pumps.concentrate_pump_cp2_current_set_speed, + dg.concentrate_pumps.concentrate_pump_cp2_measured_speed, + dg.concentrate_pumps.concentrate_pump_cp1_current_set_speed, + dg.concentrate_pumps.concentrate_pump_cp1_measured_speed, + dg.conductivity_sensors.conductivity_sensor_cpi, + dg.conductivity_sensors.conductivity_sensor_cpo, dg.conductivity_sensors.conductivity_sensor_cd1, + dg.conductivity_sensors.conductivity_sensor_cd2, + DGConcentratePumpsStates(dg.concentrate_pumps.concentrate_pump_cp1_current_state).name, + DGConcentratePumpsStates(dg.concentrate_pumps.concentrate_pump_cp2_current_state).name, + dg.conductivity_sensors.cpi_sensor_status, dg.conductivity_sensors.cpo_sensor_status, + dg.conductivity_sensors.cd1_sensor_status, dg.conductivity_sensors.cd2_sensor_status, + dg.concentrate_pumps.cp1_temp_pulse, dg.concentrate_pumps.cp2_temp_pulse, + dg.concentrate_pumps.concentrate_pump_cp1_target_speed, + dg.concentrate_pumps.concentrate_pump_cp2_target_speed, + dg.concentrate_pumps.concentrate_pump_cp1_parked, + dg.concentrate_pumps.concentrate_pump_cp1_park_fault, + dg.concentrate_pumps.concentrate_pump_cp2_parked, + dg.concentrate_pumps.concentrate_pump_cp2_park_fault)) + return info + + +def get_blood_leak_info(): + info = ('Blood_leak_state, {}, Blood_leak_status, {}, ' + .format(hd.blood_leak.get_blood_leak_state(), hd.blood_leak.get_blood_leak_status())) + return info + + +def get_hd_pumps_info(): + info = ('DialIn_tgt_flow, {}, DialIn_meas_flow, {:5.3f}, DialIn_current, {:5.3f}, DialOut_current, {:5.3f}, ' + .format(hd.dialysate_inlet_flow.target_dialysate_inlet_flow_rate, + hd.dialysate_inlet_flow.measured_dialysate_inlet_flow_rate, + hd.dialysate_inlet_flow.measured_dialysate_inlet_pump_mc_current, + hd.dialysate_outlet_flow.measured_dialysate_outlet_pump_mc_current)) + return info + + +def get_dg_fill_info(): + info = ('Avg_acid_cond, {:5.3f}, Avg_bicarb_cond, {:5.3f}, Is_this_first_fill, {}, Diff_cond_pct, {:5.3f}, ' + 'Used_acid, {:5.3f}, Used_bicarb, {:5.3f}, Total_vol, {:5.3f}, ' + .format(dg.dialysate_fill.avg_acid, dg.dialysate_fill.avg_bicarb, dg.dialysate_fill.first_fill, + dg.dialysate_fill.pctDiffConduct, dg.dialysate_fill.used_acid, dg.dialysate_fill.used_acid, + dg.dialysate_fill.total_volume)) + return info + + +def get_hd_air_trap_info(): + info = ('Air_trap_high_level, {}, Air_trap_low_level, {}, Air_trap_valve, {}, Air_bubble_status, {}, ' + .format(hd.air_trap.upper_level, hd.air_trap.lower_level, hd.valves.hd_air_trap_status, + hd.air_bubbles.air_bubbles_status)) + return info + + +def get_dg_idle_bad_fill_info(): + info = ('Bad_fill_state, {}, ' + .format(DGGenIdleModeBadFillSubStates(dg.gen_idle.bad_fill_state).name)) + return info + + +def get_voltages_info(): + info = ('HD_24, {:5.3f}, HD_24_regen, {:5.3f}, '. + format(hd.voltages.monitored_voltages[HDMonitoredVoltages.MONITORED_LINE_24V.value], + hd.voltages.monitored_voltages[HDMonitoredVoltages.MONITORED_LINE_24V_REGEN.value])) + return info + + +def get_dg_voltages_info(): + info = ('DG_24, {:5.3f}, DG_24_non-iso, {:5.3f}, '. + format(dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_MAIN.value], + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_NON_ISOLATED_24_V_MAIN.value])) + return info + + +def collect_treatment_data(): + address = os.path.join(os.getcwd(), "treatment_run.log") + f = open(address, "w") + + #dg.conductivity_sensors.cmd_conductivity_sensor_override(ConductivitySensorsEnum.CPI.value, 1500.00) + #sleep(1) + + """ + dg.conductivity_sensors.cmd_conductivity_sensor_override(ConductivitySensorsEnum.CD1.value, 12100.00) + sleep(1)SW_CONFIG_DISABLE_WATER_QUALITY_CHECK + + dg.dialysate_fill.cmd_used_bicarb_volume_override(3700.0) + sleep(1) + """ + counter = 1 + start = False + sleep_time = 1 + + #dg.heaters.cmd_heaters_broadcast_interval_override(50) + #sleep(1) + #dg.uv_reactors.cmd_uv_reactors_data_broadcast_interval_override(50) + #dg.voltages.cmd_monitored_voltages_broadcast_interval_override(50) + #dg.concentrate_pumps.cmd_concentrate_pump_broadcast_interval_override(50) + #sleep(1) + """ + dg.test_configs.cmd_set_test_config(DGTestConfigOptions.TEST_CONFIG_MIX_WITH_WATER.value) + sleep(0.5) + hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_USE_WET_CARTRIDGE.value) + sleep(0.5) + hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_SKIP_DISINFECT_AND_SERVICE_TX_BLOCKERS.value) + sleep(0.5) + hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_DISABLE_WET_SELFTEST_DISPLACEMENT_CHECK.value) + sleep(0.5) + hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_USE_WORN_CARTRIDGE.value) + sleep(0.5) + dg.test_configs.cmd_set_test_config(DGTestConfigOptions.TEST_CONFIG_DISABLE_INLET_WATER_TEMP_CHECK.value) + sleep(0.5) + hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_SKIP_DISINFECT_AND_SERVICE_TX_BLOCKERS.value) + """ + #dg.hd_proxy.cmd_start_stop_dg() + #sleep(4) + + #dg.hd_proxy.cmd_fill() + hd.cmd_hd_set_operation_mode(4) + sleep(1) + dg.hd_proxy.cmd_start_stop_dg() + sleep(1) + dg.dialysate_fill.cmd_set_mode_fill_cal_check_state(2) + + try: + while True: + hd_run = get_hd_run_info() + hd_rsrvrs = get_hd_reservoirs_info() + dg_rsrvrs = get_dg_reservoirs_info() + dg_run = get_dg_run_info() + drain = get_drain_states_info() + load_cell = get_load_cells_info() + valves = get_dg_valves_states() + ro = get_ro_info() + temp = get_temperature_sensors_info() + heaters = get_heaters_info() + dg_fans = get_dg_fans_info() + conc_pumps = get_concentrate_pumps_info() + blood_leak = get_blood_leak_info() + hd_pumps = get_hd_pumps_info() + fill_info = get_dg_fill_info() + idle_bad_fill = '0,' #get_dg_idle_bad_fill_info() + uv = get_uv_reactors_info() + hd_fans = get_hd_fans_info() + hd_pressures = '0' #get_hd_occlusion_pressures_info() + air_trap = get_hd_air_trap_info() + + var = str(datetime.now()) + ', ' + hd_run + dg_run + hd_rsrvrs + dg_rsrvrs + load_cell + drain + ro + \ + temp + heaters + conc_pumps + dg_fans + valves + blood_leak + hd_pumps + fill_info + uv + hd_fans + \ + hd_pressures + air_trap + '\r' + + print(var) + f.write(var) + sleep(sleep_time) + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg(start=False) + f.close() + + +def run_ro_permeate_sample(): + complete_counter = 1 + address = os.path.join(os.getcwd(), "ro_permeate_sample.log") + f = open(address, "w") + #dg.hd_proxy.cmd_start_stop_dg_ro_permeate_sample() + + #dg.temperatures.cmd_temperatures_value_override(0, 49) + + try: + while True: + ro_perm = get_ro_permeate_sample_mode_info() + drain = get_drain_states_info() + load_cell = get_load_cells_info() + valves = get_dg_valves_states() + ro = get_ro_info() + temp = get_temperature_sensors_info() + heaters = get_heaters_info() + uv = get_uv_reactors_info() + dg_fans = get_dg_fans_info() + hd_fans = get_hd_fans_info() + conc = get_concentrate_pumps_info() + + var = ro_perm + load_cell + drain + ro + temp + heaters + uv + dg_fans + hd_fans + valves + conc + '\r' + + print(var) + f.write(var) + sleep(1) + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg_ro_permeate_sample(start=False) + f.close() + + +def run_heat_disinfect(): + complete_counter = 1 + address = os.path.join(os.getcwd(), "heat_disinfect.log") + f = open(address, "w") + # dg.heaters.cmd_heaters_broadcast_interval_override(50) + # sleep(1) + #dg.hd_proxy.cmd_start_stop_dg_heat_disinfect() + #dg.hd_proxy.cmd_start_stop_dg_heat_disinfect_active_cool() + + try: + while True: + disinfect = get_heat_disinfect_mode_info() + drain = get_drain_states_info() + load_cell = get_load_cells_info() + valves = get_dg_valves_states() + ro = get_ro_info() + temp = get_temperature_sensors_info() + heaters = get_heaters_info() + uv = get_uv_reactors_info() + dg_fans = get_dg_fans_info() + hd_fans = get_hd_fans_info() + conc = get_concentrate_pumps_info() + + var = disinfect + load_cell + drain + ro + temp + heaters + uv + dg_fans + hd_fans + valves + conc + '\r' + + print(var) + f.write(var) + sleep(1) + + # If the mode came back to standby or standby solo + # if dg.dg_operation_mode == 3 or dg.dg_operation_mode == 4: + # If it is the first call, stop heat disinfect + # if complete_counter == 1: + # dg.hd_proxy.cmd_start_stop_dg_heat_disinfect(start=False) + + # Write a few more complete states to make sure the complete state items are recorded + # elif complete_counter == 3: + # pass + # f.close() + # break + + # complete_counter += 1 + + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg_heat_disinfect(start=False) + sleep(0.2) + dg.hd_proxy.cmd_start_stop_dg_heat_disinfect_active_cool(start=False) + f.close() + + +def run_chemical_disinfect(): + complete_counter = 1 + base_dir = os.getcwd() + f = open(os.path.join(base_dir, "chemical_disinfect.log"), "w") + dg.hd_proxy.cmd_start_stop_dg_chemical_disinfect() + #dg.hd_proxy.cmd_start_stop_dg_chemical_disinfect_flush() + + dg.test_configs.cmd_set_test_config(DGTestConfigOptions.TEST_CONFIG_MIX_WITH_WATER.value) + + try: + while True: + + disinfect = get_chemical_disinfect_mode_info() + drain = get_drain_states_info() + load_cell = get_load_cells_info() + conc = get_concentrate_pumps_info() + valves = get_dg_valves_states() + ro = get_ro_info() + temp = get_temperature_sensors_info() + heaters = get_heaters_info() + #fans = get_dg_fans_info() + + #var = disinfect + load_cell + conc + drain + ro + temp + heaters + fans + valves + '\r' + var = disinfect + load_cell + conc + drain + ro + temp + heaters + valves + '\r' + + print(var) + f.write(var) + sleep(1) + + # If the mode came back to standby or standby solo + if dg.dg_operation_mode == 3 or dg.dg_operation_mode == 4: + + # Write a few more complete states to make sure the complete state items are recorded + if complete_counter == 3: + # pass + f.close() + break + + complete_counter += 1 + + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg_chemical_disinfect(start=False) + dg.hd_proxy.cmd_start_stop_dg_chemical_disinfect_flush(start=False) + f.close() + + +def cmd_set_disinfect_ui_screen(): + hd = HD() + sleep(0.5) + hd.ui.cmd_ui_set_standby_submode_to_disinfect() + + while True: + print(hd.ui.disinfects_hd_submode, hd.ui.disinfects_dg_mode) + sleep(1) + + +def run_flush_mode(): + complete_counter = 1 + f = open("/home/fw/projects/leahi_dialin/tests/flush_mode.log", "w") + dg.hd_proxy.cmd_start_stop_dg_flush() + #dg.cmd_dg_software_reset_request() + + try: + while True: + flush = get_flush_mode_info() + load_cell = get_load_cells_info() + drain = get_drain_states_info() + ro = get_ro_info() + conc = get_concentrate_pumps_info() + uv_reactors = get_uv_reactors_info() + valves = get_dg_valves_states() + + var = flush + uv_reactors + load_cell + drain + ro + conc + valves + '\r' + print(var) + f.write(var) + sleep(1) + + # If the mode came back to standby or standby solo + if dg.dg_operation_mode == 3 or dg.dg_operation_mode == 4: + + if complete_counter == 1: + dg.hd_proxy.cmd_start_stop_dg_flush() + # Write a few more complete states to make sure the complete state items are recorded + if complete_counter == 3: + f.close() + #events = dg.events.get_dg_events(2, 60) + #for event in events: + # print(event) + break + + complete_counter += 1 + + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg_flush(start=False) + f.close() + #events = dg.events.get_dg_events(2, 50) + #for event in events: + # print(event) + + +def run_test_configs(): + + counter = 1 + reset_val = 0 + print(hex(dg.test_configs.cmd_get_test_config_status(DGTestConfigOptions.TEST_CONFIG_MIX_WITH_WATER.value))) + + while True: + if counter == 1: + dg.test_configs.cmd_set_test_config(DGTestConfigOptions.TEST_CONFIG_MIX_WITH_WATER.value, reset=reset_val) + counter += 1 + if counter > 10: + #hd.test_configs.cmd_request_test_config_status_from_fw() + dg.test_configs.cmd_request_test_config_status_from_fw() + + while True: + #print(hex(hd.test_configs.hd_test_configs[HDTestConfigOptions.TEST_CONFIG_USE_WORN_CARTRIDGE.name])) + print(hex(dg.test_configs.dg_test_configs[DGTestConfigOptions.TEST_CONFIG_MIX_WITH_WATER.name]), reset_val) + #print((dg.test_configs.dg_test_configs), reset_val) + + if counter > 20: + + if reset_val == 1: + reset_val = 0 + else: + reset_val = 1 + counter = 1 + break + counter += 1 + sleep(0.1) + + sleep(0.1) + +def test_can_messages(): + #f = open('can_messages_test.log') + try: + while True: + status = hd.alarms.cmd_alarm_state_override(7, 1) + if status == 0 or status is False: + print('Broad Failed {} {}'.format(time(), status)) + status = dg.temperatures.cmd_temperatures_value_override(0, 45) + if status == 0 or status is False: + print('Temp Override Failed {} {}'.format(time(), status)) + status = dg.temperatures.cmd_temperatures_value_override(0, 45, reset=1) + if status == 0 or status is False: + print('Temp Override Reset Failed {} {}'.format(time(), status)) + sleep(0.1) + except KeyboardInterrupt: + print("Test stopped") + + +if __name__ == "__main__": + #dg = DG(log_level='DEBUG') + dg = DG() + dg.cmd_log_in_to_dg() + sleep(1) + #hd = HD(log_level='DEBUG') + hd = HD() + hd.cmd_log_in_to_hd() + sleep(1) + + #hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_USE_WET_CARTRIDGE.value) + #sleep(1) + #hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_DISABLE_WET_SELFTEST_DISPLACEMENT_CHECK.value) + #dg.load_cells.cmd_get_load_cells_tare_values() + + #dg.test_configs.cmd_set_recover_from_mode_fault_signal() + + #while True: + # print(dg.load_cells.load_cells_tare_values) + # sleep(0.5) + # if dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_1_PRIMARY.name] != 0.0: + # dg.load_cells.cmd_set_load_cells_tare_values() + # break + + #run_test_configs() + + #run_heat_disinfect() + + #run_flush_mode() + + #run_chemical_disinfect() + + #hd.alarms.cmd_alarm_state_override(319, 1) + #dg.ro_permeate_sample.cmd_send_hd_dg_is_ready_to_dispense() + + #run_dg() + + # cmd_set_disinfect_ui_screen() + + #collect_treatment_data() + + #run_ro_permeate_sample() + + #collect_hd_treatment() + + #run_nelson_support_modes() + + #while True: + # print(get_hd_fans_info(), get_dg_fans_info(), get_temperature_sensors_info()) + # print(get_dg_valves_states()) + # sleep(1) + + #while True: + # print(dg.rtc.get_rtc_epoch(), hd.rtc.get_rtc_epoch()) + # sleep(1) + + #ui = HDSimulator() + #ui.cmd_send_hd_operation_mode(3, 1) + + #hd.ui.cmd_ui_set_dg_service_time() + + #hd.cmd_hd_software_reset_request() + + #hd.ui.cmd_set_ro_only_mode_status(1) + + #while True: + # print(dg.switches.dg_switches_status) + # sleep(1) + #dg.hd_proxy.cmd_start_stop_dg_heat_disinfect() + #while True: + # print(hd.alarms.get_alarm_state(286), hd.alarms.get_alarm_state(289), dg.alarms.get_alarm_state(286), + # dg.alarms.get_alarm_state(289)) + # sleep(0.5) + #hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_SKIP_DISINFECT_AND_SERVICE_TX_BLOCKERS.value) + #dg.cmd_dg_set_operation_mode(3) + #hd.cmd_hd_set_operation_mode(1) + + test_can_messages() + #while True: + # sleep(0.1) Index: tests/depreciated_tests/dg_valves_test.py =================================================================== diff -u --- tests/depreciated_tests/dg_valves_test.py (revision 0) +++ tests/depreciated_tests/dg_valves_test.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,57 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file dg_valves_test.py +# +# @author (last) Dara Navaei +# @date (last) 01-Apr-2021 +# @author (original) Peman Montazemi +# @date (original) 20-May-2020 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.dg.dialysate_generator import DG +from time import sleep + +if __name__ == "__main__": + # Create an instance of the DG Class called hd + dg = DG() + sleep(2) + + # Log in to DG as tester + if dg.cmd_log_in_to_dg() == 0: + print("DG login failed.") + exit(1) + sleep(1) + + # Create log file + with open("DG_valves_test.log", "w") as f: + # Collect DG valves states + while True: + sleep(1) + valvesStates = "DGValves.VBF," + str(dg.valves.valve_state_VRF.get("state", None)) + \ + ",DGValves.VRI," + str(dg.valves.valve_state_VRI.get("state", None)) + \ + ",DGValves.VRD," + str(dg.valves.valve_state_VRD.get("state", None)) + \ + ",DGValves.VRO," + str(dg.valves.valve_state_VRO.get("state", None)) + \ + ",DGValves.VPO," + str(dg.valves.valve_state_VPO.get("state", None)) + \ + ",DGValves.VBF," + str(dg.valves.valve_state_VBF.get("state", None)) + \ + ",DGValves.VRC," + str(dg.valves.valve_state_VRC.get("state", None)) + \ + ",DGValves.VDR," + str(dg.valves.valve_state_VDR.get("state", None)) + \ + ",DGValves.VPI," + str(dg.valves.valve_state_VPI.get("state", None)) + \ + ",DGValves.VSP," + str(dg.valves.valve_state_VSP.get("state", None)) + \ + ",DGValves.VR1," + str(dg.valves.valve_state_VR1.get("state", None)) + \ + ",DGValves.VR2," + str(dg.valves.valve_state_VR2.get("state", None)) + \ + ",DGValves.VPD," + str(dg.valves.valve_state_VPD.get("state", None)) + + # Log data + f.write(valvesStates) + f.write("\n") + + # Print to console + print("DG Valves States: "+valvesStates) Index: tests/depreciated_tests/hd_air_bubbles_data.py =================================================================== diff -u --- tests/depreciated_tests/hd_air_bubbles_data.py (revision 0) +++ tests/depreciated_tests/hd_air_bubbles_data.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,75 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file hd_air_bubbles_data.py +# +# @author (last) Peman Montazemi +# @date (last) 21-May-2021 +# @author (original) Peman Montazemi +# @date (original) 18-May-2021 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from time import sleep + +if __name__ == "__main__": + # Air bubble detectors + ADA = 0 # Air bubble Detector Arterial + ADV = 1 # Air bubble Detector Venous + + # Create an HD object called hd + hd = HD() + sleep(2) + + hd.cmd_log_in_to_hd() + sleep(1) + hd.air_bubbles.cmd_air_bubbles_data_broadcast_interval_override(100) + sleep(1) + + i = 0 + while i < 5: + if hd.air_bubbles.air_bubbles_status[0] == hd.air_bubbles.FLUID_DETECTED_STATUS: + ADAStatus = "ADA fluid detected" + elif hd.air_bubbles.air_bubbles_status[0] == hd.air_bubbles.BUBBLE_DETECTED_STATUS: + ADAStatus = "ADA bubble detected" + if hd.air_bubbles.air_bubbles_status[1] == hd.air_bubbles.FLUID_DETECTED_STATUS: + ADVStatus = "ADV fluid detected" + elif hd.air_bubbles.air_bubbles_status[1] == hd.air_bubbles.BUBBLE_DETECTED_STATUS: + ADVStatus = "ADV bubble detected" + print("ADA Status = " + ADAStatus, " ADA State = " + str(hd.air_bubbles.air_bubbles_state[0]) + + " ADV Status = " + ADVStatus, " ADV State = " + str(hd.air_bubbles.air_bubbles_state[1])) + sleep(1) + i += 1 + + # Self-test state + #hd.air_bubbles.cmd_air_bubble_self_test_request(ADA) + #sleep(0.1) + + hd.air_bubbles.cmd_air_bubble_status_override( 1, 1) + sleep(0.1) + hd.air_bubbles.cmd_air_bubble_self_test_request(ADV) + counter = 0 + + while True: + if ( counter == 50 ): + hd.air_bubbles.cmd_air_bubble_status_override( 1, 1, 1) + + if hd.air_bubbles.air_bubbles_status[0] == hd.air_bubbles.FLUID_DETECTED_STATUS: + ADAStatus = "ADA fluid detected" + elif hd.air_bubbles.air_bubbles_status[0] == hd.air_bubbles.BUBBLE_DETECTED_STATUS: + ADAStatus = "ADA bubble detected" + if hd.air_bubbles.air_bubbles_status[1] == hd.air_bubbles.FLUID_DETECTED_STATUS: + ADVStatus = "ADV fluid detected" + elif hd.air_bubbles.air_bubbles_status[1] == hd.air_bubbles.BUBBLE_DETECTED_STATUS: + ADVStatus = "ADV bubble detected" + print("ADA Status = " + ADAStatus, " ADA State = " + str(hd.air_bubbles.air_bubbles_state[0]) + + " ADV Status = " + ADVStatus, " ADV State = " + str(hd.air_bubbles.air_bubbles_state[1])) + sleep(0.1) + counter += 1 Index: tests/depreciated_tests/hd_blood_leak_data.py =================================================================== diff -u --- tests/depreciated_tests/hd_blood_leak_data.py (revision 0) +++ tests/depreciated_tests/hd_blood_leak_data.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,137 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file hd_blood_leak_data.py +# +# @author (last) Dara Navaei +# @date (last) 17-Jul-2023 +# @author (original) Peman Montazemi +# @date (original) 15-Apr-2021 +# +############################################################################ + +import sys +import os +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from dialin.common.hd_defs import HDOpModes +from dialin.hd.blood_leak import EmbModeCommands +from time import sleep +from datetime import datetime + + +from dialin.hd.hemodialysis_device import HD +from dialin.common.hd_defs import HDOpModes +from dialin.hd.blood_leak import EmbModeCommands +from time import sleep +from datetime import datetime + + +def get_blood_leak_info(): + info = ('Blood_leak_state, {}, Blood_leak_status, {}, Blood_leak_serial_comm, {}, ' + .format(hd.blood_leak.get_blood_leak_state(), hd.blood_leak.get_blood_leak_status(), + hd.blood_leak.blood_leak_serial_comm_state)) + return info + +#def get_blood_leak_info(): +# info = ('Blood_leak_state, {}, Blood_leak_status, {}, Blood_leak_detect_level, {},' +# ' Blood_leak_led_intensity, {}, ' +# .format(hd.blood_leak.get_blood_leak_state(), hd.blood_leak.get_blood_leak_status(), +# hd.blood_leak.get_blood_leak_detect_level(), +# hd.blood_leak.get_blood_leak_led_intensity())) +# return info + + +if __name__ == "__main__": + # Create an HD object called hd + hd = HD(log_level='DEBUG') + hd.cmd_log_in_to_hd() + sleep(1) + + address = os.path.join(os.getcwd(), "blood_leak.log") + f = open(address, "w") + + #hd.blood_leak.cmd_blood_leak_data_broadcast_interval_override(50) + + hd.blood_leak.cmd_blood_leak_zero_request() + command_sent = True + counter = 0 + + #hd.blood_leak.cmd_blood_leak_set_to_embedded_mode() + + #print(hd.blood_leak.get_blood_leak_emb_mode_command_response()) + + #hd.blood_leak.cmd_blood_leak_set_embedded_mode_command(EmbModeCommands.Z.value, msg_payload=0) + + #print(hd.blood_leak.get_blood_leak_emb_mode_command_response()) + + #hd.blood_leak.cmd_blood_leak_zero_request() + + while True: + #print(hd.blood_leak.blood_leak_emb_mode_cmds) + + if command_sent == False and hd.blood_leak.blood_leak_state != 3: + hd.blood_leak.cmd_blood_leak_zero_request() + command_sent = True + + if hd.blood_leak.blood_leak_state != 3: + counter += 1 + + if counter > 4: + command_sent = False + counter = 0 + + var = str(datetime.now()) + ', ' + str(counter) + ', ' + str(command_sent) + ', ' + get_blood_leak_info() + '\r' + + print(var) + f.write(var) + + sleep(1) + + """ + while True: + hd.blood_leak.cmd_blood_leak_set_embedded_mode_command(EmbModeCommands.I.value, msg_payload=125) + + print(hd.blood_leak.get_blood_leak_emb_mode_command_response()) + + hd.blood_leak.cmd_blood_leak_set_embedded_mode_command(EmbModeCommands.V.value, msg_payload=125) + + print(hd.blood_leak.get_blood_leak_emb_mode_command_response()) + + hd.blood_leak.cmd_blood_leak_set_embedded_mode_command(EmbModeCommands.SP.value, msg_payload=30) + + print(hd.blood_leak.get_blood_leak_emb_mode_command_response()) + + hd.blood_leak.cmd_blood_leak_set_embedded_mode_command(EmbModeCommands.D.value, msg_payload=30) + + print(hd.blood_leak.get_blood_leak_emb_mode_command_response()) + + hd.blood_leak.cmd_blood_leak_set_embedded_mode_command(EmbModeCommands.Z.value, msg_payload=30) + + print(hd.blood_leak.get_blood_leak_emb_mode_command_response()) + + hd.blood_leak.cmd_blood_leak_set_embedded_mode_command(EmbModeCommands.Q.value, msg_payload=30) + + print(hd.blood_leak.get_blood_leak_emb_mode_command_response()) + """ + """ + f = open("/home/fw/projects/leahi_dialin/tests/blood_leak.log", "w") + + try: + while True: + hd_blood_leak = get_blood_leak_info() + + var = str(datetime.now()) + ', ' + hd_blood_leak + '\r' + + print(var) + f.write(var) + sleep(1) + except KeyboardInterrupt: + f.close() + """ + + Index: tests/depreciated_tests/hd_fluid_leak_state.py =================================================================== diff -u --- tests/depreciated_tests/hd_fluid_leak_state.py (revision 0) +++ tests/depreciated_tests/hd_fluid_leak_state.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,39 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file hd_fluid_leak_state.py +# +# @author (last) Dara Navaei +# @date (last) 13-May-2021 +# @author (original) Peman Montazemi +# @date (original) 10-Mar-2021 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from time import sleep + +if __name__ == "__main__": + # Create an HD object called hd + hd = HD() + sleep(2) + + #hd.cmd_log_in_to_hd() + sleep(1) + #hd.fluid_leak.cmd_fluid_leak_state_broadcast_interval_override(100) + + state = "Dry" + + while True: + if hd.fluid_leak.fluid_leak_state == hd.fluid_leak.NO_FLUID_LEAK_DETECTED_STATE: + state = "Dry" + else: # FLUID_LEAK_DETECTED + state = "Wet" + print("State = " + state) + sleep(0.1) Index: tests/depreciated_tests/hd_nvm_scripts.py =================================================================== diff -u --- tests/depreciated_tests/hd_nvm_scripts.py (revision 0) +++ tests/depreciated_tests/hd_nvm_scripts.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,139 @@ +########################################################################### +# +# Copyright (c) 2022-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file hd_nvm_scripts.py +# +# @author (last) Dara Navaei +# @date (last) 18-Mar-2024 +# @author (original) Dara Navaei +# @date (original) 10-Feb-2022 +# +############################################################################ +from dialin import HD +from time import sleep + + +def run_sw_configs_commands(): + # NOTE: For further details, please refer to 'Instructions to Change the Software Configurations Dynamically' in + # the development section of the DevOps OneNote file + + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_hd_sw_config_record() to get the software configurations record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called HD_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + #hd.sw_configs.cmd_get_hd_sw_config_record() + + # Use cmd_update_hd_sw_config_record() set the changes back to firmware + # This function requires an address for the excel report. Use the absolute address of your excel report like the + # example below + hd.sw_configs.cmd_update_hd_sw_config_record('/home/fw/projects/HD_NV_Records/2023-06-12-HD-SW-CONFIGS-Record.xlsx') + + # Use this function to reset the configuration records to all be 0 + #hd.sw_configs.cmd_reset_hd_sw_config_record() + + +def run_calibration_commands(): + # NOTE: For further details, please refer to 'Instructions to Calibrate a Device Using the Calibration Report' + # in the development section of the DevOps OneNote file + + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_calibration_record_report() to get the calibration record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called HD_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + hd.calibration_record.cmd_get_hd_calibration_record_report() + + # Use cmd_set_hd_calibration_excel_to_fw() set the changes back to firmware + # This function requires an address for the excel report. Use the absolute address of your excel report like the + # example below + #hd.calibration_record.cmd_set_hd_calibration_excel_to_fw('/home/fw/projects/HD_NV_Records/2024-02-27-HD-Record.xlsx') + + # For resetting the calibration record to benign values, use the function below + #hd.calibration_record.cmd_reset_hd_calibration_record() + + +def run_system_commands(): + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_system_record_report() to get the system record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called DG_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + #hd.system_record.cmd_get_hd_system_record_report() + + hd.system_record.cmd_set_hd_system_record_excel_to_fw('/home/fw/projects/HD_NV_Records/2024-02-27-HD-Record.xlsx') + + # For resetting the system record to benign values, use the function below + #hd.system_record.cmd_reset_hd_system_record() + + +def run_usage_info_commands(): + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_system_record_report() to get the system record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called DG_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + #hd.usage_record.cmd_get_hd_usage_info_record() + + hd.usage_record.cmd_set_dg_usage_info_excel_to_fw('/home/fw/projects/HD_NV_Records/2022-12-07-HD-Record.xlsx') + + #hd.usage_record.cmd_reset_hd_usage_info_record() + + +def run_service_commands(): + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + # Use cmd_get_dg_system_record_report() to get the system record in an excel + # This function gets an address to locate the report there (i.e. /home/fw/projects/) + # It creates a folder called DG_NV_Records in the destination that is called + # If no address is provided, the default location is one folder above the leahi_dialin folder wherever it is installed + # in your computer. + #hd.service_record.cmd_get_hd_service_record() + + hd.service_record.cmd_set_hd_service_record_excel_to_fw('/home/fw/projects/HD_NV_Records/2024-02-27-HD-Record.xlsx') + + #hd.service_record.cmd_reset_hd_service_record() + +def run_institutional_commands(): + # Comment and un-comment any of the functions that you would like to use or you can use your own scripts. + + #hd.institutional_record.cmd_get_hd_institutional_record() + + hd.institutional_record.cmd_set_hd_institutional_record_excel_to_fw('/home/fw/projects/HD_NV_Records/2024-03-18-HD-Record.xlsx') + + #hd.institutional_record.cmd_reset_hd_institutional_record() + + +if __name__ == "__main__": + + hd = HD(log_level="DEBUG") + + if hd.cmd_log_in_to_hd(): + + # Comment this function if not needed + #run_sw_configs_commands() + + # Comment this function if not needed + #run_calibration_commands() + + #run_system_commands() + + #run_usage_info_commands() + + #run_service_commands() + + run_institutional_commands() + + Index: tests/depreciated_tests/hd_test_pumps_open_loop.py =================================================================== diff -u --- tests/depreciated_tests/hd_test_pumps_open_loop.py (revision 0) +++ tests/depreciated_tests/hd_test_pumps_open_loop.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,95 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file hd_test_pumps_open_loop.py +# +# @author (last) Sean Nash +# @date (last) 05-Aug-2020 +# @author (original) Sean Nash +# @date (original) 05-Aug-2020 +# +############################################################################ +import sys +sys.path.append("..") +from dialin.hd.constants import RESET, NO_RESET +from dialin.hd.constants import PUMP_CONTROL_MODE_CLOSED_LOOP, PUMP_CONTROL_MODE_OPEN_LOOP +from dialin.hd.hemodialysis_device import HD +from time import sleep +import unittest + +class Test(unittest.TestCase): + def hd_test_pumps_open_loop(self): + """ + Sets the target flow rate for all HD pumps using + \returns None + """ + + # Create an instance of the HD Class called hd + hd = HD() + sleep(1) + + # Set HD open loop pumps flow rates in mL/min + HD_BLOOD_PUMP_FLOW_RATE = 200 + HD_DIALYSATE_PUMP_IN_FLOW_RATE = 200 + HD_DIALYSATE_PUMP_OUT_FLOW_RATE = 200 + + # Log in to HD as tester + if hd.cmd_log_in_to_hd() == 0: + print("HD login failed.") + exit(1) + sleep(1) + + # Reset all flow rate broadcast intervals + hd.bloodflow.cmd_blood_flow_broadcast_interval_override(RESET, 0) + sleep(1) + hd.dialysate_inlet_flow.cmd_dialysate_inlet_flow_broadcast_interval_override(RESET, 0) + sleep(1) + hd.dialysate_outlet_flow.cmd_dialysate_outlet_flow_broadcast_interval_override(RESET, 0) + sleep(1) + + # Reset all flow rate set points + hd.bloodflow.cmd_blood_flow_set_point_override(RESET, 0) + sleep(1) + hd.dialysate_inlet_flow.cmd_dialysate_inlet_flow_set_point_override(RESET, 0) + sleep(1) + hd.dialysate_outlet_flow.cmd_dialysate_outlet_flow_set_point_override(RESET, 0) + sleep(1) + + # Reset all flow rate measures + hd.bloodflow.cmd_blood_flow_measured_override(RESET, 0) + sleep(1) + hd.dialysate_inlet_flow.cmd_dialysate_inlet_flow_measured_override(RESET, 0) + sleep(1) + hd.dialysate_outlet_flow.cmd_dialysate_outlet_flow_measured_override(RESET, 0) + sleep(1) + + # Set HD pumps flow rates (open loop) + hd.bloodflow.cmd_blood_flow_set_point_override(HD_BLOOD_PUMP_FLOW_RATE, PUMP_CONTROL_MODE_OPEN_LOOP) + hd.dialysate_inlet_flow.cmd_dialysate_inlet_flow_set_point_override(HD_DIALYSATE_PUMP_IN_FLOW_RATE, PUMP_CONTROL_MODE_OPEN_LOOP) + hd.dialysate_outlet_flow.cmd_dialysate_outlet_flow_set_point_override(HD_DIALYSATE_PUMP_OUT_FLOW_RATE, PUMP_CONTROL_MODE_OPEN_LOOP) + sleep(5) + + print("Blood Flow Target = {}".format(hd.bloodflow.target_blood_flow_rate)) + print("Dialysate Flow In Target = {}".format(hd.dialysate_inlet_flow.target_dialysate_inlet_flow_rate)) + print("Dialysate Flow Out Target = {}".format(hd.dialysate_outlet_flow.target_dialysate_outlet_flow_rate)) + sleep(1) + + i = 0 + while True: + sleep(0.5) + print("Measured Blood Flow = {} mL/min".format(hd.bloodflow.measured_blood_flow_rate)) + print("Measured Dialysate Flow In = {} mL/min".format(hd.dialysate_inlet_flow.measured_dialysate_inlet_flow_rate)) + print("Measured Dialysate Flow Out = {} mL/min".format(hd.dialysate_outlet_flow.measured_dialysate_outlet_flow_rate)) + if i > 0 and i % 60 == 0: + resp = input("Press 'Enter' to continue or 'q' to quit: ") + if resp.lower() == "q": + break + i += 1 + + +if __name__ == '__main__': + unittest.main(verbosity=2) Index: tests/depreciated_tests/hd_valves_test.py =================================================================== diff -u --- tests/depreciated_tests/hd_valves_test.py (revision 0) +++ tests/depreciated_tests/hd_valves_test.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,160 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file hd_valves_test.py +# +# @author (last) Dara Navaei +# @date (last) 22-Feb-2022 +# @author (original) Dara Navaei +# @date (original) 19-Aug-2020 +# +############################################################################ +import sys +sys.path.append("..") +from dialin.hd.constants import RESET, NO_RESET +from dialin.hd.hemodialysis_device import HD +from dialin.hd.valves import ValvesEnum +from dialin.hd.valves import AirTrapState +from dialin.hd.valves import ValvesPositions +from dialin.common.alarm_defs import AlarmList +from dialin.common.hd_defs import HDOpModes +from time import sleep + + +def cycle_valves(): + # valves.cmd_open_hd_air_trap_valve(AirTrapState.STATE_OPEN) + # sleep(2) + + overall_counter = 0 + sleep_time = 0.05 + overall_time_seconds = 4 + loops = 5 + counter = 0 + + valve = ValvesEnum.VDI + + valves.cmd_hd_valves_broadcast_interval_override(100) + sleep(3) + + # valves.cmd_set_hd_valve_position(0, 2) + # sleep(3) + + valves.cmd_home_hd_valve(valve.value) + sleep(3) + + # valves.cmd_set_hd_valve_current_override(valve.value, 0.85, reset=1) + # sleep(3) + + # valves.cmd_set_hd_valve_position_count_override(valve.value, 5000, reset=1) + # sleep(2) + + f = open("Valves_Test_200.log", "w") + + while counter < loops: + + print('Loop: {}'.format(counter)) + overall_counter = 0 + valves.cmd_set_hd_valve_position(valve.value, ValvesPositions.VALVE_POSITION_B_OPEN.value) + + while overall_counter < (overall_time_seconds / sleep_time): + sleep(sleep_time) + + status = ('ID, {}, Pos, {}, PosCnt, {}, Cmd, {}, State, {}, Current, {}, PosA, {}, PosB, {}, PosC, {} \r' + .format(valves.valves_status[valve.name]['Valve'], + valves.valves_status[valve.name]['PosID'], + valves.valves_status[valve.name]['PosCnt'], + valves.valves_status[valve.name]['Cmd'], + valves.valves_status[valve.name]['State'], + valves.valves_status[valve.name]['Current'], + valves.valves_status[valve.name]['PosA'], + valves.valves_status[valve.name]['PosB'], + valves.valves_status[valve.name]['PosC'])) + + print(status) + f.write(status) + overall_counter = overall_counter + 1 + + overall_counter = 0 + valves.cmd_set_hd_valve_position(valve.value, ValvesPositions.VALVE_POSITION_C_CLOSE.value) + + while overall_counter < (overall_time_seconds / sleep_time): + sleep(sleep_time) + print('done') + + +def change_valves_position(): + + valve = ValvesEnum.VDI + valves.cmd_home_hd_valve(valve.value) + sleep(0.5) + + valves.cmd_set_hd_valve_position(valve.value, ValvesPositions.VALVE_POSITION_B_OPEN.value) + sleep(0.05) + valves.cmd_set_hd_valve_position(valve.value, ValvesPositions.VALVE_POSITION_A_INSERT_EJECT.value) + + while True: + + try: + status = ('ID, {}, Pos, {}, PosCnt, {}, Cmd, {}, State, {}, Current, {}, PosA, {}, PosB, {}, PosC, {} \r' + .format(valves.valves_status[valve.name]['Valve'], + valves.valves_status[valve.name]['PosID'], + valves.valves_status[valve.name]['PosCnt'], + valves.valves_status[valve.name]['Cmd'], + valves.valves_status[valve.name]['State'], + valves.valves_status[valve.name]['Current'], + valves.valves_status[valve.name]['PosA'], + valves.valves_status[valve.name]['PosB'], + valves.valves_status[valve.name]['PosC'])) + print(status) + except: + pass + + sleep(1) + + +def fail_homing(): + + i = 0 + while i < 5: + status = False + hd.cmd_hd_software_reset_request() + sleep(1) + + hd.alarms.clear_dialin_alarms() + + while True: + if hd.hd_operation_mode == HDOpModes.MODE_STAN.value and status is not True: + hd.cmd_log_in_to_hd() + sleep(1) + + hd.valves.cmd_home_hd_valve(0) + #sleep(2) + hd.valves.cmd_set_hd_valve_position_count_override(0, 8000) + status = True + + print(i, hd.alarms.get_alarm_state(AlarmList.ALARM_ID_HD_VALVE_HOMING_FAILED.value), hd.alarms.alarm_top) #, hd.valves.valves_status[ValvesEnum.VDI.name]) + sleep(0.1) + + if hd.alarms.get_alarm_state(AlarmList.ALARM_ID_HD_VALVE_HOMING_FAILED.value): + i += 1 + sleep(1) + break + + + +if __name__ == "__main__": + # Create an instance of the DG Class + hd = HD(log_level='DEBUG') + + if hd.cmd_log_in_to_hd() == 0: + exit(1) + + valves = hd.valves + + #cycle_valves() + #change_valves_position() + fail_homing() Index: tests/depreciated_tests/set_accels_cal.py =================================================================== diff -u --- tests/depreciated_tests/set_accels_cal.py (revision 0) +++ tests/depreciated_tests/set_accels_cal.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,60 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file set_accels_cal.py +# +# @author (last) Dara Navaei +# @date (last) 01-Apr-2021 +# @author (original) Sean Nash +# @date (original) 05-Aug-2020 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from dialin.dg.dialysate_generator import DG +from time import sleep + +if __name__ == "__main__": + # create an HD object called hd + hd = HD() + # create an DG object called hd + #hd = DG() + sleep(2) + + # log in to HD and DG as tester + if hd.cmd_log_in_to_hd() == 0: + exit(1) + #if hd.cmd_log_in_to_dg() == 0: + # exit(1) + sleep(1) + + #reset calibrations + hd.accel.cmd_set_accel_calibration(0, 0, 0) + #hd.accel.cmd_set_accel_calibration(0, 0, 0) + + #wait for new readings after calibration_record reset + sleep(5) + + #calculate offsets (assuming HD and DG systems are level) + hd_offsets = hd.accel.get_accel_vector() + #dg_offsets = hd.accel.get_accel_vector() + hd_offsets.x *= -1.0 + hd_offsets.y *= -1.0 + hd_offsets.z -= 1.0 + hd_offsets.z *= -1.0 + #dg_offsets.x *= -1.0 + #dg_offsets.y *= -1.0 + #dg_offsets.z -= 1.0 + #dg_offsets.z *= -1.0 + + #set new offsets + hd.accel.cmd_set_accel_calibration(hd_offsets.x, hd_offsets.y, hd_offsets.z) + #hd.accel.cmd_set_accel_calibration(dg_offsets.x, dg_offsets.y, dg_offsets.z) + + exit(0) Index: tests/depreciated_tests/set_flow_sensors_cal.py =================================================================== diff -u --- tests/depreciated_tests/set_flow_sensors_cal.py (revision 0) +++ tests/depreciated_tests/set_flow_sensors_cal.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,34 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file set_flow_sensors_cal.py +# +# @author (last) Dara Navaei +# @date (last) 19-Nov-2020 +# @author (original) Sean Nash +# @date (original) 05-Aug-2020 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from time import sleep + +if __name__ == "__main__": + # create an HD object called hd + hd = HD() + sleep(2) + + # log in to HD as tester + if hd.cmd_log_in_to_hd() == 0: + exit(1) + sleep(1) + + #set calibrations ******** MUST PROVIDE GAIN/OFFSET FOR EACH SENSOR HERE ********* + hd.bloodflow.cmd_set_blood_flow_calibration(0.0, 0.0) + hd.dialysate_inlet_flow.cmd_set_dialysate_flow_calibration(0.0, 0.0) Index: tests/depreciated_tests/test_alarms.py =================================================================== diff -u --- tests/depreciated_tests/test_alarms.py (revision 0) +++ tests/depreciated_tests/test_alarms.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,138 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_alarms.py +# +# @author (last) Peter Lucia +# @date (last) 02-Oct-2020 +# @author (original) Peter Lucia +# @date (original) 05-Jun-2020 +# +############################################################################ +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from dialin.utils.base import AbstractObserver +from dialin.ui.hd_simulator import HDSimulator +from dialin.common.alarm_defs import AlarmList +from time import time, sleep + + +class Observer(AbstractObserver): + + def __init__(self): + pass + + def update(self, result): + pass + + # Store the state + + def check_something(self): + pass + + +def test_disable_all_hd_alarms(): + """ + Disables all hd alarms + \returns None + """ + hd = HD() + + if hd.cmd_log_in_to_hd(): + hd.ui.cmd_ui_request_hd_version() + sleep(0.5) + print(f"Current HD version: {hd.ui.hd_version}") + for desc, val in hd.alarms.ids.items(): + hd.alarms.cmd_alarm_state_override(0, val) + sleep(0.5) + + +def test_hd_alarms(): + """ + Simulates all HD alarms + \returns None + """ + hd = HD() + + alarm_faults = [ + 'ALARM_ID_NO_ALARM', + 'ALARM_ID_SOFTWARE_FAULT', + 'ALARM_ID_STUCK_BUTTON_TEST_FAILED', + 'ALARM_ID_FPGA_POST_TEST_FAILED', + 'ALARM_ID_WATCHDOG_POST_TEST_FAILED', + 'ALARM_ID_UI_COMM_POST_FAILED', + 'ALARM_ID_WATCHDOG_EXPIRED', + 'ALARM_ID_RTC_COMM_ERROR', + 'ALARM_ID_DG_COMM_TIMEOUT', + 'ALARM_ID_UI_COMM_TIMEOUT', + 'ALARM_ID_COMM_TOO_MANY_BAD_CRCS', + 'ALARM_ID_CAN_MESSAGE_NOT_ACKED', + 'ALARM_ID_UF_RATE_TOO_HIGH_ERROR', + 'ALARM_ID_UF_VOLUME_ACCURACY_ERROR', + 'ALARM_ID_RTC_OR_TIMER_ACCURACY_FAILURE', + 'ALARM_ID_NVDATA_CAL_RECORD_CRC_ERROR', + 'ALARM_ID_NVDATA_DISINFECTION_DATE_CRC_ERROR', + 'ALARM_ID_NVDATA_MFG_RECORD_CRC_ERROR', + 'ALARM_ID_RO_PUMP_OUT_PRESSURE_OUT_OF_RANGE', + 'ALARM_ID_TEMPERATURE_SENSORS_OUT_OF_RANGE', + 'ALARM_ID_TEMPERATURE_SENSORS_INCONSISTENT', + 'ALARM_ID_VALVE_CONTROL_FAILURE' + ] + + alarms_observer = Observer() + + hd.alarms.attach(alarms_observer) + + if hd.cmd_log_in_to_hd(): + hd.ui.cmd_ui_request_hd_version() + sleep(0.5) + print(f"Current HD version: {hd.ui.hd_version}") + for desc, val in hd.alarms.ids.items(): + if desc in alarm_faults: + print("Skipping {0}".format(desc)) + continue + print("Testing {0} = {1}".format(val.name, val.value)) + success = hd.alarms.cmd_alarm_state_override(1, val.value) + sleep(3) + if not success: + raise ValueError("Failed to activate alarm {0} = {1}".format(desc, val)) + success = hd.alarms.cmd_alarm_state_override(0, val.value) + if not success: + raise ValueError("Failed to deactivate alarm {0} = {1}".format(desc, val)) + sleep(2) + + +def test_clear_alarms(): + hd_sim = HDSimulator() + hd_sim.alarms_simulator.cmd_send_clear_alarms() + sleep(3) + hd_sim.alarms_simulator.cmd_activate_alarm(alarm=AlarmList.ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK) + sleep(3) + hd_sim.alarms_simulator.cmd_send_clear_alarms() + sleep(1) + + +def test_repeated_alarm(): + hd_sim = HDSimulator(log_level="DEBUG") + hd_sim.alarms_simulator.cmd_send_clear_alarms() + sleep(2) + flags = hd_sim.alarms_simulator.cmd_make_alarm_flags(alarms_silenced=0, + user_acknowledge=0) + hd_sim.alarms_simulator.set_flags(flags) + hd_sim.alarms_simulator.cmd_repeat_broadcast_alarm(alarm=AlarmList.ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, + state=1, + timeout=20) +def test_activate_alarm(): + hd_sim = HDSimulator() + hd_sim.alarms_simulator.cmd_send_clear_alarms() + hd_sim.alarms_simulator.cmd_activate_alarm(alarm=AlarmList.ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK) + + +if __name__ == '__main__': + test_activate_alarm() + # test_repeated_alarm() Index: tests/depreciated_tests/test_buttons.py =================================================================== diff -u --- tests/depreciated_tests/test_buttons.py (revision 0) +++ tests/depreciated_tests/test_buttons.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,31 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_buttons.py +# +# @author (last) Peter Lucia +# @date (last) 06-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 06-Aug-2020 +# +############################################################################ +import sys +sys.path.append("..") + +from dialin.hd.hemodialysis_device import HD +from dialin.hd.constants import RESET, NO_RESET + +def test_buttons(): + hd = HD(log_level="DEBUG") + hd.buttons.PRESSED + hd.buttons.cmd_stop_button_override(hd.buttons.PRESSED, RESET) + hd.buttons.cmd_stop_button_override(hd.buttons.PRESSED, NO_RESET) + + +if __name__ == '__main__': + test_buttons() + Index: tests/depreciated_tests/test_can_xmit.py =================================================================== diff -u --- tests/depreciated_tests/test_can_xmit.py (revision 0) +++ tests/depreciated_tests/test_can_xmit.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,39 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_can_xmit.py +# +# @author (last) Peter Lucia +# @date (last) 06-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 14-Jul-2020 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from time import sleep + +if __name__ == "__main__": + # create an HD object called hd + hd = HD() + + # log into HD + if not hd.cmd_log_in_to_hd(): + sys.exit() + + # reset sequence counter + x = 0 + # send large CAN test messages (6 frames each) every 100ms + while True: + sleep(0.1) + hd.pressure_occlusion.test_can_message(x) + x += 6 + + + Index: tests/depreciated_tests/test_conductivity.py =================================================================== diff -u --- tests/depreciated_tests/test_conductivity.py (revision 0) +++ tests/depreciated_tests/test_conductivity.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,154 @@ +########################################################################### +# +# Copyright (c) 2022-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_conductivity.py +# +# @author (last) Hung Nguyen +# @date (last) 30-Mar-2022 +# @author (original) Hung Nguyen +# @date (original) 08-Mar-2022 +# +############################################################################ +import sys +import time +from datetime import datetime +from dialin.dg.dialysate_generator import DG +import os +import csv + + +directory = 'DG Cond' +file_name = 'Test 1' +notes = 'None' +sampling_rate = 1 + + +cwd = os.getcwd() +if not os.path.isdir(cwd + f'/{directory}'): + os.mkdir(cwd + f'/{directory}') + + +current_time = datetime.now().strftime('%b-%d-%Y %H-%M-%S') +result_file_name = f'{directory}/{file_name} - {current_time}.csv' +dg = DG() +if dg.cmd_log_in_to_dg() == 0: + sys.exit('Unable to login into DG') + + +dg.cmd_ui_request_dg_version() +time.sleep(1) +dg_fw_version = dg.get_version() +dg_fpga_version = dg.get_fpga_version() + + +def get_dg_mixing_data(): + # Conductivity Cells + cond_data = dg.conductivity_sensors.get_conductivity_sensors() + cpi = cond_data[0] + cpo = cond_data[1] + cd1 = cond_data[2] + cd2 = cond_data[3] + cpi_raw = cond_data[4] + cpo_raw = cond_data[5] + cd1_raw = cond_data[6] + cd2_raw = cond_data[7] + + # Temperature + # dg.temperatures.cmd_temperatures_value_override(0, 38.0) + tpi = dg.temperatures.get_temperatures_values(0) + tpo = dg.temperatures.get_temperatures_values(2) + td1 = dg.temperatures.get_temperatures_values(3) + td2 = dg.temperatures.get_temperatures_values(4) + + # DG Op modes + dg_mode = dg.get_operation_mode() + dg_sub_mode = dg.get_operation_sub_mode() + dg_sub_sub_mode = dg.gen_idle.get_sub_state() # log the gen idle bad fill sub-states + + # flows + fmp = dg.ro_pump.get_measured_flow_rate() + raw_fmp = dg.ro_pump.get_ro_pump_measured_raw_flow_rate_mlp() + ro_pwm = dg.ro_pump.get_pwm_duty_cycle_pct() + cp1_setpoint = dg.concentrate_pumps.concentrate_pump_cp1_current_set_speed + cp1_measured = dg.concentrate_pumps.concentrate_pump_cp1_measured_speed + cp2_setpoint = dg.concentrate_pumps.concentrate_pump_cp2_current_set_speed + cp2_measured = dg.concentrate_pumps.concentrate_pump_cp2_measured_speed + + # pressure + ppi = dg.pressures.ro_pump_inlet_pressure + ppo = dg.pressures.ro_pump_outlet_pressure + prd = dg.pressures.drain_pump_inlet_pressure + pdr = dg.pressures.drain_pump_outlet_pressure + + # Load Cells + lc_a1 = dg.load_cells.load_cell_A1 + lc_a2 = dg.load_cells.load_cell_A2 + lc_b1 = dg.load_cells.load_cell_B1 + lc_b2 = dg.load_cells.load_cell_B2 + + # f'DG SubMode, {dg_sub_mode}, ' \ + data_string = f'DG Mode, {dg_mode}, ' \ + f'SubMode, {dg_sub_mode}, ' \ + f'SubSubMode, {dg_sub_sub_mode}, ' \ + f'CPi, {cpi:.4f}, ' \ + f'CPo, {cpo:.4f}, ' \ + f'CD1, {cd1:.4f}, ' \ + f'CD2, {cd2:.4f}, ' \ + f'CPi raw, {cpi_raw:.4f}, ' \ + f'CPo raw, {cpo_raw:.4f}, ' \ + f'CD1 raw, {cd1_raw:.4f}, ' \ + f'CD2 raw, {cd2_raw:.4f}, ' \ + f'TPi, {tpi:.4f}, ' \ + f'TPo, {tpo:.4f}, ' \ + f'TD1, {td1:.4f}, ' \ + f'TD2, {td2:.4f}, ' \ + f'RO_PWM, {ro_pwm:.4f}, ' \ + f'FMP, {fmp:.4f}, ' \ + f'Raw FMP, {raw_fmp:.4f}, ' \ + f'CP1_setpoint, {cp1_setpoint}, ' \ + f'CP1_measured_spd, {cp1_measured:.4f}, ' \ + f'CP2_setpoint, {cp2_setpoint}, ' \ + f'CP2_measured_spd, {cp2_measured}, ' \ + f'PPi, {ppi:.4f}, ' \ + f'PPo, {ppo:.4f}, ' \ + f'PRd, {prd:.4f}, ' \ + f'PDr, {pdr:.4f}, ' \ + f'LCA1, {lc_a1:.4f}, ' \ + f'LCA2, {lc_a2:.4f}, ' \ + f'LCB1, {lc_b1:.4f}, ' \ + f'LCB2, {lc_b2:.4f}' + return data_string + + +try: + with open(result_file_name, 'w') as f: + writer = csv.writer(f, delimiter=',') + writer.writerows([[f'Date: {datetime.now()}'], + [f'Sampling Rate: {sampling_rate} (s)'], + [f'Notes: {notes}'], + [f'DG FW version: {dg_fw_version}'], + [f'DG FPGA version: {dg_fpga_version}'] + ]) + writer.writerow(['Data:']) # use this for a tag to find when data collection start using Pandas + + start_time = time.perf_counter() + timer = 0 + + while True: + time.sleep(sampling_rate) + end_time = time.perf_counter() + timer = end_time - start_time + data = f'time, {timer:.4f}, ' + get_dg_mixing_data() + writer.writerow(data.split(',')) + print(data) + + +except KeyboardInterrupt: + print('end script') + +finally: + dg.hd_proxy.cmd_start_stop_dg(0) Index: tests/depreciated_tests/test_deprime.py =================================================================== diff -u --- tests/depreciated_tests/test_deprime.py (revision 0) +++ tests/depreciated_tests/test_deprime.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,91 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_deprime.py +# +# @author (last) Quang Nguyen +# @date (last) 01-Apr-2021 +# @author (original) Quang Nguyen +# @date (original) 01-Apr-2021 +# +############################################################################ +import sys +sys.path.append("..") +from dialin.dg.dialysate_generator import DG +from dialin.hd.hemodialysis_device import HD +from dialin.hd.valves import ValvesEnum, ValvesPositions +from time import sleep + +def dePrime(): + hd.valves.cmd_set_hd_valve_position(ValvesEnum.VDI.value, ValvesPositions.VALVE_POSITION_B_OPEN.value) + hd.valves.cmd_set_hd_valve_position(ValvesEnum.VDO.value, ValvesPositions.VALVE_POSITION_B_OPEN.value) + hd.valves.cmd_set_hd_valve_position(ValvesEnum.VBA.value, ValvesPositions.VALVE_POSITION_B_OPEN.value) + hd.valves.cmd_set_hd_valve_position(ValvesEnum.VBV.value, ValvesPositions.VALVE_POSITION_B_OPEN.value) + + hd.dialysate_inlet_flow.cmd_dialysate_inlet_flow_set_point_override(400, 1) + hd.dialysate_outlet_flow.cmd_dialysate_outlet_flow_set_point_override(400, 1) + hd.bloodflow.cmd_blood_flow_set_point_override(400, 1) + +def drainReservoirs( drainRes ): + if ( drainRes == 1 ): + dg.reservoirs.cmd_switch_reservoirs(0) + else: + dg.reservoirs.cmd_switch_reservoirs(1) + sleep(1) + + dg.hd_proxy.cmd_drain(0) + sleep(1) + while dg.dg_operation_mode == 5: + sleep(1) + print("In recirc") + + while dg.dg_operation_mode == 7: + sleep(1) + print("Draining") + print("Drain Completed") + +if __name__ == "__main__": + + dg = DG() + hd = HD() + + counter=0 + skipDrain=False + dg.cmd_log_in_to_dg() + hd.cmd_log_in_to_hd() + + dg.hd_proxy.cmd_start_stop_dg() + + if skipDrain == False: + drainReservoirs(0) + drainReservoirs(1) + + dg.reservoirs.cmd_switch_reservoirs(0) + dg.valves.cmd_valve_override(1, dg.valves.VALVE_RESERVOIR_INLET) + + dePrime() + + while True: + print("COUNTER: {} - HD {} sub-mode {}, DG {} sub-mode {} RO pump {} Res1 {} Res2 {}".format( + counter, + hd.hd_operation_mode, + hd.hd_operation_sub_mode, + dg.dg_operation_mode, + dg.dg_operation_sub_mode, + dg.ro_pump.measured_flow_rate_lpm, + dg.load_cells.load_cell_A1, + dg.load_cells.load_cell_B1 + )) + + sleep(1) + counter = counter + 1 + + if counter > 60: + hd.dialysate_inlet_flow.cmd_dialysate_inlet_flow_set_point_override(0, 1) + hd.dialysate_outlet_flow.cmd_dialysate_outlet_flow_set_point_override(0, 1) + hd.bloodflow.cmd_blood_flow_set_point_override(0, 1) + break Index: tests/depreciated_tests/test_dg_records.py =================================================================== diff -u --- tests/depreciated_tests/test_dg_records.py (revision 0) +++ tests/depreciated_tests/test_dg_records.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,114 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_dg_records.py +# +# @author (last) Dara Navaei +# @date (last) 28-Sep-2022 +# @author (original) Dara Navaei +# @date (original) 01-Mar-2021 +# +############################################################################ +from dialin.dg.dialysate_generator import DG +from time import sleep + + +def process_calibration_record(read=False): + + cal = dg.calibration_record + print(cal.dg_calibration_record) + + try: + if read: + cal.cmd_request_dg_calibration_record() + while True: + sleep(0.5) + if cal.cal_data != 0: + #if cal.is_reading_record_done(): + sleep(4) + break + else: + cal.cmd_set_dg_calibration_record() + + print(cal.dg_calibration_record) + + except KeyboardInterrupt: + pass + + +def process_system_record(read=False): + + sys = dg.system_record + print(sys.dg_system_record) + + try: + if read: + sys.get_dg_system_record() + while True: + sleep(0.5) + if sys.is_reading_record_done(): + if sys.is_reading_record_done(): + break + else: + sys.set_dg_system_record() + + print(sys.dg_system_record) + + except KeyboardInterrupt: + pass + + +def process_service_record(read=False): + + sys = dg.service_record + print(sys.dg_service_record) + + try: + if read: + sys.get_dg_service_record() + while True: + sleep(0.5) + if sys.is_reading_record_done(): + if sys.is_reading_record_done(): + break + else: + sys.set_dg_service_record() + + print(sys.dg_service_record) + + except KeyboardInterrupt: + pass + + +if __name__ == "__main__": + # Create an instance of the DG Class + dg = DG(log_level='DEBUG') + + if dg.cmd_log_in_to_dg() == 0: + exit(1) + sleep(2) + + """ + dg.calibration_record.cmd_request_dg_calibration_record() + sleep(5) + dg.calibration_record.cmd_set_dg_calibration_record(dg.calibration_record.dg_calibration_record) + sleep(5) + + dg.calibration_record.cmd_request_dg_calibration_record() + sleep(5) + dg.calibration_record.cmd_set_dg_calibration_record(dg.calibration_record.dg_calibration_record) + sleep(5) + """ + + #process_calibration_record(read=True) + #process_system_record(read=True) + #process_service_record(read=False) + + + + + Index: tests/depreciated_tests/test_dg_valves.py =================================================================== diff -u --- tests/depreciated_tests/test_dg_valves.py (revision 0) +++ tests/depreciated_tests/test_dg_valves.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,60 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_dg_valves.py +# +# @author (last) Peter Lucia +# @date (last) 21-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 14-Jul-2020 +# +############################################################################ +import unittest +import sys +sys.path.append("../..") +from datetime import datetime +from dialin.dg.dialysate_generator import DG + + +class DGValves(unittest.TestCase): + + # @unittest.skip("Skipping test_imports") + def test_dg_valves_conversion(self): + dg = DG() + observation = {'datetime': datetime(2020, 7, 13, 10, 43, 27, 433357), + 'valve_state_VBF': {'id': 5, 'state': True}, + 'valve_state_VDR': {'id': 7, 'state': True}, + 'valve_state_VPD': {'id': 12, 'state': True}, + 'valve_state_VPI': {'id': 8, 'state': True}, + 'valve_state_VPO': {'id': 4, 'state': True}, + 'valve_state_VR1': {'id': 10, 'state': True}, + 'valve_state_VR2': {'id': 11, 'state': True}, + 'valve_state_VRC': {'id': 6, 'state': True}, + 'valve_state_VRD': {'id': 2, 'state': True}, + 'valve_state_VRF': {'id': 0, 'state': True}, + 'valve_state_VRI': {'id': 1, 'state': True}, + 'valve_state_VRO': {'id': 3, 'state': True}, + 'valve_state_VSP': {'id': 9, 'state': True}, + 'valve_states_all': 8191} + + assert(dg.valves.sort_by_id(observation) == [('valve_state_VRF', 0, True), + ('valve_state_VRI', 1, True), + ('valve_state_VRD', 2, True), + ('valve_state_VRO', 3, True), + ('valve_state_VPO', 4, True), + ('valve_state_VBF', 5, True), + ('valve_state_VRC', 6, True), + ('valve_state_VDR', 7, True), + ('valve_state_VPI', 8, True), + ('valve_state_VSP', 9, True), + ('valve_state_VR1', 10, True), + ('valve_state_VR2', 11, True), + ('valve_state_VPD', 12, True)]) + + +if __name__ == '__main__': + sys.exit(unittest.main(verbosity=2).result.wasSuccessful()) Index: tests/depreciated_tests/test_dialysate_flow_sensor.py =================================================================== diff -u --- tests/depreciated_tests/test_dialysate_flow_sensor.py (revision 0) +++ tests/depreciated_tests/test_dialysate_flow_sensor.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,45 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_dialysate_flow_sensor.py +# +# @author (last) Sean Nash +# @date (last) 16-Nov-2021 +# @author (original) Hung Nguyen +# @date (original) 29-Oct-2021 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from dialin.dg.dialysate_generator import DG +from time import sleep + +if __name__ == "__main__": + + # Create a dialysate flow object called df_object + dg_object = DG() + hd_object = HD() + + dg_object.cmd_log_in_to_dg() + #dg_object.dialysate_flow_sensor.cmd_flow_sensor_data_broadcast_interval_override(50,0) + #dg_object.dialysate_flow_sensor.cmd_flow_sensor_value_override(499.99 , 0) + #sleep(2) + + while True: + print("Measured Dialysate Flow =, {} ,mL/min".format(dg_object.dialysate_flow_sensor.get_flow_rate())+ + ", UF Rate =, {} ,mL/min".format(hd_object.dialysate_outlet_flow.get_measured_dialysate_outlet_pump_speed())) + sleep(1) + + + + + + + + Index: tests/depreciated_tests/test_flush.py =================================================================== diff -u --- tests/depreciated_tests/test_flush.py (revision 0) +++ tests/depreciated_tests/test_flush.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,163 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_flush.py +# +# @author (last) Dara Navaei +# @date (last) 18-Jan-2023 +# @author (original) Dara Navaei +# @date (original) 16-Apr-2021 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.dg.dialysate_generator import DG +from dialin.hd.hemodialysis_device import HD +from dialin.dg.drain_pump import DrainPumpStates +from time import sleep + + +def get_flush_mode_info(): + + """ + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, Drain_vol, {:5.3f}, Top_alarm, {}, Op, {}, ' + 'Sub, {}, History, {}, ' + .format(dg.flush.flush_state, dg.flush.overall_elapsed_time, dg.flush.state_elapsed_time, + dg.flush.flush_drain_line_volume_l, hd.alarms.alarm_top, dg.events.get_dg_events(1, 0), + dg.events.get_dg_nth_event(2), dg.events.get_dg_events(2, 70))) + """ + + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, Drain_vol, {:5.3f}, Top_alarm, {}, ' + .format(dg.flush.flush_state, dg.flush.overall_elapsed_time, dg.flush.state_elapsed_time, + dg.flush.flush_drain_line_volume_l, hd.alarms.alarm_top)) + + return info + +def get_concentrate_pumps_info(): + + info = ('Bicarb_tgt_speed, {:5.3f}, Bicarb_speed, {:5.3f}, Acid_tgt_speed, {:5.3f}, Acid_speed, {:5.3f}, ' + 'CPo, {:5.3f}, CD1, {:5.3f}, CD2, {:5.3f}, ' + .format(dg.concentrate_pumps.concentrate_pump_cp2_current_set_speed, + dg.concentrate_pumps.concentrate_pump_cp2_measured_speed, + dg.concentrate_pumps.concentrate_pump_cp1_current_set_speed, + dg.concentrate_pumps.concentrate_pump_cp1_measured_speed, + dg.conductivity_sensors.conductivity_sensor_cpo, dg.conductivity_sensors.conductivity_sensor_cd1, + dg.conductivity_sensors.conductivity_sensor_cd2)) + return info + + +def get_dg_valves_states(): + + info = ('VPi, {}, VSP, {}, VPd, {}, VBf, {}, VPo, {}, VDr, {}, VRc, {}, VRo, {}, VRd, {}, VRi, {}, VRf, {}, ' + 'VRD1, {}, VRD2, {}, ' + .format(dg.valves.valve_states_enum[dg.valves.VALVE_PRESSURE_INLET], + dg.valves.valve_states_enum[dg.valves.VALVE_SAMPLING_PORT], + dg.valves.valve_states_enum[dg.valves.VALVE_PRODUCTION_DRAIN], + dg.valves.valve_states_enum[dg.valves.VALVE_BYPASS_FILTER], + dg.valves.valve_states_enum[dg.valves.VALVE_PRESSURE_OUTLET], + dg.valves.valve_states_enum[dg.valves.VALVE_DRAIN], + dg.valves.valve_states_enum[dg.valves.VALVE_RECIRCULATE], + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_OUTLET], + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_DRAIN], + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_INLET], + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_FILL], + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_DRAIN_1], + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_DRAIN_2])) + return info + + +def get_drain_states_info(): + + info = ('Drain, {}, DAC, {}, Tgt_RPM, {}, Curr_RPM, {}, PRd, {:5.3f}, PDr, {:5.3f}, '. + format(DrainPumpStates(dg.drain_pump.drain_pump_state).name, dg.drain_pump.dac_value, + dg.drain_pump.target_drain_pump_rpm, dg.drain_pump.current_drain_pump_rpm, + dg.pressures.drain_pump_inlet_pressure, + dg.pressures.drain_pump_outlet_pressure)) + return info + + +def get_load_cells_info(): + + info = ('A1, {:5.3f}, A2, {:5.3f}, B1, {:5.3f}, B2, {:5.3f}, '. + format(dg.load_cells.load_cell_A1, dg.load_cells.load_cell_A2, dg.load_cells.load_cell_B1, + dg.load_cells.load_cell_B2)) + return info + + +def get_ro_info(): + + info = ('RO, {}, PPi, {:5.3f}, PPo, {:5.3f}, PWM, {:5.3f}, Flow, {:5.3f}, Feedback_PWM, {:5.3f},' + .format(dg.ro_pump.ro_pump_state, dg.pressures.ro_pump_inlet_pressure, + dg.pressures.ro_pump_outlet_pressure, dg.ro_pump.pwm_duty_cycle_pct, + dg.ro_pump.measured_flow_rate_lpm, dg.ro_pump.feedback_duty_cycle_pct)) + return info + + +def get_uv_reactors_info(): + + info = ('Inlet_status, {}, Outlet_status, {}, ' + .format(dg.uv_reactors.inlet_uv_reactor_state, dg.uv_reactors.outlet_uv_reactor_state)) + return info + + +def run_flush_mode(): + + complete_counter = 1 + f = open("/home/fw/projects/leahi_dialin/tests/flush_mode.log", "w") + dg.hd_proxy.cmd_start_stop_dg_flush() + #dg.cmd_dg_software_reset_request() + + try: + while True: + flush = get_flush_mode_info() + load_cell = get_load_cells_info() + drain = get_drain_states_info() + ro = get_ro_info() + conc = get_concentrate_pumps_info() + uv_reactors = get_uv_reactors_info() + valves = get_dg_valves_states() + + var = flush + load_cell + drain + ro + conc + uv_reactors + valves + '\r' + + print(var) + f.write(var) + sleep(1) + + # If the mode came back to standby or standby solo + if dg.dg_operation_mode == 3 or dg.dg_operation_mode == 4: + + if complete_counter == 1: + dg.hd_proxy.cmd_start_stop_dg_flush() + # Write a few more complete states to make sure the complete state items are recorded + if complete_counter == 3: + f.close() + #events = dg.events.get_dg_events(2, 60) + #for event in events: + # print(event) + break + + complete_counter += 1 + + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg_flush(start=False) + f.close() + #events = dg.events.get_dg_events(2, 50) + #for event in events: + # print(event) + + +if __name__ == "__main__": + + dg = DG(log_level='DEBUG') + hd = HD(log_level='DEBUG') + dg.cmd_log_in_to_dg() + sleep(1) + hd.cmd_log_in_to_hd() + sleep(1) + + run_flush_mode() Index: tests/depreciated_tests/test_hd.py =================================================================== diff -u --- tests/depreciated_tests/test_hd.py (revision 0) +++ tests/depreciated_tests/test_hd.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,84 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_hd.py +# +# @author (last) Peter Lucia +# @date (last) 02-Oct-2020 +# @author (original) Peter Lucia +# @date (original) 14-Jul-2020 +# +############################################################################ +import sys +sys.path.append("..") +from dialin.hd.constants import RESET, NO_RESET +from dialin import HD +from time import sleep +import unittest + + +class Test(unittest.TestCase): + + # @unittest.skip("Skipping test_hd_1.") + def test_hd_1(self): + hd = HD() + sleep(2) + + if hd.basics.cmd_log_in_to_hd() == 0: + exit(1) + + hd.bloodflow.cmd_blood_flow_broadcast_interval_override(RESET, 0) + + sleep(2) + print("Blood Flow Target = {}".format(hd.bloodflow.target_blood_flow_rate)) + print("Blood Pump Current = {}".format(hd.bloodflow.measured_blood_pump_mc_current)) + sleep(5) + print("Blood Pump Current = {}".format(hd.bloodflow.measured_blood_pump_mc_current)) + + hd.bloodflow.cmd_blood_pump_measured_current_override(NO_RESET, 140) + + sleep(1) + print("Blood Pump Current= {}".format(hd.bloodflow.measured_blood_pump_mc_current)) + sleep(5) + hd.bloodflow.cmd_blood_pump_measured_current_override(RESET, 0) + + i = 0 + while True: + sleep(0.5) + print("Measured Flow = {} mL/min".format(hd.bloodflow.measured_blood_flow_rate)) + if i > 0 and i % 60 == 0: + resp = input("Press 'Enter' to continue or 'q' to quit: ") + if resp.lower() == "q": + break + i += 1 + tgtRate = 0 + hd.bloodflow.cmd_blood_flow_broadcast_interval_override(NO_RESET, 2000) + + i = 0 + while True: + if hd.bloodflow.target_blood_flow_rate == 0: + if tgtRate != 0: + hd.bloodflow.cmd_blood_flow_broadcast_interval_override(NO_RESET, 2000) + tgtRate = 0 + else: + if tgtRate == 0: + hd.bloodflow.cmd_blood_flow_broadcast_interval_override(NO_RESET, 200) + tgtRate = hd.bloodflow.target_blood_flow_rate + if i > 0 and i % 60 == 0: + resp = input("Press 'Enter' to continue or 'q' to quit: ") + if resp.lower() == "q": + break + i += 1 + + # hd.bloodflow.cmd_blood_flow_broadcast_interval_override(RESET,0) + + # TODO: Update passing criteria + self.assertTrue(True) + + +if __name__ == '__main__': + unittest.main(verbosity=2) Index: tests/depreciated_tests/test_hd_dg_fans.py =================================================================== diff -u --- tests/depreciated_tests/test_hd_dg_fans.py (revision 0) +++ tests/depreciated_tests/test_hd_dg_fans.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,53 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_hd_dg_fans.py +# +# @author (last) Dara Navaei +# @date (last) 23-Feb-2022 +# @author (original) Dara Navaei +# @date (original) 04-Aug-2021 +# +############################################################################ + +from dialin import HD, DG +from dialin.hd.temperatures import HDTemperaturesNames +#from leahi_dialin.hd.fans import FansNames +from dialin.hd.switches import HDSwitchesNames +from time import sleep + + +def get_fans_info(): + info = ('Target_fans_DC, {:5.3f}, HD_fans_target_RPM, {:5.3f}, Inlet1_RPM, {:5.3f}, Board_temp, {:5.3f}, ' + 'Power_supply_temp, {:5.3f}, FPGA_temp, {:5.3f}, Venous_temp, {:5.3f}, pba_adc_temp, {:5.3f}, ' + .format(hd.fans.duty_cycle, hd.fans.target_rpm, hd.fans.inlet_1_rpm, + hd.temperatures.hd_temperatures[HDTemperaturesNames.THERMISTOR_ONBOARD_NTC.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.THERMISTOR_POWER_SUPPLY_1.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_FPGA_BOARD.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_VENOUS_PRESS_TEMP.name], + hd.temperatures.hd_temperatures[HDTemperaturesNames.TEMPSENSOR_PBA_ADC_SENSOR.name])) + return info + + +def get_hd_switches_info(): + info = ('Door_switch, {}, Pump_track_switch, {}'. + format(hd.switches.hd_switches_status[HDSwitchesNames.FRONT_DOOR.name], + hd.switches.hd_switches_status[HDSwitchesNames.PUMP_TRACK_SWITCH.name])) + return info + + +if __name__ == "__main__": + + # Create an instance of the DG Class + hd = HD(log_level='DEBUG') + + if hd.cmd_log_in_to_hd() == 0: + exit(1) + + while True: + print(get_fans_info()) + sleep(1) Index: tests/depreciated_tests/test_hd_records.py =================================================================== diff -u --- tests/depreciated_tests/test_hd_records.py (revision 0) +++ tests/depreciated_tests/test_hd_records.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,96 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_hd_records.py +# +# @author (last) Peter Lucia +# @date (last) 20-Apr-2021 +# @author (original) Dara Navaei +# @date (original) 14-Feb-2021 +# +############################################################################ +from dialin.hd.hemodialysis_device import HD +from time import sleep + + +def process_calibration_record(read=False): + + cal = hd.calibration_record + print(cal.hd_calibration_record) + + try: + if read: + cal.cmd_request_hd_calibration_record() + while True: + sleep(0.5) + if cal.cal_data != 0: + if cal.is_reading_record_done(): + break + else: + cal.set_hd_calibration_record() + + print(cal.hd_calibration_record) + + except KeyboardInterrupt: + pass + + +def process_system_record(read=False): + + sys = hd.system_record + print(sys.hd_system_record) + + try: + if read: + sys.get_hd_system_record() + while True: + sleep(0.5) + if sys.is_reading_record_done(): + if sys.is_reading_record_done(): + break + else: + sys.set_hd_system_record() + + print(sys.hd_system_record) + + except KeyboardInterrupt: + pass + + +def process_service_record(read=False): + + sys = hd.service_record + print(sys.hd_service_record) + + try: + if read: + sys.get_hd_service_record() + while True: + sleep(0.5) + if sys.is_reading_record_done(): + if sys.is_reading_record_done(): + break + else: + sys.set_hd_service_record() + + print(sys.hd_service_record) + + except KeyboardInterrupt: + pass + + +if __name__ == "__main__": + # Create an instance of the DG Class + hd = HD(log_level='DEBUG') + + if hd.cmd_log_in_to_hd() == 0: + exit(1) + sleep(2) + + #process_calibration_record(read=False) + #process_system_record(read=True) + process_service_record(read=False) \ No newline at end of file Index: tests/depreciated_tests/test_hd_valves.py =================================================================== diff -u --- tests/depreciated_tests/test_hd_valves.py (revision 0) +++ tests/depreciated_tests/test_hd_valves.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,77 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_hd_valves.py +# +# @author (last) Dara Navaei +# @date (last) 25-Apr-2023 +# @author (original) Sean Nash +# @date (original) 15-Oct-2020 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from dialin.hd.valves import ValvesEnum +from time import sleep +import os + +if __name__ == "__main__": + # create an HD object called hd + hd = HD() + hd.cmd_log_in_to_hd() + + address = os.path.join(os.getcwd(), "DVT-006-valves.log") + f = open(address, "w") + + hd.valves.cmd_hd_valves_broadcast_interval_override(50) + sleep(1) + #hd.valves.cmd_home_hd_valve(ValvesEnum.VDI.value) + + #hd.cmd_hd_set_operation_mode(2) + #sleep(1) + + while True: + var = str(hd.valves.valves_status) + '\r' + print(var) + f.write(var) + sleep(0.5) + + + """ + # print params every second for a while + while True: + sleep(0.100) + print(hd.valves.valves_status[ValvesEnum.VDI.name]['Valve'], + hd.valves.valves_status[ValvesEnum.VDI.name]['State'], + hd.valves.valves_status[ValvesEnum.VDI.name]['PosID'], + hd.valves.valves_status[ValvesEnum.VDI.name]['PosCnt'], + hd.valves.valves_status[ValvesEnum.VDI.name]['PosB'], + hd.valves.valves_status[ValvesEnum.VDI.name]['Current'], + hd.valves.valves_status[ValvesEnum.VDO.name]['Valve'], + hd.valves.valves_status[ValvesEnum.VDO.name]['State'], + hd.valves.valves_status[ValvesEnum.VDO.name]['PosID'], + hd.valves.valves_status[ValvesEnum.VDO.name]['PosCnt'], + hd.valves.valves_status[ValvesEnum.VDO.name]['PosB'], + hd.valves.valves_status[ValvesEnum.VDO.name]['Current'], + hd.valves.valves_status[ValvesEnum.VBA.name]['Valve'], + hd.valves.valves_status[ValvesEnum.VBA.name]['State'], + hd.valves.valves_status[ValvesEnum.VBA.name]['PosID'], + hd.valves.valves_status[ValvesEnum.VBA.name]['PosCnt'], + hd.valves.valves_status[ValvesEnum.VBA.name]['PosB'], + hd.valves.valves_status[ValvesEnum.VBA.name]['Current'], + hd.valves.valves_status[ValvesEnum.VBV.name]['Valve'], + hd.valves.valves_status[ValvesEnum.VBV.name]['State'], + hd.valves.valves_status[ValvesEnum.VBV.name]['PosID'], + hd.valves.valves_status[ValvesEnum.VBV.name]['PosCnt'], + hd.valves.valves_status[ValvesEnum.VBV.name]['PosB'], + hd.valves.valves_status[ValvesEnum.VBV.name]['Current']) + + exit(1) + """ + Index: tests/depreciated_tests/test_heparin.py =================================================================== diff -u --- tests/depreciated_tests/test_heparin.py (revision 0) +++ tests/depreciated_tests/test_heparin.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,28 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_heparin.py +# +# @author (last) Peter Lucia +# @date (last) 22-Feb-2021 +# @author (original) Peter Lucia +# @date (original) 22-Feb-2021 +# +############################################################################ +import sys +sys.path.append("..") +from dialin.ui import HDSimulator +from dialin.ui import TXStates + +hd_sim = HDSimulator() +# hd_sim.alarms_simulator.cmd_send_clear_alarms() +# hd_sim.cmd_set_treatment_states_data() +# hd_sim.cmd_send_start_treatment_response(1, 0) +hd_sim.cmd_set_treatment_states_data(TXStates.TREATMENT_DIALYSIS_STATE, + TXStates.UF_OFF_STATE, + TXStates.SALINE_BOLUS_STATE_IDLE, + TXStates.HEPARIN_STATE_OFF) \ No newline at end of file Index: tests/depreciated_tests/test_heprin_bolus_target_rate.py =================================================================== diff -u --- tests/depreciated_tests/test_heprin_bolus_target_rate.py (revision 0) +++ tests/depreciated_tests/test_heprin_bolus_target_rate.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,33 @@ +########################################################################### +# +# Copyright (c) 2022-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_heprin_bolus_target_rate.py +# +# @author (last) Hung Nguyen +# @date (last) 16-Feb-2022 +# @author (original) Hung Nguyen +# @date (original) 15-Feb-2022 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from time import sleep + +if __name__ == "__main__": + + # Create a heprin bolus set target rate object called hd_object + hd_object = HD() + hd_object.cmd_log_in_to_hd() + + hd_object.syringe_pump.cmd_heprin_target_rate_override(30.0) + + + + + Index: tests/depreciated_tests/test_lc.py =================================================================== diff -u --- tests/depreciated_tests/test_lc.py (revision 0) +++ tests/depreciated_tests/test_lc.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,49 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_lc.py +# +# @author (last) Sean Nash +# @date (last) 24-Mar-2021 +# @author (original) Sean Nash +# @date (original) 15-Mar-2021 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.dg.dialysate_generator import DG +from time import sleep + +if __name__ == "__main__": + # create a DG object called dg + dg = DG() + sleep(2) + + # log in to DG as tester +# if dg.cmd_log_in_to_dg() == 0: +# exit(1) +# sleep(1) + + # create log file + with open("LC_test.log", "w") as f: + + # collect load cell related data from DG + while True: + sleep(0.1) + loadCells = "FILTERED:, A1, " + '{:8.2f}'.format(dg.load_cells.load_cell_A1) + \ + ", B1, " + '{:8.2f}'.format(dg.load_cells.load_cell_B1) + \ + ", A2, " + '{:8.2f}'.format(dg.load_cells.load_cell_A2) + \ + ", B2, " + '{:8.2f}'.format(dg.load_cells.load_cell_B2) + + # log data + f.write(loadCells) + f.write("\n") + + # print to console + print(" Load Cells: "+loadCells) + Index: tests/depreciated_tests/test_nelson_labs_disinfect.py =================================================================== diff -u --- tests/depreciated_tests/test_nelson_labs_disinfect.py (revision 0) +++ tests/depreciated_tests/test_nelson_labs_disinfect.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,325 @@ +########################################################################### +# +# Copyright (c) 2023-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_nelson_labs_disinfect.py +# +# @author (last) Dara Navaei +# @date (last) 21-Jun-2023 +# @author (original) Dara Navaei +# @date (original) 03-Feb-2023 +# +############################################################################ +import os + +from dialin.dg.dialysate_generator import DG +from dialin.hd.hemodialysis_device import HD +from dialin.ui.hd_simulator import HDSimulator +from dialin.common.dg_defs import DGHeatDisinfectStates, DGHeatDisinfectUIStates +from dialin.dg.heat_disinfect import HeatCancellationModes, NelsonSupportModes +from dialin.common.dg_defs import DGChemicalDisinfectStates, DGChemDisinfectUIStates +from dialin.common.dg_defs import DGChemDisinfectFlushStates, DGChemDisinfectFlushUIStates +from dialin.dg.chemical_disinfect import ChemCancellationModes +from dialin.dg.drain_pump import DrainPumpStates +from dialin.dg.thermistors import ThermistorsNames +from dialin.dg.temperatures import DGTemperaturesNames +from dialin.dg.dialysate_generator import DGOperationModes +from dialin.hd.temperatures import HDTemperaturesNames +from dialin.dg.concentrate_pumps import DGConcentratePumpsStates +from dialin.dg.uv_reactors import ReactorsNames +from dialin.common.hd_defs import HDOpModes, HDStandbyStates, PreTreatmentWetSelfTestStates, PostTreatmentStates, \ + PreTreatmentDrySelfTestsStates +from dialin.hd.post_treatment import HDPostTreatmentDrainStates +from dialin.common.dg_defs import DGEventList +from dialin.common.hd_defs import HDEventList +from dialin.hd.reservoirs import HDReservoirStates +from dialin.dg.reservoirs import DGReservoirsNames +from dialin.common.dg_defs import DGGenIdleModeBadFillSubStates +from dialin.common.alarm_defs import AlarmList +from dialin.dg.fans import DGFansNames +from dialin.dg.pressures import DGPressures +from dialin.dg.conductivity_sensors import ConductivitySensorsEnum +from dialin.dg.voltages import DGMonitoredVoltages +from dialin.dg.valves import DGValveNames +from dialin.hd.valves import HDValves +from dialin.hd.voltages import HDMonitoredVoltages +from dialin.hd.pretreatment import PreTreatmentRsrvrState +from dialin.common.dg_defs import DGFlushStates, DGHeatDisinfectActiveCoolStates +from time import sleep +from datetime import datetime +import sys + +sys.path.append("..") + + +def get_chemical_disinfect_mode_info(): + + state = DGChemicalDisinfectStates(dg.chemical_disinfect.chemical_disinfect_state).name + overall_elapsed_time = dg.chemical_disinfect.overall_elapsed_time + state_elapsed_time = dg.chemical_disinfect.state_elapsed_time + + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, Disinfect_elapsed_time, {}, ' + 'Cancellation_mode, {}, R1_level, {:5.3f}, R2_level, {:5.3f}, Current_rinse_count, {}, ' + 'Total_rinse_count, {}, Top_alarm, {}, ' + .format(state, overall_elapsed_time, state_elapsed_time, + dg.chemical_disinfect.chemical_disinfect_target_time, + ChemCancellationModes(dg.chemical_disinfect.cancellation_mode).name, dg.chemical_disinfect.r1_level, + dg.chemical_disinfect.r2_level, dg.chemical_disinfect_flush.rinse_count, 0, hd.alarms.alarm_top)) + return info + + +def get_heat_disinfect_mode_info(): + + state = DGHeatDisinfectStates(dg.heat_disinfect.heat_disinfect_state).name + overall_elapsed_time = dg.heat_disinfect.overall_elapsed_time + state_elapsed_time = dg.heat_disinfect.state_elapsed_time + + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, Disinfect_RO_77, {}, Disinfect_RO_82, {}, ' + 'Disinfect_R_77, {}, Disinfect_R_82, {}, R1_level, {:5.3f}, R2_level, {:5.3f}, Top_alarm, {}, UI_state, {},' + ' ' + .format(state, overall_elapsed_time, state_elapsed_time, dg.heat_disinfect.disinfect_ro_77_time_s, + dg.heat_disinfect.disinfect_ro_82_time_s, dg.heat_disinfect.disinfect_r_77_time_s, + dg.heat_disinfect.disinfect_r_82_time_s, dg.heat_disinfect.r1_level, dg.heat_disinfect.r2_level, + hd.alarms.alarm_top, DGHeatDisinfectUIStates(dg.heat_disinfect.heat_disinfect_ui_state).name)) + return info + + +def get_dg_valves_states(): + info = ('VPi, {}, VSP, {}, VPd, {}, VBf, {}, VPo, {}, VDr, {}, VRc, {}, VRo, {}, VRi, {}, VRf, {}, ' + 'VRD1, {}, VRD2, {}, ' + .format(dg.valves.valve_states_enum[DGValveNames.VALVE_PRESSURE_INLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_SAMPLING_PORT.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_PRODUCTION_DRAIN.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_BYPASS_FILTER.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_PRESSURE_OUTLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_DRAIN.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RECIRCULATE.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_OUTLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_INLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_FILL.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_DRAIN_1.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_DRAIN_2.value])) + return info + + +def get_drain_states_info(): + info = ('Drain, {}, DAC, {}, Tgt_RPM, {}, Curr_RPM, {}, PRd, {:5.3f}, PDr, {:5.3f}, Baro, {:5.3f}, ' + 'Drain_curr_A, {:5.3f}, Drain_dir, {}, Target_flow_lpm, {:5.3f}, ' + .format(DrainPumpStates(dg.drain_pump.drain_pump_state).name, dg.drain_pump.dac_value, + dg.drain_pump.target_drain_pump_rpm, dg.drain_pump.current_drain_pump_rpm, + dg.pressures.drain_pump_inlet_pressure, dg.pressures.drain_pump_outlet_pressure, + dg.pressures.barometric_pressure, dg.drain_pump.drain_pump_current_A, + dg.drain_pump.drain_pump_direction, dg.drain_pump.target_drain_pump_outlet_flow_lpm)) + return info + + +def get_load_cells_info(): + info = ('A1, {:5.3f}, A2, {:5.3f}, B1, {:5.3f}, B2, {:5.3f}, ' + .format(dg.load_cells.load_cell_A1, dg.load_cells.load_cell_A2, dg.load_cells.load_cell_B1, + dg.load_cells.load_cell_B2)) + return info + + +def get_ro_info(): + info = ('RO, {}, PPi, {:5.3f}, PPo, {:5.3f}, PWM, {:5.3f}, Flow, {:5.3f}, Tgt_flow, {:5.3f}, ' + 'Feedback_PWM, {:5.3f}, Flow_with_conc_pumps, {:5.3f}, Dialysate_flow, {:5.3f}, ' + .format(dg.ro_pump.ro_pump_state, dg.pressures.ro_pump_inlet_pressure, + dg.pressures.ro_pump_outlet_pressure, dg.ro_pump.pwm_duty_cycle_pct, + dg.flow_sensors.measured_ro_flow_LPM, dg.ro_pump.target_flow_lpm, + dg.ro_pump.feedback_duty_cycle_pct, + dg.flow_sensors.measured_ro_flow_with_cp_LPM, dg.flow_sensors.measured_dialysate_flow_LPM)) + return info + + +def get_heaters_info(): + info = ('Pri_main_DC, {:5.3f}, Pri_state, {}, Trimmer_DC, {:5.3f}, Trimmer_state, {}, ' + 'Primary_target_temp, {:5.3f}, Trimmer_target_temp, {:5.3f}, Primary_eff, {:5.3f}, ' + 'Primary_calc_temp, {:5.3f}, Trimmer_calc_temp, {:5.3f}, Primary_power, {:5.3f}, ' + 'Primary_volt, {:5.3f}, Primary_sec_volt, {:5.3f}, Trimmer_volt, {:5.3f}, Trimmer_use_last_dc, {}, ' + .format(dg.heaters.main_primary_heater_duty_cycle, dg.heaters.primary_heater_state, + dg.heaters.trimmer_heater_duty_cycle, dg.heaters.trimmer_heater_state, + dg.heaters.primary_heaters_target_temperature, dg.heaters.trimmer_heater_target_temperature, + dg.heaters.primary_efficiency, dg.heaters.primary_calc_target_temperature, + dg.heaters.trimmer_calc_target_temperature, + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_POWER_PRIM_HTR_V.value], + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_GND_MAIN_PRIM_HTR_V.value], + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_GND_SMALL_PRIM_HTR_V.value], + dg.voltages.monitored_voltages[DGMonitoredVoltages.MONITORED_LINE_24V_GND_TRIM_HTR_V.value], + dg.heaters.trimmer_use_last_duty_cycle)) + return info + + +def get_temperature_sensors_info(): + info = ('TPi, {:5.3f}, THd, {:5.3f}, TPo, {:5.3f}, TD1, {:5.3f}, TD2, {:5.3f}, TRo, {:5.3f}, TDi, {:5.3f}, ' + 'Baro_temp, {:5.3f}, ' + .format(dg.temperatures.temperatures[DGTemperaturesNames.INLET_PRIMARY_HEATER.name], + dg.temperatures.temperatures[DGTemperaturesNames.HEAT_DISINFECT.name], + dg.temperatures.temperatures[DGTemperaturesNames.OUTLET_PRIMARY_HEATER.name], + dg.temperatures.temperatures[DGTemperaturesNames.CONDUCTIVITY_SENSOR_1.name], + dg.temperatures.temperatures[DGTemperaturesNames.CONDUCTIVITY_SENSOR_2.name], + dg.temperatures.temperatures[DGTemperaturesNames.OUTLET_DIALYSATE_REDUNDANT.name], + dg.temperatures.temperatures[DGTemperaturesNames.INLET_DIALYSATE.name], + dg.temperatures.temperatures[DGTemperaturesNames.BARO_TEMP_SENSOR.name])) + return info + + +def get_uv_reactors_info(): + info = ('Inlet_status, {}, Outlet_status, {}, Inlet_health, {}, Outlet_health, {}, ' + .format(dg.uv_reactors.inlet_uv_reactor_state, dg.uv_reactors.outlet_uv_reactor_state, + dg.uv_reactors.inlet_uv_reactor_health, dg.uv_reactors.outlet_uv_reactor_health)) + return info + + +def get_concentrate_pumps_info(): + info = ('Bicarb_curr_speed, {:5.3f}, Bicarb_speed, {:5.3f}, Acid_curr_speed, {:5.3f}, Acid_speed, {:5.3f}, ' + 'CPo, {:5.3f}, CD1, {:5.3f}, CD2, {:5.3f}, CP1_state, {}, CP2_state, {}, CPi_status, {}, CPo_status, {}, ' + 'CD1_status, {}, CD2_status, {}, CP1_pulse, {:5.3f}, CP2_pulse, {:5.3f}, Acid_tgt_speed, {:5.3f}, ' + 'Bicarb_tgt_speed, {:5.3f}, CP1_parked, {}, CP1_park_fault, {}, CP2_parked, {}, CP2_park_fault, {}, ' + .format(dg.concentrate_pumps.concentrate_pump_cp2_current_set_speed, + dg.concentrate_pumps.concentrate_pump_cp2_measured_speed, + dg.concentrate_pumps.concentrate_pump_cp1_current_set_speed, + dg.concentrate_pumps.concentrate_pump_cp1_measured_speed, + dg.conductivity_sensors.conductivity_sensor_cpo, + dg.conductivity_sensors.conductivity_sensor_cd1, + dg.conductivity_sensors.conductivity_sensor_cd2, + DGConcentratePumpsStates(dg.concentrate_pumps.concentrate_pump_cp1_current_state).name, + DGConcentratePumpsStates(dg.concentrate_pumps.concentrate_pump_cp2_current_state).name, + dg.conductivity_sensors.cpi_sensor_status, dg.conductivity_sensors.cpo_sensor_status, + dg.conductivity_sensors.cd1_sensor_status, dg.conductivity_sensors.cd2_sensor_status, + dg.concentrate_pumps.cp1_temp_pulse, dg.concentrate_pumps.cp2_temp_pulse, + dg.concentrate_pumps.concentrate_pump_cp1_target_speed, + dg.concentrate_pumps.concentrate_pump_cp2_target_speed, + dg.concentrate_pumps.concentrate_pump_cp1_parked, + dg.concentrate_pumps.concentrate_pump_cp1_park_fault, + dg.concentrate_pumps.concentrate_pump_cp2_parked, + dg.concentrate_pumps.concentrate_pump_cp2_park_fault)) + return info + + +def get_dg_fans_info(): + info = ('Target_fans_DC, {:5.3f}, Inlet1_RPM, {:5.3f}, Inlet2_RPM, {:5.3f}, Inlet3_RPM, {:5.3f}, ' + 'Outlet1_RPM, {:5.3f}, Outlet2_RPM, {:5.3f}, Outlet3_RPM, {:5.3f}, Board_temp, {:5.3f}, ' + 'Power_supply_1, {:5.3f}, Power_supply_2, {:5.3f}, FPGA_temp, {:5.3f}, Load_cell_A1_B1, {:5.3f}, ' + 'Load_cell_A2_B2, {:5.3f}, timeOffset, {}, ' + .format(dg.fans.dg_fans_duty_cycle, dg.fans.inlet_1_rpm, dg.fans.inlet_2_rpm, dg.fans.inlet_3_rpm, + dg.fans.outlet_1_rpm, dg.fans.outlet_2_rpm, dg.fans.outlet_3_rpm, + dg.thermistors.thermistors[ThermistorsNames.THERMISTOR_ONBOARD_NTC.name], + dg.thermistors.thermistors[ThermistorsNames.THERMISTOR_POWER_SUPPLY_1.name], + dg.thermistors.thermistors[ThermistorsNames.THERMISTOR_POWER_SUPPLY_2.name], + dg.temperatures.temperatures[DGTemperaturesNames.FPGA_BOARD_SENSOR.name], + dg.temperatures.temperatures[DGTemperaturesNames.LOAD_CELL_A1_B1.name], + dg.temperatures.temperatures[DGTemperaturesNames.LOAD_CELL_A2_B2.name], + dg.fans.rpm_alarm_time)) + return info + + +def get_sensors_actuators_info(nelson_support, f): + + call_numer = 0 + try: + while True: + if nelson_support == NelsonSupportModes.NELSON_INOCULATE.name or \ + nelson_support == NelsonSupportModes.NELSON_HEAT_DISINFECT.name or \ + nelson_support == NelsonSupportModes.NELSON_DRAIN_SAMPLE.name or \ + nelson_support == NelsonSupportModes.NELSON_POS_CONTROL_HEAT_DISINFECT.name: + disinfect = get_heat_disinfect_mode_info() + else: + disinfect = get_chemical_disinfect_mode_info() + drain = get_drain_states_info() + load_cell = get_load_cells_info() + valves = get_dg_valves_states() + ro = get_ro_info() + temp = get_temperature_sensors_info() + heaters = get_heaters_info() + uv = get_uv_reactors_info() + dg_fans = get_dg_fans_info() + conc = get_concentrate_pumps_info() + + var = str(datetime.now()) + ', ' + disinfect + load_cell + drain + ro + temp + heaters + uv + dg_fans + \ + valves + conc + '\r' + + print(var) + f.write(var) + sleep(1) + + # Wait for a couple of seconds and then exit this loop if we are no longer in any of the disinfect modes + if dg.dg_operation_mode is not DGOperationModes.DG_OP_MODE_DISINFECT.value and \ + dg.dg_operation_mode is not DGOperationModes.DG_OP_MODE_CHEMICAL_DISINFECT.value: + call_numer += 1 + + if call_numer > 3: + f.close() + exit() + + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg_heat_disinfect(start=False) + dg.hd_proxy.cmd_start_stop_dg_chemical_disinfect(start=False) + f.close() + + +def run_nelson_inoculate(): + + current_dir = os.getcwd() + mode = NelsonSupportModes.NELSON_INOCULATE.name + log_file = os.path.join(current_dir, mode.lower() + '.log') + f = open(log_file, "w") + dg.heat_disinfect.cmd_set_nelson_support_mode(NelsonSupportModes.NELSON_INOCULATE.value) + get_sensors_actuators_info(mode, f) + + +def run_nelson_drain_samples(): + current_dir = os.getcwd() + mode = NelsonSupportModes.NELSON_DRAIN_SAMPLE.name + log_file = os.path.join(current_dir, mode.lower() + '.log') + f = open(log_file, "w") + dg.heat_disinfect.cmd_set_nelson_support_mode(NelsonSupportModes.NELSON_DRAIN_SAMPLE.value) + get_sensors_actuators_info(mode, f) + + +def run_nelson_heat_positive_control(): + current_dir = os.getcwd() + mode = NelsonSupportModes.NELSON_POS_CONTROL_HEAT_DISINFECT.name + log_file = os.path.join(current_dir, mode.lower() + '.log') + f = open(log_file, "w") + dg.heat_disinfect.cmd_set_nelson_support_mode(NelsonSupportModes.NELSON_POS_CONTROL_HEAT_DISINFECT.value) + get_sensors_actuators_info(mode, f) + + +def run_nelson_heat_disinfect(): + current_dir = os.getcwd() + mode = NelsonSupportModes.NELSON_HEAT_DISINFECT.name + log_file = os.path.join(current_dir, mode.lower() + '.log') + f = open(log_file, "w") + dg.heat_disinfect.cmd_set_nelson_support_mode(NelsonSupportModes.NELSON_HEAT_DISINFECT.value) + get_sensors_actuators_info(mode, f) + + +def run_nelson_chem_disinfect(): + current_dir = os.getcwd() + mode = NelsonSupportModes.NELSON_CHEM_DISINFECT.name + log_file = os.path.join(current_dir, mode.lower() + '.log') + f = open(log_file, "w") + dg.heat_disinfect.cmd_set_nelson_support_mode(NelsonSupportModes.NELSON_CHEM_DISINFECT.value) + get_sensors_actuators_info(mode, f) + + +if __name__ == "__main__": + dg = DG(log_level='DEBUG') + dg.cmd_log_in_to_dg() + sleep(1) + hd = HD(log_level='DEBUG') + hd.cmd_log_in_to_hd() + sleep(1) + + #run_nelson_inoculate() + + #run_nelson_drain_samples() + + #run_nelson_heat_positive_control() + + #run_nelson_heat_disinfect() + + run_nelson_chem_disinfect() \ No newline at end of file Index: tests/depreciated_tests/test_saline_bolus.py =================================================================== diff -u --- tests/depreciated_tests/test_saline_bolus.py (revision 0) +++ tests/depreciated_tests/test_saline_bolus.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,55 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_saline_bolus.py +# +# @author (last) Sean Nash +# @date (last) 09-Oct-2020 +# @author (original) Sean Nash +# @date (original) 30-Sep-2020 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from time import sleep + +if __name__ == "__main__": + # create an HD object called hd + hd = HD() + + # print params every second for a while + for x in range(300): + sleep(1) + hdmod = hd.hd_operation_mode + hdsub = hd.hd_operation_sub_mode + trtim = hd.treatment.get_treatment_time_elapsed() + ufmod = hd.treatment.get_treatment_uf_state() + sbmod = hd.treatment.get_saline_bolus_state() + mxvol = hd.treatment.get_saline_bolus_max_volume() + cmvol = hd.treatment.get_saline_bolus_cumulative_volume_delivered() + bovol = hd.treatment.get_saline_bolus_volume_delivered() + print(x, hdmod, hdsub, trtim, ufmod, sbmod, mxvol, cmvol, bovol) + + # exit here unless you want to trigger a saline bolus from here + exit(1) + # send saline bolus request + hd.ui.cmd_ui_request_saline_bolus(True) + # continue showing params every second + for x in range(60): + sleep(1) + hdmod = hd.hd_operation_mode + hdsub = hd.hd_operation_sub_mode + ufmod = hd.treatment.get_treatment_uf_state() + sbmod = hd.treatment.get_saline_bolus_state() + mxvol = hd.treatment.get_saline_bolus_max_volume() + cmvol = hd.treatment.get_saline_bolus_cumulative_volume_delivered() + bovol = hd.treatment.get_saline_bolus_volume_delivered() + print(x, hdmod, hdsub, ufmod, sbmod, mxvol, cmvol, bovol) + + exit(1) Index: tests/depreciated_tests/test_syringe.py =================================================================== diff -u --- tests/depreciated_tests/test_syringe.py (revision 0) +++ tests/depreciated_tests/test_syringe.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,68 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_syringe.py +# +# @author (last) Sean Nash +# @date (last) 07-May-2021 +# @author (original) Sean Nash +# @date (original) 15-Mar-2021 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from time import sleep + +if __name__ == "__main__": + # create an HD object called hd + hd = HD() + sleep(2) + + # log in to HD and DG as tester + if hd.cmd_log_in_to_hd() == 0: + exit(1) + sleep(1) + +# hd.syringe_pump.cmd_syringe_pump_operation(0,0.0,0.0) # stop +# hd.syringe_pump.cmd_syringe_pump_operation(1,0.0,0.0) # retract +# sleep(10) +# hd.syringe_pump.cmd_syringe_pump_operation(2,0.0,0.0) # seek +# sleep(5) +# hd.syringe_pump.cmd_syringe_pump_operation(3,0.0,0.0) # prime +# sleep(5) +# hd.syringe_pump.cmd_syringe_pump_operation(4,0.0,2.0) # bolus +# hd.syringe_pump.cmd_syringe_pump_operation(5,1.0,0.0) # continuous + + # create log file + with open("syringe_test.log", "w") as f: + # write column header labels to log file + header = "PumpState, Hep.State, SetRate, MeasRate, Position, Volume, HomeV, SwitchV, ForceV, SafetyVol\n" + f.write(header) + + # write syringe pump related data from HD to log file + while True: + sleep(1) + syringeData = '{:2d}'.format(hd.syringe_pump.syringe_pump_state) + \ + ", " + '{:2d}'.format(hd.syringe_pump.heparin_state) + \ + ", " + '{:12.6f}'.format(hd.syringe_pump.syringe_pump_set_rate_ml_hr) + \ + ", " + '{:12.6f}'.format(hd.syringe_pump.syringe_pump_meas_rate_ml_hr) + \ + ", " + '{:10d}'.format(hd.syringe_pump.syringe_pump_position) + \ + ", " + '{:12.9f}'.format(hd.syringe_pump.syringe_pump_volume_ml) + \ + ", " + '{:5.3f}'.format(hd.syringe_pump.syringe_pump_home_v) + \ + ", " + '{:5.3f}'.format(hd.syringe_pump.syringe_pump_switch_v) + \ + ", " + '{:5.3f}'.format(hd.syringe_pump.syringe_pump_force_v) + \ + ", " + '{:12.9}'.format(hd.syringe_pump.syringe_pump_safety_volume_ml) + "\n" + + # log data + f.write(syringeData) + + # print to console + print(syringeData) + + Index: tests/depreciated_tests/test_tx_config_tests.py =================================================================== diff -u --- tests/depreciated_tests/test_tx_config_tests.py (revision 0) +++ tests/depreciated_tests/test_tx_config_tests.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,393 @@ +########################################################################### +# +# Copyright (c) 2023-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_tx_config_tests.py +# +# @author (last) Dara Navaei +# @date (last) 28-Aug-2023 +# @author (original) Dara Navaei +# @date (original) 28-Aug-2023 +# +############################################################################ + +import os + +from dialin.dg.dialysate_generator import DG +from dialin.hd.hemodialysis_device import HD +from dialin.dg.load_cells import DGLoadCellNames +from dialin.hd.switches import HDSwitchesNames, HDSwitchStatus +from dialin.hd.constants import RESET, NO_RESET +from dialin.ui.hd_simulator import HDSimulator +from dialin.common.dg_defs import DGHeatDisinfectStates, DGHeatDisinfectUIStates +from dialin.dg.heat_disinfect import HeatCancellationModes, NelsonSupportModes +from dialin.common.dg_defs import DGChemicalDisinfectStates, DGChemDisinfectUIStates +from dialin.common.dg_defs import DGChemDisinfectFlushStates, DGChemDisinfectFlushUIStates +from dialin.dg.chemical_disinfect import ChemCancellationModes +from dialin.dg.drain_pump import DrainPumpStates, DrainPumpRPMFeedBackSensors +from dialin.dg.thermistors import ThermistorsNames +from dialin.dg.temperatures import DGTemperaturesNames +from dialin.dg.dialysate_generator import DGOperationModes +from dialin.hd.temperatures import HDTemperaturesNames +from dialin.dg.concentrate_pumps import DGConcentratePumpsStates +from dialin.dg.uv_reactors import ReactorsNames +from dialin.common.hd_defs import HDOpModes, HDStandbyStates, PreTreatmentWetSelfTestStates, PostTreatmentStates, \ + PreTreatmentDrySelfTestsStates +from dialin.hd.post_treatment import HDPostTreatmentDrainStates +from dialin.common.dg_defs import DGEventList +from dialin.common.hd_defs import HDEventList +from dialin.hd.reservoirs import HDReservoirStates +from dialin.dg.reservoirs import DGReservoirsNames +from dialin.common.dg_defs import DGGenIdleModeBadFillSubStates +from dialin.common.alarm_defs import AlarmList +from dialin.dg.fans import DGFansNames +from dialin.dg.pressures import DGPressures +from dialin.dg.conductivity_sensors import ConductivitySensorsEnum +from dialin.dg.voltages import DGMonitoredVoltages +from dialin.dg.valves import DGValveNames +from dialin.hd.valves import HDValves +from dialin.hd.voltages import HDMonitoredVoltages +from dialin.hd.pretreatment import PreTreatmentRsrvrState +from dialin.common.dg_defs import DGFlushStates, DGHeatDisinfectActiveCoolStates +from dialin.common.test_config_defs import DGTestConfigOptions, HDTestConfigOptions +from dialin.common.dg_defs import DGOpModes +from dg_tests import * +from time import sleep +from datetime import datetime +import sys + +sys.path.append("..") + + +def get_dg_run_info(): + info = ('DG_op_mode, {}, DG_op_mode_num, {}, DG_sub_mode, {}, '.format(DGOperationModes(dg.dg_operation_mode).name, + dg.dg_operation_mode, + dg.dg_operation_sub_mode)) + return info + + +def get_dg_valves_states(): + info = ('VPi, {}, VSP, {}, VPd, {}, VBf, {}, VPo, {}, VDr, {}, VRc, {}, VRo, {}, VRi, {}, VRf, {}, ' + 'VRD1, {}, VRD2, {}, ' + .format(dg.valves.valve_states_enum[DGValveNames.VALVE_PRESSURE_INLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_SAMPLING_PORT.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_PRODUCTION_DRAIN.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_BYPASS_FILTER.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_PRESSURE_OUTLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_DRAIN.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RECIRCULATE.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_OUTLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_INLET.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_FILL.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_DRAIN_1.value], + dg.valves.valve_states_enum[DGValveNames.VALVE_RESERVOIR_DRAIN_2.value])) + return info + + +def get_drain_states_info(): + info = ('Drain, {}, DAC, {}, Tgt_RPM, {}, Curr_RPM, {}, PRd, {:5.3f}, PDr, {:5.3f}, Baro, {:5.3f}, ' + 'Drain_curr_A, {:5.3f}, Drain_dir, {}, Target_flow_lpm, {:5.3f}, Maxon_rpm, {}, ' + .format(DrainPumpStates(dg.drain_pump.drain_pump_state).name, dg.drain_pump.dac_value, + dg.drain_pump.target_drain_pump_rpm, + dg.drain_pump.current_drain_pump_rpm[DrainPumpRPMFeedBackSensors.DRAIN_PUMP_HALL_SNSR_FB.name], + dg.pressures.drain_pump_inlet_pressure, dg.pressures.drain_pump_outlet_pressure, + dg.pressures.barometric_pressure, dg.drain_pump.drain_pump_current_A, + dg.drain_pump.drain_pump_direction, dg.drain_pump.target_drain_pump_outlet_flow_lpm, + dg.drain_pump.current_drain_pump_rpm[DrainPumpRPMFeedBackSensors.DRAIN_PUMP_MAXON_SNSR_FB.name])) + return info + + +def get_load_cells_info(): + info = ('A1, {:5.3f}, A2, {:5.3f}, B1, {:5.3f}, B2, {:5.3f}, ' + .format(dg.load_cells.load_cell_A1, dg.load_cells.load_cell_A2, dg.load_cells.load_cell_B1, + dg.load_cells.load_cell_B2)) + return info + + +def get_ro_info(): + info = ('RO, {}, PPi, {:5.3f}, PPo, {:5.3f}, PWM, {:5.3f}, Flow, {:5.3f}, Tgt_flow, {:5.3f}, ' + 'Feedback_PWM, {:5.3f}, Flow_with_conc_pumps, {:5.3f}, Dialysate_flow, {:5.3f}, ' + .format(dg.ro_pump.ro_pump_state, dg.pressures.ro_pump_inlet_pressure, + dg.pressures.ro_pump_outlet_pressure, dg.ro_pump.pwm_duty_cycle_pct, + dg.flow_sensors.measured_ro_flow_LPM, dg.ro_pump.target_flow_lpm, + dg.ro_pump.feedback_duty_cycle_pct, + dg.flow_sensors.measured_ro_flow_with_cp_LPM, dg.flow_sensors.measured_dialysate_flow_LPM)) + return info + + +def check_status(delay_counter, sleep_time, target_delay, state_counter): + + if delay_counter >= (target_delay / sleep_time): + state_counter += 1 + delay_counter = 0 + else: + delay_counter += 1 + + return state_counter, delay_counter + + +def recover_treatment(): + + sleep_time = 0.1 + counter = 1 + delay_counter = 0 + target_delay = 1 + + address = os.path.join(os.getcwd(), "treatment_recovery.log") + f = open(address, "w") + + try: + while True: + + dg_run = get_dg_run_info() + drain = get_drain_states_info() + load_cell = get_load_cells_info() + valves = get_dg_valves_states() + ro = get_ro_info() + + var = str(counter) + ',' + str(target_delay) + ',' + dg_run + load_cell + drain + ro + valves + '\r' + + print(var) + f.write(var) + + if counter == 1: + if delay_counter == 0: + #dg.load_cells.cmd_get_load_cells_tare_values() + pass + + # For testing only. Use the get function to get the actual tare values during the development of this + # script and the procedure for this + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_1_PRIMARY.name] = 1726.822998046875 + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_1_BACKUP.name] = 1716.2781982421875 + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_2_PRIMARY.name] = 1716.46484375 + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_2_BACKUP.name] = 1712.1719970703125 + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 2 and \ + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_1_PRIMARY.name] != 0.0: + if delay_counter == 0: + # Received the load cells tare values from DG. Reset both stacks + dg.cmd_dg_software_reset_request() + hd.cmd_hd_software_reset_request() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 3 and dg.dg_operation_mode == DGOpModes.DG_MODE_STAN.value: + if delay_counter == 0: + # After reset log in again + dg.cmd_log_in_to_dg() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 4 and dg.dg_operation_mode == DGOpModes.DG_MODE_STAN.value: + if delay_counter == 0: + dg.load_cells.cmd_set_load_cells_tare_values() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 5 and hd.hd_operation_mode == HDOpModes.MODE_STAN.value: + if delay_counter == 0: + hd.cmd_log_in_to_hd() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 6: + if delay_counter == 0: + # Set the operation mode is pre-treatment before commanding the start DG + hd.cmd_hd_set_operation_mode(HDOpModes.MODE_TPAR.value) + + counter, delay_counter = check_status(delay_counter, sleep_time, 0, counter) + + elif counter == 7 and hd.hd_operation_mode == HDOpModes.MODE_TPAR.value: + if delay_counter == 0: + # Start DG cannot be when HD is in standby + dg.hd_proxy.cmd_start_stop_dg() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 8 and dg.dg_operation_mode == DGOpModes.DG_MODE_GENE.value and dg.dg_operation_sub_mode == 1: + if delay_counter == 0: + # This section is for testing only to make sure we always have fluid in the reservoir. + # This part is not needed in the actual test procedure + dg.hd_proxy.cmd_fill(500) + #pass + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 9 and dg.dg_operation_mode == DGOpModes.DG_MODE_GENE.value and dg.dg_operation_sub_mode == 1: + if delay_counter == 0: + dg.hd_proxy.cmd_drain() + + counter, delay_counter = check_status(delay_counter, sleep_time, 0, counter) + + elif counter == 10 and dg.dg_operation_mode == DGOpModes.DG_MODE_DRAI.value and dg.dg_operation_sub_mode == 1: + if delay_counter == 0: + #dg.test_configs.cmd_set_test_config(DGTestConfigOptions.TEST_CONFIG_RECOVER_TREATMENT.value) + pass + + counter, delay_counter = check_status(delay_counter, sleep_time, 0, counter) + + elif counter == 11 and dg.dg_operation_mode == DGOpModes.DG_MODE_DRAI.value and dg.dg_operation_sub_mode == 1: + if delay_counter == 0: + dg.alarms.cmd_alarm_state_override(AlarmList.ALARM_ID_DG_BARO_PRESSURE_OUT_OF_RANGE.value, 1) + + counter, delay_counter = check_status(delay_counter, sleep_time, 0, counter) + + elif counter == 12 and dg.dg_operation_mode == DGOpModes.DG_MODE_FAUL.value and dg.dg_operation_sub_mode == 2: + if delay_counter == 0: + dg.alarms.cmd_alarm_state_override(AlarmList.ALARM_ID_DG_BARO_PRESSURE_OUT_OF_RANGE.value, 1, reset=1) + dg.test_configs.cmd_set_test_config(DGTestConfigOptions.TEST_CONFIG_RECOVER_TREATMENT.value) + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 13 and dg.dg_operation_mode == DGOpModes.DG_MODE_FAUL.value and dg.dg_operation_sub_mode == 2: + if delay_counter == 0: + dg.test_configs.cmd_set_recover_from_mode_fault_signal() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + sleep(sleep_time) + + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg(start=False) + f.close() + + +def expedite_pretreatment(): + + sleep_time = 0.1 + counter = 1 + delay_counter = 0 + target_delay = 1 + + while True: + if counter == 1: + if delay_counter == 0: + # dg.load_cells.cmd_get_load_cells_tare_values() + + # For testing only. Use the get function to get the actual tare values during the development of this + # script and the procedure for this + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_1_PRIMARY.name] = 1726.822998046875 + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_1_BACKUP.name] = 1716.2781982421875 + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_2_PRIMARY.name] = 1716.46484375 + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_2_BACKUP.name] = 1712.1719970703125 + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 2 and \ + dg.load_cells.load_cells_tare_values[DGLoadCellNames.LOAD_CELL_RESERVOIR_1_PRIMARY.name] != 0.0: + if delay_counter == 0: + # Received the load cells tare values from DG. Reset both stacks + dg.cmd_dg_software_reset_request() + hd.cmd_hd_software_reset_request() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 3 and dg.dg_operation_mode == 3: + if delay_counter == 0: + # After reset log in again + dg.cmd_log_in_to_dg() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 4: + if delay_counter == 0: + dg.load_cells.cmd_set_load_cells_tare_values() + + counter, delay_counter = check_status(delay_counter, sleep_time, 0, counter) + + elif counter == 5 and hd.hd_operation_mode == 3: + if delay_counter == 0: + hd.cmd_log_in_to_hd() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 6: + if delay_counter == 0: + # Set the operation mode is pre-treatment before commanding the start DG + hd.cmd_hd_set_operation_mode(4) + + counter, delay_counter = check_status(delay_counter, sleep_time, 0, counter) + + elif counter == 7 and hd.hd_operation_mode == 4: + if delay_counter == 0: + # Start DG cannot be when HD is in standby + dg.hd_proxy.cmd_start_stop_dg() + + counter, delay_counter = check_status(delay_counter, sleep_time, 0, counter) + + elif counter == 8 and dg.dg_operation_mode == 5 and dg.dg_operation_sub_mode == 1: + if delay_counter == 0: + # This section is for testing only to make sure we always have fluid in the reservoir. This part is not + # needed in the actual test procedure + dg.hd_proxy.cmd_fill(1600) + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 9 and dg.dg_operation_mode == 5 and dg.dg_operation_sub_mode == 1: + if delay_counter == 0: + hd.test_configs.cmd_set_test_config(HDTestConfigOptions.TEST_CONFIG_EXPEDITE_PRE_TREATMENT.value) + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 10: + if delay_counter == 0: + hd.ui.cmd_set_treatment_parameters() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 11: + if delay_counter == 0: + hd.ui.cmd_ui_confirm_treatment_parameters(1) + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 12: + if delay_counter == 0: + hd.ui.cmd_ui_uf_volume_set(0.0) + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + elif counter == 13: + if delay_counter == 0: + hd.switches.cmd_hd_switch_status_override(HDSwitchesNames.FRONT_DOOR.value, HDSwitchStatus.OPEN.value) + + counter, delay_counter = check_status(delay_counter, sleep_time, 2, counter) + + elif counter == 14: + if delay_counter == 0: + hd.switches.cmd_hd_switch_status_override(HDSwitchesNames.FRONT_DOOR.value, HDSwitchStatus.OPEN.value, + RESET) + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + if counter == 15: + if delay_counter == 0: + hd.ui.cmd_ui_patient_connection_confirm() + + counter, delay_counter = check_status(delay_counter, sleep_time, 2, counter) + + if counter == 16: + if delay_counter == 0: + hd.ui.cmd_ui_start_treatment_request() + + counter, delay_counter = check_status(delay_counter, sleep_time, target_delay, counter) + + sleep(sleep_time) + + +if __name__ == "__main__": + dg = DG(log_level='DEBUG') + dg.cmd_log_in_to_dg() + sleep(1) + hd = HD(log_level='DEBUG') + hd.cmd_log_in_to_hd() + sleep(1) + + #expedite_pretreatment() + + recover_treatment() + Index: tests/depreciated_tests/test_uf.py =================================================================== diff -u --- tests/depreciated_tests/test_uf.py (revision 0) +++ tests/depreciated_tests/test_uf.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,113 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_uf.py +# +# @author (last) Sean Nash +# @date (last) 24-Sep-2022 +# @author (original) Peter Lucia +# @date (original) 14-Jul-2020 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from dialin.dg.dialysate_generator import DG +from dialin.hd.valves import ValvesEnum +from dialin.dg.temperatures import DGTemperaturesNames +from time import sleep + +from leahi_dialin.td.treatment_delivery import TD +#from leahi_dialin.dd.dialysate_delivery import DD +#from leahi_dialin.fp.reverse_osmosis import RO + +from leahi_dialin.td.modules.valves import ValvesEnum + +if __name__ == "__main__": + # create an TD object called td + td = TD(log_level="DEBUG") + # create a DD object called dd +# dd = DD(log_level="DEBUG") + # create a RO object called fp +# fp = RO(log_level="DEBUG") + sleep(2) + +# hd.ui.cmd_ui_start_treatment_request() +# exit(0) + + # log in to HD and DG as tester +# if hd.cmd_log_in_to_hd() == 0: +# exit(1) +# if fp.cmd_log_in_to_ro() == 0: +# exit(1) +# sleep(1) + +# hd.bloodflow.cmd_blood_flow_set_point_override(0) +# exit(1) + + # create log file + with open("UF_test.log", "w") as f: + + # collect UF related data from HD and DG + while True: + sleep(1) + modes = "TD.m, " + '{:2d}'.format(td.td_operation_mode) + \ + ", TD.s, " + '{:2d}'.format(td.td_operation_sub_mode) + # ", DD.m, " + '{:2d}'.format(dd.dd_operation_mode) + \ + # ", DD.s, " + '{:2d}'.format(dd.dd_operation_sub_mode) + pumpSetPts = ", BP.sf, " + '{:4d}'.format(td.blood_flow.set_blood_flow_rate) + \ + ", BP.ss, " + '{:9.2f}'.format(td.blood_flow.set_rpm) + # ", ROP.s, " + '{:9.2f}'.format(fp.ro_pump.TBD) + pumpMeasSpds = ", BP.m, " + '{:7.1f}'.format(td.blood_flow.measured_blood_pump_speed) + # ", BP.r, " + '{:6.1f}'.format(td.blood_flow.measured_blood_pump_rotor_speed) + \ + # ", BP.f, " + '{:7.1f}'.format(td.blood_flow.measured_blood_flow_rate) + press = ", PBA, " + '{:9.2f}'.format(td.pressure_sensors.arterial_pressure) + \ + ", PBV, " + '{:9.2f}'.format(td.pressure_sensors.venous_pressure) + # valves = ", VBA, " + td.valves.valves_status[ValvesEnum.VBA.name]["PosID"] + \ + # ", VBV, " + td.valves.valves_status[ValvesEnum.VBV.name]["PosID"] + # air = ", ADV, " + '{:1d}'.format(td.bubbles.air_bubbles_status) + \ + # ", ULBl, " + '{:1d}'.format(td.air_trap.lower_level) + \ + # ", ULBu, " + '{:1d}'.format(td.air_trap.upper_level) + \ + # ", AP, " + '{:1d}'.format(td.air_pump.air_pump_state) + \ + # ", VBT, " + '{:1d}'.format(td.air_trap.valve_state) + # alarms = ", AL.s, " + '{:1d}'.format(td.alarms.get_current_alarms_state()) + \ + # ", AL.t, " + '{:4d}'.format(td.alarms.alarm_top) + + # log data + f.write(modes) + f.write(loadCells) + f.write(ultraFilt) + f.write(valves) + f.write(pumpSetPts) + f.write(pumpMeasSpds) + f.write(pumpPWMs) + f.write(dgPress) + f.write(alarms) + f.write(accels) + f.write(hdPress) + f.write(Temps) + f.write(htrs) + f.write(air) + f.write("\n") + + # print to console + print(" Modes: "+modes) + print(" Load Cells: "+loadCells) + print("Ultrafiltration: "+ultraFilt) + print(" DG Valves: "+valves) + print("Pump Set Points: "+pumpSetPts) + print(" Pump Speeds: "+pumpMeasSpds) + print(" Pump PWMs/DACs: "+pumpPWMs) + print(" DG Pressures: "+dgPress) + print(" HD Pressures: "+hdPress) + print(" DG Heaters: "+htrs) + print(" Temperatures: "+Temps) + print(" Air: "+air) + print(" Accelerometer: "+accels) + print(" Alarms: "+alarms) + Index: tests/depreciated_tests/test_uv_reactors.py =================================================================== diff -u --- tests/depreciated_tests/test_uv_reactors.py (revision 0) +++ tests/depreciated_tests/test_uv_reactors.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,48 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_uv_reactors.py +# +# @author (last) Dara Navaei +# @date (last) 02-May-2021 +# @author (original) Dara Navaei +# @date (original) 27-Apr-2021 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.dg.dialysate_generator import DG +from dialin.dg.uv_reactors import ReactorsStates, ReactorsHealthStatus, ReactorsNames +from time import sleep + +dg = DG(log_level='DEBUG') +dg.cmd_log_in_to_dg() +sleep(1) + +#dg.uv_reactors.cmd_start_stop_inlet_uv_reactor(ReactorsStates.UV_REACTOR_STATE_ON.value) +dg.uv_reactors.cmd_start_stop_outlet_uv_reactor(ReactorsStates.UV_REACTOR_STATE_ON.value) + +#dg.uv_reactors.cmd_uv_reactors_health_override(ReactorsNames.INLET_UV_REACTOR.value, +# ReactorsHealthStatus.UV_REACTOR_NOT_HEALTHY.value, reset=1) + +while True: + try: + sleep(1) + print('Inlet_health, {}, Inlet_state, {}, Outlet_health, {}, Outlet_health, {}'. + format(dg.uv_reactors.inlet_uv_reactor_state, + ReactorsHealthStatus(dg.uv_reactors.inlet_uv_reactor_health).name, + dg.uv_reactors.outlet_uv_reactor_state, + ReactorsHealthStatus(dg.uv_reactors.outlet_uv_reactor_health).name)) + + except KeyboardInterrupt: + dg.uv_reactors.cmd_start_stop_inlet_uv_reactor(ReactorsStates.UV_REACTOR_STATE_OFF.name) + dg.uv_reactors.cmd_start_stop_outlet_uv_reactor(ReactorsStates.UV_REACTOR_STATE_OFF.name) + dg.uv_reactors.cmd_uv_reactors_health_override(ReactorsNames.OUTLET_UV_REACTOR.value, + ReactorsHealthStatus.UV_REACTOR_NOT_HEALTHY.value, reset=1) + break + Index: tests/depreciated_tests/test_voltages.py =================================================================== diff -u --- tests/depreciated_tests/test_voltages.py (revision 0) +++ tests/depreciated_tests/test_voltages.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,98 @@ +########################################################################### +# +# Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_voltages.py +# +# @author (last) Sean Nash +# @date (last) 23-Jul-2021 +# @author (original) Sean Nash +# @date (original) 16-Apr-2021 +# +############################################################################ + +import sys +sys.path.append("..") +from dialin.hd.hemodialysis_device import HD +from dialin.dg.dialysate_generator import DG +from time import sleep +from dialin.hd.voltages import HDMonitoredVoltages +from dialin.dg.voltages import DGMonitoredVoltages +from dialin.hd.constants import NO_RESET + +if __name__ == "__main__": + # create an HD object called hd + hd = HD() + dg = DG() + + # log in to HD and DG as tester +# if hd.cmd_log_in_to_hd() == 0: +# print("Failed to log into HD.") +# exit(1) +# if dg.cmd_log_in_to_dg() == 0: +# print("Failed to log into DG.") +# exit(1) +# sleep(0.1) + +# hd.rtc.cmd_set_rtc_time_and_date(0,0,9,7,5,2021) +# exit(1) + + # override alarms/voltages broadcast interval to 50 ms + hd.voltages.cmd_monitored_voltages_broadcast_interval_override(50,NO_RESET) + hd.alarms.cmd_alarm_info_broadcast_interval_override(50,NO_RESET) + + x = 0 + + # create log file + with open("/home/fw/projects/leahi_dialin/tests/v_test.log", "w") as f: + # write column header labels to log file + header = "HD1.2V, HD3.3V, HD5V Logic, HD5V Sensors, HD24V, HD24V Regen, HDFPGA RefV, HDPBA RefV, HDAlmCurrHg, HDAlmCurrLg, HDAlmBckpCurr," + \ + "DG1V FPGA, DG1.2V, DG1.8V Proc, DG1.8V FPGA, DGVRef, DGRef1, DGRef2, DG3.3V, DG3.3V Sensors, DG5V Logic, DG5V Sensors, DG5V P/S Gate Drvr, DG24V, DG24V Htr, DG24V Trim\n" + f.write(header) + + # write monitored voltages related data from HD to log file + while True: + x = x + 1 +# if x == 40: +# hd.alarms.cmd_alarm_backup_audio_current_override(0.0,NO_RESET) +# if x == 80: +# hd.watchdog.cmd_watchdog_task_check_in_override(0,1,NO_RESET) + vHd = hd.voltages.get_monitored_voltages() + vDg = dg.voltages.get_monitored_voltages() + hdVoltageData = '{:11.6f}'.format(vHd[HDMonitoredVoltages.MONITORED_LINE_1_2V.value]) + \ + ", " + '{:11.6f}'.format(vHd[HDMonitoredVoltages.MONITORED_LINE_3_3V.value]) + \ + ", " + '{:11.6f}'.format(vHd[HDMonitoredVoltages.MONITORED_LINE_5V_LOGIC.value]) + \ + ", " + '{:11.6f}'.format(vHd[HDMonitoredVoltages.MONITORED_LINE_5V_SENSORS.value]) + \ + ", " + '{:11.6f}'.format(vHd[HDMonitoredVoltages.MONITORED_LINE_24V.value]) + \ + ", " + '{:11.6f}'.format(vHd[HDMonitoredVoltages.MONITORED_LINE_24V_REGEN.value]) + \ + ", " + '{:11.6f}'.format(vHd[HDMonitoredVoltages.MONITORED_LINE_FPGA_REF_V.value]) + \ + ", " + '{:11.6f}'.format(vHd[HDMonitoredVoltages.MONITORED_LINE_PBA_REF_V.value]) + \ + ", " + '{:11.6f}'.format(hd.alarms.alarm_audio_curr_hg) + \ + ", " + '{:11.6f}'.format(hd.alarms.alarm_audio_curr_lg) + \ + ", " + '{:11.6f}'.format(hd.alarms.alarm_backup_audio_curr) + dgVoltageData = ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_1V_FPGA.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_1_2V_PROC.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_1_8V_PROC.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_1_8V_FPGA.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_V_REF.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_EXT_ADC_1_REF_V.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_EXT_ADC_2_REF_V.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_3_3V.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_3_3V_SENSORS.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_5V_LOGIC.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_5V_SENSORS.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_PS_GATE_DRIVER_V.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_24V_MAIN.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_24V_PRIM_HTR_V.value]) + \ + ", " + '{:11.6f}'.format(vDg[DGMonitoredVoltages.MONITORED_LINE_24V_TRIM_HTR_V.value]) + sleep(0.05) + + # log data + f.write(hdVoltageData+dgVoltageData+"\n") + + # print to console + print(hdVoltageData) + print(dgVoltageData) Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/dg_hd_switches_test.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/dg_heaters_test.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/dg_nvm_scripts.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/dg_tests.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/dg_valves_test.py'. Fisheye: No comparison available. Pass `N' to diff? Index: tests/fp_dianogistic_logger.py =================================================================== diff -u --- tests/fp_dianogistic_logger.py (revision 0) +++ tests/fp_dianogistic_logger.py (revision 68422d08c4141999a13496343264483a32314d37) @@ -0,0 +1,106 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_uf.py +# +# @author (last) Sean Nash +# @date (last) 24-Sep-2022 +# @author (original) Peter Lucia +# @date (original) 14-Jul-2020 +# +############################################################################ + +import sys +sys.path.append("..") +import threading +from time import sleep +from tests.data_capture_helpers.fp_helpers import fp_float_controller, fp_pressure_recorder, fp_temperature_recorder, \ +fp_level_recorder, fp_flow_recorder, fp_conductivity_recorder, fp_valve_recorder, fp_ro_pump_recorder, fp_boost_pump_recorder, \ +fp_op_mode_recorder, fp_combine_logs, fp_log_setup +from leahi_dialin.fp.filtration_purification import FP + +RECORDING_INTERVAL = 0.25 +RECORDING_INTERVAL_IN_MS = int(RECORDING_INTERVAL * 1000) +CONTROL_INTERVAL = 0.5 + +def set_broadcast_overrides(fp:FP, interval = RECORDING_INTERVAL_IN_MS): + fp.boost_pump.cmd_boost_pump_broadcast_interval_override(interval) + fp.conductivity.cmd_conductivity_sensor_data_broadcast_interval_override(interval) + fp.flows.cmd_flow_sensor_broadcast_interval_override(interval) + fp.levels.cmd_levels_broadcast_interval_override(interval) + fp.pressures.cmd_pressure_sensors_broadcast_interval_override(interval) + fp.ro_pump.cmd_ro_pump_broadcast_interval_override(interval) + fp.temperatures.cmd_temperatures_data_broadcast_interval_override(interval) + fp.valves.cmd_valve_broadcast_interval_override(interval) + fp.cmd_op_mode_broadcast_interval_override(interval) + +def reset_broadcast_overrides(fp:FP): + fp.boost_pump.cmd_boost_pump_broadcast_interval_override(0, 1) + fp.conductivity.cmd_conductivity_sensor_data_broadcast_interval_override(0, 1) + fp.flows.cmd_flow_sensor_broadcast_interval_override(0, 1) + fp.levels.cmd_levels_broadcast_interval_override(0, 1) + fp.pressures.cmd_pressure_sensors_broadcast_interval_override(0, 1) + fp.ro_pump.cmd_ro_pump_broadcast_interval_override(0, 1) + fp.temperatures.cmd_temperatures_data_broadcast_interval_override(0, 1) + fp.valves.cmd_valve_broadcast_interval_override(0, 1) + fp.cmd_op_mode_broadcast_interval_override(0,1) + +if __name__ == "__main__": + try: + # create a FP object called fp + fp = FP(log_level="DEBUG") + + # log in to fp as a tester + if fp.cmd_log_in_to_fp() == 0: + print ("Failed to log into FP") + exit(1) + print( "Sending broadcast overrides.. ") + set_broadcast_overrides(fp) + fp_log_setup() + + print ("Starting threads...") + float_control_thread = threading.Thread(target=fp_float_controller, args=(fp, CONTROL_INTERVAL),daemon=True) + #float_control_thread.start() + + pressure_log_writer_thread = threading.Thread(target=fp_pressure_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + temp_log_writer_thread = threading.Thread(target=fp_temperature_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + level_log_writer_thread = threading.Thread(target=fp_level_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + flows_log_writer_thread = threading.Thread(target=fp_flow_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + conductivity_log_writer_thread = threading.Thread(target=fp_conductivity_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + valve_log_writer_thread = threading.Thread(target=fp_valve_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + ro_log_writer_thread = threading.Thread(target=fp_ro_pump_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + boost_log_writer_thread = threading.Thread(target=fp_boost_pump_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + opmode_log_writer_thread = threading.Thread(target=fp_op_mode_recorder, args=(fp, RECORDING_INTERVAL), daemon=True) + + pressure_log_writer_thread.start() + temp_log_writer_thread.start() + level_log_writer_thread.start() + flows_log_writer_thread.start() + conductivity_log_writer_thread.start() + valve_log_writer_thread.start() + ro_log_writer_thread.start() + boost_log_writer_thread.start() + opmode_log_writer_thread.start() + + while True: + sleep(1) + except KeyboardInterrupt: + print("Stopping.") + reset_broadcast_overrides(fp) + + + finally: + print("Creating log...") + fp_combine_logs() + + print("Exiting") + exit(0) + + + + + Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/hd_air_bubbles_data.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/hd_blood_leak_data.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/hd_fluid_leak_state.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/hd_nvm_scripts.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/hd_test_pumps_open_loop.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/hd_valves_test.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/set_accels_cal.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/set_flow_sensors_cal.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_alarms.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_buttons.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_can_xmit.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_conductivity.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_deprime.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_dg_records.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_dg_valves.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_dialysate_flow_sensor.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_flush.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_hd.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_hd_dg_fans.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_hd_records.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_hd_valves.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_heparin.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_heprin_bolus_target_rate.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_lc.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_nelson_labs_disinfect.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_ro.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_saline_bolus.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_syringe.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_tx_config_tests.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_uf.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_uv_reactors.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 68422d08c4141999a13496343264483a32314d37 refers to a dead (removed) revision in file `tests/test_voltages.py'. Fisheye: No comparison available. Pass `N' to diff?