Index: dialin/common/msg_ids.py =================================================================== diff -u -r5fad1b021480de4d9708932bf3f68e27095c658f -r74da0b9125ce91e76ce824e4f8e520eb32ee8d84 --- dialin/common/msg_ids.py (.../msg_ids.py) (revision 5fad1b021480de4d9708932bf3f68e27095c658f) +++ dialin/common/msg_ids.py (.../msg_ids.py) (revision 74da0b9125ce91e76ce824e4f8e520eb32ee8d84) @@ -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 Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -r5fad1b021480de4d9708932bf3f68e27095c658f -r74da0b9125ce91e76ce824e4f8e520eb32ee8d84 --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 5fad1b021480de4d9708932bf3f68e27095c658f) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 74da0b9125ce91e76ce824e4f8e520eb32ee8d84) @@ -7,8 +7,8 @@ # # @file dialysate_generator.py # -# @author (last) Sean Nash -# @date (last) 21-Dec-2022 +# @author (last) Dara Navaei +# @date (last) 22-Dec-2022 # @author (original) Peter Lucia # @date (original) 02-Apr-2020 # Index: dialin/dg/heat_disinfect.py =================================================================== diff -u -rf8e8a2028269c7d914f30d28b6be993e74388534 -r74da0b9125ce91e76ce824e4f8e520eb32ee8d84 --- dialin/dg/heat_disinfect.py (.../heat_disinfect.py) (revision f8e8a2028269c7d914f30d28b6be993e74388534) +++ dialin/dg/heat_disinfect.py (.../heat_disinfect.py) (revision 74da0b9125ce91e76ce824e4f8e520eb32ee8d84) @@ -13,13 +13,14 @@ # @date (original) 27-Feb-2021 # ############################################################################ -import struct + from enum import unique from logging import Logger -from ..common.msg_defs import MsgIds, MsgFieldPositions -from ..protocols.CAN import DenaliChannels +from ..common.msg_defs import MsgIds +from ..protocols.CAN import DenaliChannels, DenaliMessage from ..utils.base import AbstractSubSystem, publish, DialinEnum +from ..utils.conversions import * @unique @@ -114,11 +115,12 @@ @param message: published heat disinfect UI data message @returns none """ - disinfect_target_time = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] - disinfect_count_down_time = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + payload = message['message'] + index = DenaliMessage.PAYLOAD_START_INDEX + disinfect_target_time, index = bytearray_to_integer(payload, index, False) + disinfect_count_down_time, index = bytearray_to_integer(payload, index, False) + self.heat_disinfect_target_time = int(disinfect_target_time / 1000) self.heat_disinfect_count_down_time = disinfect_count_down_time @@ -131,25 +133,93 @@ @param message: published heat disinfect data message @returns none """ - state = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] - elapsed_time = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] - state_elapsed_time = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] - cancellation_mode = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] - r1 = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] - r2 = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] - ui = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] + payload = message['message'] + index = DenaliMessage.PAYLOAD_START_INDEX + state, index = bytearray_to_integer(payload, index, False) + elapsed_time, index = bytearray_to_integer(payload, index, False) + state_elapsed_time, index = bytearray_to_integer(payload, index, False) + cancellation_mode, index = bytearray_to_integer(payload, index, False) + r1, index = bytearray_to_float(payload, index, False) + r2, index = bytearray_to_float(payload, index, False) + ui_state, index = bytearray_to_integer(payload, index, False) + self.heat_disinfect_state = state self.overall_elapsed_time = int(elapsed_time / 1000) self.state_elapsed_time = int(state_elapsed_time / 1000) self.cancellation_mode = cancellation_mode self.r1_level = r1 self.r2_level = r2 - self.heat_disinfect_ui_state = ui + self.heat_disinfect_ui_state = ui_state + + def get_heat_disinfect_state(self) -> int: + """ + Gets Heat Disinfection State + + @return: (int) + """ + return self.heat_disinfect_state + + def get_heat_disinfect_heat_disinfect_target_time(self) -> int: + """ + Gets Heat Disinfection target time + + @return: (int) + """ + return self.heat_disinfect_target_time + + def get_heat_disinfect_heat_disinfect_count_down_time(self) -> int: + """ + Gets Heat Disinfection count down time + + @return: (int) + """ + return self.heat_disinfect_count_down_time + + def get_heat_disinfect_overall_elapsed_time(self) -> int: + """ + Gets Heat Disinfection overall elapsed time + + @return: (int) + """ + return self.overall_elapsed_time + + def get_heat_disinfect_state_elapsed_time(self) -> int: + """ + Gets Heat Disinfection state elapsed time + + @return: (int) + """ + return self.heat_disinfect_target_time + + def get_heat_disinfect_cancellation_mode(self) -> int: + """ + Gets Heat Disinfection cancellation mode + + @return: (int) + """ + return self.cancellation_mode + + def get_heat_disinfect_r1_level(self) -> int: + """ + Gets Heat Disinfection r1 level + + @return: (int) + """ + return self.r1_level + + def get_heat_disinfect_r2_level(self) -> int: + """ + Gets Heat Disinfection r2 level + + @return: (int) + """ + return self.r2_level + + def get_heat_disinfect_heat_disinfect_ui_state(self) -> int: + """ + Gets Heat Disinfection UI state + + @return: (int) + """ + return self.heat_disinfect_state Index: dialin/hd/alarms.py =================================================================== diff -u -rf8e8a2028269c7d914f30d28b6be993e74388534 -r74da0b9125ce91e76ce824e4f8e520eb32ee8d84 --- dialin/hd/alarms.py (.../alarms.py) (revision f8e8a2028269c7d914f30d28b6be993e74388534) +++ dialin/hd/alarms.py (.../alarms.py) (revision 74da0b9125ce91e76ce824e4f8e520eb32ee8d84) @@ -40,7 +40,7 @@ HD_ALARM_LAMP_PATTERN_LOW = 5 HD_ALARM_LAMP_PATTERN_MANUAL = 6 - # Alarm states + # Alarm priority states HD_ALARM_STATE_NONE = 0 HD_ALARM_STATE_LOW = 1 HD_ALARM_STATE_MEDIUM = 2 @@ -122,7 +122,7 @@ self.alarm_table_button_blockers = [False] * self.AlarmResponseButtons.NUM_OF_HD_ALARM_RESPONSE_BUTTONS.value self.alarm_state_button_blockers = [False] * self.AlarmResponseButtons.NUM_OF_HD_ALARM_RESPONSE_BUTTONS.value - def get_current_alarms_state(self): + def get_current_alarm_priority(self): """ Gets the current alarms state. @@ -184,17 +184,17 @@ def get_alarm_rank(self, alarm_id): """ - Gets alarm rank for given alarm. + Gets alarm rank for given alarm @return: Alarm rank """ return self.alarm_ranks[alarm_id] def get_alarm_clear_top_only(self, alarm_id): """ - Gets alarm "clear top only" property for given alarm. + Gets clear top only property for given alarm - @return: T/F + @return: Clear top only property (T/F) """ return self.alarm_clear_top_only_flags[alarm_id] @@ -345,6 +345,30 @@ """ return (self.alarms_flags & 64) > 0 + def get_alarm_flag_okay_button_only(self) -> bool: + """ + Gets the alarm flag Ok button only. + + @return: (bool) Alarm flag Ok button only (T/F) + """ + return (self.alarms_flags & 128) > 0 + + def get_alarm_flag_alarm_to_escalate(self) -> bool: + """ + Gets the alarm flag to escalate. + + @return: (bool) Alarm flag indicating an active alarm is due to escalate (T/F) + """ + return (self.alarms_flags & 256) > 0 + + def get_alarm_flag_is_alarm_silenced(self) -> bool: + """ + Gets the alarm flag alarm silence + + @return: (bool) Alarm flag indicating alarms are currently silenced (T/F) + """ + return (self.alarms_flags & 512) > 0 + def get_alarm_flag_lamp_on(self) -> bool: """ Gets the alarm flag lamp on. @@ -377,6 +401,15 @@ """ return (self.alarms_flags & 16384) > 0 + def get_alarm_flag_top_condition(self) -> bool: + """ + Gets the alarm flag top condition. + + @return: (bool) Top Alarm's condition is still being detected + """ + + return (self.alarms_flags & 32768) > 0 + def clear_dialin_alarms(self): """ Clears the alarms states in Dialin. @@ -395,8 +428,7 @@ @param message: published blood flow data message @return: none """ - - self.alarms_state = int.from_bytes(bytearray( + self.alarms_priority_state = int.from_bytes(bytearray( message['message'][self.START_POS_ALARM_STATE:self.END_POS_ALARM_STATE]), byteorder=DenaliMessage.BYTE_ORDER) self.alarm_top = int.from_bytes(bytearray( @@ -421,16 +453,24 @@ @return: none """ self.logger.debug("Alarm activated!") - alarm_id = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) - data_typ_1 = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) - data_1 = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3])) - data_typ_2 = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4])) - data_2 = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5])) - priority = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6])) - rank = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7])) - clr_top_only = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8])) + alarm_id = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) + data_typ_1 = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) + data_1 = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3])) + data_typ_2 = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4])) + data_2 = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5])) + priority = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6])) + rank = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7])) + clr_top_only = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8])) - self.logger.debug("Alarm ID: %d %d %d"%(alarm_id[0], data_1[0], data_2[0])) + self.logger.debug("Alarm ID: %d %d %d" % (alarm_id[0], data_1[0], data_2[0])) self.alarm_states[alarm_id[0]] = True self.alarm_conditions[alarm_id[0]] = True self.alarm_priorities[alarm_id[0]] = priority[0] @@ -775,7 +815,7 @@ else: str_res = str(ms) + " ms: " self.logger.debug("Alarm status broadcast interval overridden to " + str_res + - str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: Index: dialin/hd/ui_proxy.py =================================================================== diff -u -rab24503836ed04ff6e3f14b80fc9de92efb557b5 -r74da0b9125ce91e76ce824e4f8e520eb32ee8d84 --- dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision ab24503836ed04ff6e3f14b80fc9de92efb557b5) +++ dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 74da0b9125ce91e76ce824e4f8e520eb32ee8d84) @@ -8,7 +8,7 @@ # @file ui_proxy.py # # @author (last) Dara Navaei -# @date (last) 03-Aug-2022 +# @date (last) 08-Dec-2022 # @author (original) Sean # @date (original) 15-Apr-2020 # Index: tests/dg_tests.py =================================================================== diff -u -rf8e8a2028269c7d914f30d28b6be993e74388534 -r74da0b9125ce91e76ce824e4f8e520eb32ee8d84 --- tests/dg_tests.py (.../dg_tests.py) (revision f8e8a2028269c7d914f30d28b6be993e74388534) +++ tests/dg_tests.py (.../dg_tests.py) (revision 74da0b9125ce91e76ce824e4f8e520eb32ee8d84) @@ -296,8 +296,8 @@ 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_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, @@ -349,7 +349,7 @@ def get_dg_idle_bad_fill_info(): info = ('Bad_fill_state, {}, ' - .format(DGGenIdleModeBadFillSubStates(dg.gen_idle.sub_state).name)) + .format(DGGenIdleModeBadFillSubStates(dg.gen_idle.bad_fill_state).name)) return info @@ -430,7 +430,6 @@ dg.dialysate_fill.cmd_used_bicarb_volume_override(3700.0) sleep(1) """ - counter = 1 start = False sleep_time = 1 @@ -733,6 +732,10 @@ #test_conc_pumps() + #while True: + # print(get_concentrate_pumps_info()) + # sleep(1) + #ui = HDSimulator() #ui.cmd_send_hd_operation_mode(3, 1) Index: tests/hd_nvm_scripts.py =================================================================== diff -u -rf8e8a2028269c7d914f30d28b6be993e74388534 -r74da0b9125ce91e76ce824e4f8e520eb32ee8d84 --- tests/hd_nvm_scripts.py (.../hd_nvm_scripts.py) (revision f8e8a2028269c7d914f30d28b6be993e74388534) +++ tests/hd_nvm_scripts.py (.../hd_nvm_scripts.py) (revision 74da0b9125ce91e76ce824e4f8e520eb32ee8d84) @@ -58,7 +58,7 @@ #hd.calibration_record.cmd_set_hd_calibration_excel_to_fw('/home/fw/projects/HD_NV_Records/2022-08-13-HD-Record.xlsx') # For resetting the calibration record to benign values, use the function below - #hd.calibration_record.cmd_reset_hd_calibration_record() + hd.calibration_record.cmd_reset_hd_calibration_record() def run_system_commands(): Index: tools/Code_Report.csv =================================================================== diff -u -r26d0d474f68286ef7570354ebc280bb56956ee66 -r74da0b9125ce91e76ce824e4f8e520eb32ee8d84 --- tools/Code_Report.csv (.../Code_Report.csv) (revision 26d0d474f68286ef7570354ebc280bb56956ee66) +++ tools/Code_Report.csv (.../Code_Report.csv) (revision 74da0b9125ce91e76ce824e4f8e520eb32ee8d84) @@ -1284,17 +1284,17 @@ common/alarm_defs.py, Enum, AlarmList, ALARM_ID_AIR_TRAP_FILL_DURING_TREATMENT common/alarm_defs.py, Enum, AlarmList, ALARM_ID_OCCLUSION_BLOOD_PUMP common/alarm_defs.py, Enum, AlarmList, ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE -common/alarm_defs.py, Enum, AlarmList, ALARM_ID_DG_RO_FLOW_SENSOR_INVALID_CAL_RECORD +common/alarm_defs.py, Enum, AlarmList, ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH common/alarm_defs.py, Enum, AlarmList, ALARM_ID_ACID_CONDUCTIVITY_OUT_OF_RANGE common/alarm_defs.py, Enum, AlarmList, ALARM_ID_DG_RTC_OR_TIMER_ACCURACY_FAILURE common/alarm_defs.py, Enum, AlarmList, ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT -common/alarm_defs.py, Enum, AlarmList, ALARM_ID_INLET_WATER_HIGH_TEMPERATURE +common/alarm_defs.py, Enum, AlarmList, ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_HIGH common/alarm_defs.py, Enum, AlarmList, ALARM_ID_HD_WATCHDOG_EXPIRED common/alarm_defs.py, Enum, AlarmList, ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE common/alarm_defs.py, Enum, AlarmList, ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE common/alarm_defs.py, Enum, AlarmList, ALARM_ID_INLET_WATER_PRESSURE_IN_LOW_RANGE common/alarm_defs.py, Enum, AlarmList, ALARM_ID_PRIME_COMPLETED_HIGH -common/alarm_defs.py, Enum, AlarmList, ALARM_ID_NVDATA_EEPROM_OPS_FAILURE +common/alarm_defs.py, Enum, AlarmList, ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW common/alarm_defs.py, Enum, AlarmList, ALARM_ID_HD_NEW_RESERVOIRS_DATA_MESSAGE_NOT_RECEIVE common/alarm_defs.py, Enum, AlarmList, ALARM_ID_HD_NEW_DG_OPERATION_MODE_MESSAGE_NOT_RECEIVE common/alarm_defs.py, Enum, AlarmList, ALARM_ID_DG_CHEM_DISINFECT_PRIME_ACID_LINE_TIME_OUT