Index: dialin/common/dg_defs.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- dialin/common/dg_defs.py (.../dg_defs.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ dialin/common/dg_defs.py (.../dg_defs.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -263,10 +263,20 @@ @unique class DGEventList(DialinEnum): - DG_EVENT_STARTUP = 0 - DG_EVENT_OP_MODE_CHANGE = 1 - DG_EVENT_SUB_MODE_CHANGE = 2 - NUM_OF_DG_EVENT_IDS = 3 + DG_EVENT_STARTUP = 0 # DG startup event + DG_EVENT_OP_MODE_CHANGE = 1 # DG Op mode change event + DG_EVENT_SUB_MODE_CHANGE = 2 # DG Op sub-mode change event + DG_EVENT_CONCENTRATE_CAP_SWITCH_CHANGE = 3 # DG concentrate cap switch change + DG_EVENT_DIALYSATE_CAP_SWITCH_CHANGE = 4 # DG dialysate cap switch change + DG_EVENT_CPU_RAM_ERROR_STATUS = 5 # DG processor RAM error + DG_EVENT_CAL_RECORD_UPDATE = 6 # DG new calibration record updated + DG_EVENT_SYSTEM_RECORD_UPDATE = 7 # DG new system record has been updated + DG_EVENT_SERVICE_UPDATE = 8 # DG new service record has been updated + DG_EVENT_USAGE_INFO_UPDATE = 9 # DG new usage information has been updated + DG_EVENT_SW_CONFIG_UPDATE = 10 # DG new software configuration has been updated + DG_EVENT_SCHEDULED_RUNS_UPDATE = 11 # DG new scheduled runs information has been updated + DG_EVENT_HEATERS_INFO_UPDATE = 12 # DG new heaters information has been updated + NUM_OF_DG_EVENT_IDS = 13 # Total number of DG events @unique Index: dialin/common/hd_defs.py =================================================================== diff -u -rfaeb2ee05cafdcdb5008b2c10f65713646a217f0 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- dialin/common/hd_defs.py (.../hd_defs.py) (revision faeb2ee05cafdcdb5008b2c10f65713646a217f0) +++ dialin/common/hd_defs.py (.../hd_defs.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -49,32 +49,31 @@ @unique class HDInitStates(DialinEnum): - POST_STATE_START = 0 # Start initialize & POST mode state - POST_STATE_FW_INTEGRITY = 1 # Run firmware integrity test state - POST_STATE_AC = 2 # Check HD has AC power - power off if not - POST_STATE_WATCHDOG = 3 # Run watchdog test state - POST_STATE_SAFETY_SHUTDOWN = 4 # Run safety shutdown test state - POST_STATE_RTC = 5 # Run RTC test state - POST_STATE_NVDATAMGMT = 6 # Run NV Data Mgmt. test state - POST_STATE_BLOOD_FLOW = 7 # Run blood flow test state - POST_STATE_DIALYSATE_INLET_FLOW = 8 # Run dialysate inlet flow test state - POST_STATE_DIALYSATE_OUTLET_FLOW = 9 # Run dialysate outlet flow test state - POST_STATE_BLOOD_LEAK = 10 # Run blood leak sensor test state - POST_STATE_VALVES = 11 # Run valves test state - POST_STATE_SYRINGE_PUMP = 12 # Run syringe pump test state - POST_STATE_PRES_OCCL = 13 # Run pressure occlusion state - POST_STATE_ALARM_AUDIO = 14 # Run alarm audio test state - POST_STATE_ALARM_LAMP = 15 # Run alarm lamp test state - POST_STATE_ACCELEROMETER = 16 # Run Accelerometer test state - POST_STATE_TEMPERATURES = 17 # Run temperatures POST state - POST_STATE_FANS = 18 # Run fans POST state - POST_STATE_STUCK_BUTTON = 19 # Run stuck button test state - POST_STATE_UI_POST = 20 # Check whether UI passed its POST tests - POST_STATE_FW_COMPATIBILITY = 21 # Run firmware compatibility test state - POST_STATE_FPGA = 22 # Run FPGA test state - POST_STATE_COMPLETED = 23 # POST self-tests completed state - POST_STATE_FAILED = 24 # POST self-tests failed state - NUM_OF_POST_STATES = 25 # Number of initialize & POST mode states + POST_STATE_START = 0 # Start initialize & POST mode state + POST_STATE_FW_INTEGRITY = 1 # Run firmware integrity test state + POST_STATE_RTC = 2 # Run RTC test state + POST_STATE_NVDATAMGMT = 3 # Run NV Data Mgmt. test state + POST_STATE_WATCHDOG = 4 # Run watchdog test state + POST_STATE_SAFETY_SHUTDOWN = 5 # Run safety shutdown test state + POST_STATE_BLOOD_FLOW = 6 # Run blood flow test state + POST_STATE_DIALYSATE_INLET_FLOW = 7 # Run dialysate inlet flow test state + POST_STATE_DIALYSATE_OUTLET_FLOW = 8 # Run dialysate outlet flow test state + POST_STATE_BLOOD_LEAK = 9 # Run blood leak sensor test state + POST_STATE_VALVES = 10 # Run valves test state + POST_STATE_SYRINGE_PUMP = 11 # Run syringe pump test state + POST_STATE_PRES_OCCL = 12 # Run pressure occlusion state + POST_STATE_ALARM_AUDIO = 13 # Run alarm audio test state + POST_STATE_ALARM_LAMP = 14 # Run alarm lamp test state + POST_STATE_ACCELEROMETER = 15 # Run Accelerometer test state + POST_STATE_TEMPERATURES = 16 # Run temperatures POST state + POST_STATE_FANS = 17 # Run fans POST state + POST_STATE_STUCK_BUTTON = 18 # Run stuck button test state + POST_STATE_UI_POST = 19 # Check whether UI passed its POST tests + POST_STATE_FW_COMPATIBILITY = 20 # Run firmware compatibility test state + POST_STATE_FPGA = 21 # Run FPGA test state + POST_STATE_COMPLETED = 22 # POST self-tests completed state + POST_STATE_FAILED = 23 # POST self-tests failed state + NUM_OF_POST_STATES = 24 # Number of initialize & POST mode states @unique class PreTreatmentSubModes(DialinEnum): @@ -332,7 +331,22 @@ HD_EVENT_STARTUP = 0 # HD startup event HD_EVENT_OP_MODE_CHANGE = 1 # HD Op mode change event HD_EVENT_SUB_MODE_CHANGE = 2 # HD Op sub-mode change event - NUM_OF_EVENT_IDS = 3 # Total number of HD events + HD_EVENT_DRY_SELF_TEST_CARTRIDGE_RESULT = 3 # HD dry self test cartridge result + HD_EVENT_DRY_SELF_TEST_PRESSURE_RESULT = 4 # HD dry self test pressure result + HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT = 5 # HD wet self test displacement result + HD_EVENT_CPU_RAM_ERROR_STATUS = 6 # HD CPU RAM error status + HD_EVENT_CAL_RECORD_UPDATE = 7 # HD new calibration record updated + HD_EVENT_SYSTEM_RECORD_UPDATE = 8 # HD new system record has been updated + HD_EVENT_SERVICE_UPDATE = 9 # HD new service record has been updated + HD_EVENT_USAGE_INFO_UPDATE = 10 # HD new usage information has been updated + HD_EVENT_SW_CONFIG_UPDATE = 11 # HD new software configuration has been updated + HD_EVENT_BUTTON = 12 # HD button pressed/released + HD_EVENT_SAFETY_LINE = 13 # HD safety line pulled/released + HD_EVENT_RSRVR_1_LOAD_CELL_START_VALUES = 14 # HD reservoir 1 load cells start values + HD_EVENT_RSRVR_1_LOAD_CELL_END_VALUES = 15 # HD reservoir 2 load cells end values + HD_EVENT_RSRVR_2_LOAD_CELL_START_VALUES = 16 # HD reservoir 2 load cells start values + HD_EVENT_RSRVR_2_LOAD_CELL_END_VALUES = 17 # HD reservoir 2 load cells end values + NUM_OF_EVENT_IDS = 18 # Total number of HD events @unique Index: dialin/common/msg_ids.py =================================================================== diff -u -r171cfe518f3441e140b2995fbaa790d322697b38 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- dialin/common/msg_ids.py (.../msg_ids.py) (revision 171cfe518f3441e140b2995fbaa790d322697b38) +++ dialin/common/msg_ids.py (.../msg_ids.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -1,14 +1,14 @@ ########################################################################### # -# Copyright (c) 2021-2022 Diality Inc. - All Rights Reserved. +# Copyright (c) 2021-2023 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 msg_ids.py # # @author (last) Dara Navaei -# @date (last) 21-Dec-2022 +# @date (last) 03-Jan-2023 # @author (original) Peter Lucia # @date (original) 06-Apr-2021 # @@ -195,7 +195,7 @@ MSG_ID_DG_SET_SERVICE_TIME = 0xAC MSG_ID_UI_INSTALLATION_CONFIRM_RESPONSE = 0xAD MSG_ID_DG_FILL_MODE_DATA = 0xAE - MSG_ID_DG_BAD_FILL_SUB_STATE = 0xAF + MSG_ID_DG_GEN_IDLE_DATA = 0xAF MSG_ID_UI_REQUEST_SERVICE_MODE = 0xB0 MSG_ID_HD_RESPONSE_SERVICE_MODE_REQUEST = 0xB1 MSG_ID_HD_REQUEST_UI_FINAL_POST_RESULT = 0xB2 @@ -219,6 +219,7 @@ MSG_ID_HD_CHEM_DISINFECT_FLUSH_CONFIRM_RESPONSE = 0xC4 MSG_ID_DG_HEAT_DISINFECT_ACTIVE_COOL_DATA = 0xC5 MSG_ID_DG_START_STOP_HEAT_DISINFECT_ACTIVE_COOL = 0xC6 + MSG_ID_HD_AIR_PUMP_DATA = 0xC7 MSG_ID_CAN_ERROR_COUNT = 0x999 @@ -249,7 +250,7 @@ MSG_ID_PRESSURE_VENOUS_OVERRIDE = 0x8018 MSG_ID_OCCLUSION_BLOOD_PUMP_OVERRIDE = 0x8019 MSG_ID_BLOOD_PUMP_ROTOR_COUNT_OVERRIDE = 0x801A - MSG_ID____AVAILABLE_11 = 0x801B + MSG_ID_HD_AIR_PUMP_SET_STATE = 0x801B MSG_ID_PRES_OCCL_SEND_INTERVAL_OVERRIDE = 0x801C MSG_ID_SET_RTC_DATE_TIME = 0x801D MSG_ID_DIAL_OUT_FLOW_SEND_INTERVAL_OVERRIDE = 0x801E @@ -440,7 +441,7 @@ MSG_ID_DG_SET_FANS_RPM_ALARM_START_TIME_OFFSET = 0xA04F MSG_ID_DG_USED_BICARB_VOLUME_ML_OVERRIDE = 0xA050 MSG_ID_FILL_MODE_DATA_PUBLISH_INTERVAL_OVERRIDE = 0xA051 - MSG_ID_BAD_FILL_STATES_PUBLISH_INTERVAL_OVERRIDE = 0xA052 + MSG_ID_DG_GEN_IDLE_PUBLISH_INTERVAL_OVERRIDE = 0xA052 MSG_ID_DG_GET_USAGE_INFO_RECORD = 0xA053 MSG_ID_DG_SET_USAGE_INFO_RECORD = 0xA054 MSG_ID_DG_SEND_USAGE_INFO_RECORD = 0xA055 Index: dialin/dg/drain_pump.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- dialin/dg/drain_pump.py (.../drain_pump.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ dialin/dg/drain_pump.py (.../drain_pump.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -57,7 +57,7 @@ self.dac_value = 0 self.drain_pump_state = 0 self.current_drain_pump_rpm = 0 - self.target_drain_pump_outlet_pressure = 0.0 + self.target_drain_pump_outlet_flow_lpm = 0.0 self.drain_pump_current_A = 0.0 self.drain_pump_direction = 0 @@ -94,7 +94,7 @@ return self.current_drain_pump_rpm @publish(["target_drain_pump_rpm", "dac_value", "drain_pump_state", "current_drain_pump_rpm", - "drain_pump_current_A", "drain_pump_direction"]) + "drain_pump_current_A", "drain_pump_direction", "target_drain_pump_outlet_flow_lpm"]) def _handler_drain_pump_sync(self, message): """ Handles published drain pump data messages. Drain pump data are captured @@ -111,39 +111,39 @@ message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] self.current_drain_pump_rpm = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] - self.target_drain_pump_outlet_pressure = struct.unpack('f', bytearray( + self.target_drain_pump_outlet_flow_lpm = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] self.drain_pump_current_A = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] self.drain_pump_direction = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] - def cmd_drain_pump_set_outlet_target_pressure(self, pressure: float) -> int: + def cmd_drain_pump_set_outlet_target_flow_lpm(self, flow: float) -> int: """ - Constructs and sends the drain pump target outlet pressure command + Constructs and sends the drain pump target outlet flow in L/min Constraints: Must be logged into DG. - @param pressure: (float) target outlet pressure + @param flow: (float) target outlet flow in L/min @return: 1 if successful, zero otherwise """ - prssr = float_to_bytearray(pressure) - payload = prssr + flw = float_to_bytearray(flow) + payload = flw message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, - message_id=MsgIds.MSG_ID_DRAIN_PUMP_TARGET_OUTLET_PRESSURE.value, + message_id=MsgIds.MSG_ID_DRAIN_PUMP_TARGET_OUTLET_FLOW.value, payload=payload) - self.logger.debug("Setting drain pump target pressure") + self.logger.debug("Setting drain pump target flow") # Send message received_message = self.can_interface.send(message) # If there is no content... if received_message is not None: - self.logger.debug("Drain pump outlet pressure set to " + str(pressure) + " psi" + + self.logger.debug("Drain pump outlet flow set to " + str(flow) + " L/min" + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] Index: dialin/dg/fluid_leak.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- dialin/dg/fluid_leak.py (.../fluid_leak.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ dialin/dg/fluid_leak.py (.../fluid_leak.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -75,20 +75,20 @@ self.fluid_leak_state = state[0] - def cmd_fluid_leak_detector_override(self, detected: int, reset: int = NO_RESET) -> int: + def cmd_fluid_leak_detector_override(self, detected_state: int, reset: int = NO_RESET) -> int: """ Constructs and sends the fluid leak detector state override command Constraints: Must be logged into DG. Given detector must be one of the detectors listed below. - @param detected: unsigned int - detected (0=wet, 1=dry) to override detector with + @param detected_state: unsigned int - detected (0=wet, 1=dry) to override detector with @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ rst = integer_to_bytearray(reset) - det = integer_to_bytearray(detected) + det = integer_to_bytearray(detected_state) payload = rst + det message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, Index: dialin/dg/heaters.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- dialin/dg/heaters.py (.../heaters.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ dialin/dg/heaters.py (.../heaters.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -34,12 +34,22 @@ @unique class HeatersState(DialinEnum): - HEATER_EXEC_STATE_OFF = 0 - HEATER_EXEC_STATE_RAMP_UP_TO_TARGET = 1 - HEATER_EXEC_STATE_CONTROL_TO_TARGET = 2 + HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET = 1 + HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET = 2 + HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGE = 3 + HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET = 4 + HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET = 5 + NUM_OF_HEATERS_STATE = 6 +@unique +class HeatersNames(DialinEnum): + DG_PRIMARY_HEATER = 0 + DG_TRIMMER_HEATER = 1 + NUM_OF_DG_HEATERS = 2 + + class Heaters(AbstractSubSystem): """ @@ -237,6 +247,37 @@ trimmer_target_temp)) self.can_interface.send(message, 0) + def cmd_heater_duty_cycle_override(self, heater: int, duty_cycle: float, reset: int = NO_RESET) -> int: + """ + Constructs and sends heater duty cycle override command + Must be logged into DG + There must be a minimum flow available for the heaters (FMP for primary and FMD for trimmer) + + @param heater the heater to override its value (primary, trimmer) + @param duty_cycle the duty cycle value to override in percent + @param reset: (int) 1 to reset a previous override, 0 to override + @returns 1 if successful, zero otherwise + """ + reset_value = integer_to_bytearray(reset) + heater_name = integer_to_bytearray(heater) + duty = float_to_bytearray(duty_cycle/100) + payload = reset_value + heater_name + duty + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=MsgIds.MSG_ID_DG_HEATERS_DUTY_CYCLE_OVERRIDE.value, + payload=payload) + + self.logger.debug("Overriding {} heater's duty cycle to {:5.3f} %".format(HeatersNames(heater).name, duty_cycle)) + # Send message + received_message = self.can_interface.send(message) + + # If there is content in message + if received_message is not None: + # Response payload is OK or not + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + def cmd_heaters_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends broadcast time interval. @@ -270,3 +311,5 @@ else: self.logger.debug("Timeout!!!!") return False + + Index: dialin/hd/blood_leak.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- dialin/hd/blood_leak.py (.../blood_leak.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ dialin/hd/blood_leak.py (.../blood_leak.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -30,38 +30,26 @@ class EmbModeCommands(DialinEnum): NU = 0 # NULL command CS = 1 # Control S command (this is handled automatically by using the embedded mode command) - SP = 2 # Set point command - T = 3 - G = 4 - I = 5 - V = 6 - Z = 7 - Q = 8 - D = 9 - C = 10 + SP = 2 # Set set point command + T = 3 # Self test command + G = 4 # Get self-test drive + I = 5 # Display intensity + V = 6 # Display blood detection level + Z = 7 # Zero command + Q = 8 # Zero confirm command + D = 9 # Display set point + C = 10 # Calibration command -class BloodLeakObserver(AbstractObserver): - """ +@unique +class BloodLeakStates(DialinEnum): + BLOOD_LEAK_WAIT_FOR_POST_STATE = 0 + BLOOD_LEAK_CHECK_SET_POINT_STATE = 1 + BLOOD_LEAK_INIT_STATE = 2 + BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE = 3 + BLOOD_LEAK_NORMAL_STATE = 4 - Observation class - """ - def __init__(self, prop): - self.received = False - self.prop = prop - - def update(self, message): - """ - Publicly accessible function to provide an update of the object that is being observed - - @param message: (str) the message to update its status - - @return none - """ - self.received = message.get(self.prop, False) - - class HDBloodLeak(AbstractSubSystem): """ HDBloodLeak @@ -73,12 +61,6 @@ BLOOD_LEAK_DETECTED = 0 # Blood detected NO_BLOOD_LEAK_DETECTED = 1 # No blood detected - # Blood leak detector state machine states - BLOOD_LEAK_INIT_STATE = 0 # Initial state - BLOOD_LEAK_ZERO_STATE = 1 # Zero state - BLOOD_LEAK_SELF_TEST_STATE = 2 # Self-test state - BLOOD_LEAK_NORMAL_STATE = 3 # Normal state - def __init__(self, can_interface, logger: Logger): """ @@ -100,13 +82,13 @@ self._handler_blood_leak_emb_mode_cmd_resp) self.blood_leak_status = self.NO_BLOOD_LEAK_DETECTED - self.blood_leak_state = self.BLOOD_LEAK_INIT_STATE - self.blood_leak_detect_set_point = 0 - self.blood_leak_detect_level = 0 - self.blood_leak_led_intensity = 0 - self.blood_leak_emb_mode_cmd_response = '' - self._is_emb_mode_command_in_progress = False + self.blood_leak_state = BloodLeakStates.BLOOD_LEAK_INIT_STATE.value + self.blood_leak_emb_mode_cmds = dict() + for cmd in EmbModeCommands.__members__: + # Initialize all the embedded mode commands + self.blood_leak_emb_mode_cmds[cmd] = '' + def get_blood_leak_status(self): """ Gets the current blood leak status @@ -123,59 +105,19 @@ """ return self.blood_leak_state - def get_blood_leak_detect_set_point(self): + def get_blood_leak_emb_mode_command_response(self, emb_mod_cmd: int) -> str: """ - Gets the current blood leak detect set point + Gets the most recent embedded mode command response for a given command - @return: integer - blood leak detect set point - """ - return self.blood_leak_detect_set_point + @param emb_mod_cmd the command to get its response - def get_blood_leak_detect_level(self): - """ - Gets the current blood leak detect level - - @return: integer - blood leak detect level - """ - return self.blood_leak_detect_level - - def get_blood_leak_led_intensity(self): - """ - Gets the current blood leak LED intensity - - @return: integer - blood leak LED intensity - """ - return self.blood_leak_led_intensity - - def get_blood_leak_emb_mode_command_response(self): - """ - Gets the embedded mode command response - @return: string - embedded mode command response """ - # Check if there has been a recent command sent to the firmware and then start an observer - # If there is no command sent and therefore, there is no pending response, the observer will hang - if self._is_emb_mode_command_in_progress is True: - # Create an object of the observer class to observe the response - observer = BloodLeakObserver("blood_leak_emb_mode_cmd_response") - # Attach the observer to the list - self.attach(observer) + if emb_mod_cmd < len(EmbModeCommands): + return self.blood_leak_emb_mode_cmds[EmbModeCommands(emb_mod_cmd).name] + else: + self.logger.debug("Invalid command!") - observer_sleep_time = 0.1 - observer_time_out = int(20 / observer_sleep_time) - observer_timer_counter = 0 - # Wait until data has been received from firmware - while not observer.received: - sleep(observer_sleep_time) - if observer_timer_counter >= observer_time_out: - print('Observer Timeout') - break - observer_timer_counter += 1 - # Done with receiving the response from the firmware - self._is_emb_mode_command_in_progress = False - - return self.blood_leak_emb_mode_cmd_response - @publish(['blood_leak_status', 'blood_leak_state']) def _handler_blood_leak_sync(self, message): """ @@ -200,7 +142,6 @@ @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) det = float_to_bytearray(detected) payload = rst + det @@ -302,7 +243,6 @@ # If there is content... if received_message is not None: - self._is_emb_mode_command_in_progress = True # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: @@ -314,10 +254,14 @@ Constructs and sends switching to embedded mode command Constraints: Must be logged into HD. + It is recommended to have delays in between sending each command to make sure the firmware's queue is not + overflown. + The sensor must be in embedded mode. The firmware sets the sensor into the embedded mode by default. @return: non-zero integer if successful, False otherwise """ command_bytes = byte_to_bytearray(command) + self.blood_leak_emb_mode_cmds[EmbModeCommands(command).name] = '' data = 0 if msg_payload is not None: @@ -335,7 +279,6 @@ # If there is content... if received_message is not None: - self._is_emb_mode_command_in_progress = True # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: @@ -352,12 +295,15 @@ @return: None """ # Clear the variable for the next read - self.blood_leak_emb_mode_cmd_response = '' + blood_leak_emb_mode_cmd_response = '' payload = message['message'] index = MsgFieldPositions.START_POS_FIELD_1 + cmd, index = bytearray_to_byte(payload, index, False) length, index = bytearray_to_integer(payload, index, False) for i in range(0, length): # Loop through the length and get the char, char_index = bytearray_to_byte(payload, index + i, False) - self.blood_leak_emb_mode_cmd_response += chr(char) + blood_leak_emb_mode_cmd_response += chr(char) + + self.blood_leak_emb_mode_cmds[EmbModeCommands(cmd).name] = blood_leak_emb_mode_cmd_response Index: dialin/hd/fluid_leak.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- dialin/hd/fluid_leak.py (.../fluid_leak.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ dialin/hd/fluid_leak.py (.../fluid_leak.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -75,20 +75,20 @@ self.fluid_leak_state = state[0] - def cmd_fluid_leak_detector_override(self, detected: int, reset: int = NO_RESET) -> int: + def cmd_fluid_leak_detector_override(self, detected_state: int, reset: int = NO_RESET) -> int: """ Constructs and sends the fluid leak detector state override command Constraints: Must be logged into HD. Given detector must be one of the detectors listed below. - @param detected: unsigned int - detected (0=wet, 1=dry) to override detector with + @param detected_state: unsigned int - detected (0=wet, 1=dry) to override detector with @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ rst = integer_to_bytearray(reset) - det = integer_to_bytearray(detected) + det = integer_to_bytearray(detected_state) payload = rst + det message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, Index: tests/dg_nvm_scripts.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- tests/dg_nvm_scripts.py (.../dg_nvm_scripts.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ tests/dg_nvm_scripts.py (.../dg_nvm_scripts.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -27,12 +27,12 @@ # 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 dialin folder wherever it is installed # in your computer. - dg.sw_configs.cmd_get_dg_sw_config_record() + #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/2022-11-29-DG-SW-CONFIGS-Record.xlsx') + dg.sw_configs.cmd_update_dg_sw_config_record('/home/fw/projects/DG_NV_Records/2022-12-28-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() @@ -49,12 +49,12 @@ # 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 dialin folder wherever it is installed # in you computer. - dg.calibration_record.cmd_get_dg_calibration_record_report() + #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/2022-10-06-DG-Record_betadvt2.xlsx') + dg.calibration_record.cmd_set_dg_calibration_excel_to_fw('/home/fw/projects/DG_NV_Records/2022-12-09-DG-Record-DVT-002.xlsx') # For resetting the calibration record to benign values, use the function below #dg.calibration_record.cmd_reset_dg_calibration_record() @@ -70,7 +70,7 @@ # 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/2022-12-19-DG-Record.xlsx') + dg.system_record.cmd_set_dg_system_record_excel_to_fw('/home/fw/projects/DG_NV_Records/2023-01-03-DG-Record.xlsx') # For resetting the system record to benign values, use the function below #dg.system_record.cmd_reset_dg_system_record() @@ -116,9 +116,9 @@ #run_calibration_commands() - #run_system_commands() + run_system_commands() - run_usage_info_commands() + #run_usage_info_commands() #run_service_commands() Index: tests/dg_tests.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- tests/dg_tests.py (.../dg_tests.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ tests/dg_tests.py (.../dg_tests.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -182,12 +182,12 @@ 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, {}, ' + '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.drain_pump_direction, dg.drain_pump.target_drain_pump_outlet_flow_lpm)) return info @@ -702,24 +702,24 @@ hd.cmd_log_in_to_hd() sleep(1) - #run_heat_disinfect() + run_heat_disinfect() #run_flush_mode() #run_chemical_disinfect() - run_chem_disinfect_flush_mode() + #run_chem_disinfect_flush_mode() #run_dg() # cmd_set_disinfect_ui_screen() - collect_treatment_data() + #collect_treatment_data() #collect_hd_treatment() #while True: - #print(get_hd_fans_info(), get_dg_fans_info(), get_temperature_sensors_info()) + # print(get_hd_fans_info(), get_dg_fans_info(), get_temperature_sensors_info()) # print(get_dg_valves_states()) # sleep(1) @@ -740,4 +740,7 @@ #hd.ui.cmd_ui_set_dg_service_time() + #dg.heaters.cmd_heater_duty_cycle_override(1, 10, reset=1) + #hd.cmd_hd_software_reset_request() + Index: tests/hd_blood_leak_data.py =================================================================== diff -u -racd09d02879e8add4cf7f694f5db8e423a76c341 -rffe7108e083bf2d9c34818a126f8c97ec9a21c1d --- tests/hd_blood_leak_data.py (.../hd_blood_leak_data.py) (revision acd09d02879e8add4cf7f694f5db8e423a76c341) +++ tests/hd_blood_leak_data.py (.../hd_blood_leak_data.py) (revision ffe7108e083bf2d9c34818a126f8c97ec9a21c1d) @@ -74,16 +74,19 @@ #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=0) - 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(get_blood_leak_info()) + #print(hd.blood_leak.blood_leak_emb_mode_cmds) sleep(1) + print(hd.blood_leak.get_blood_leak_emb_mode_command_response(6)) + """ while True: hd.blood_leak.cmd_blood_leak_set_embedded_mode_command(EmbModeCommands.I.value, msg_payload=125)