Index: leahi_dialin/common/dd_defs_proxy.py =================================================================== diff -u -r6d104d3185ac3ed7c18c97ecdc13fd59bf53a8d1 -r1f7b5ac840adf6740b023706fcb73691c33a9be7 --- leahi_dialin/common/dd_defs_proxy.py (.../dd_defs_proxy.py) (revision 6d104d3185ac3ed7c18c97ecdc13fd59bf53a8d1) +++ leahi_dialin/common/dd_defs_proxy.py (.../dd_defs_proxy.py) (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -74,4 +74,19 @@ DDValveStates = dd_defs.DDValveStates DDCancelModes = dd_defs.DDCancelModes + # Records + RecordTypes = generic_defs.RecordTypes + SystemRecordFields = generic_defs.SystemRecordFields + ServiceRecordFields = generic_defs.ServiceRecordFields + CalibrationRecordFields = generic_defs.CalibrationRecordFields + InstitutionalRecordFields = generic_defs.InstitutionalRecordFields + UsageInformationRecordFields = generic_defs.UsageInformationRecordFields + + # Record support + CalibRecordAccelerometerFields = generic_defs.CalibRecordAccelerometerFields + CalibRecordBloodLeakFields = generic_defs.CalibRecordBloodLeakFields + CalibRecordConcentrateFields = generic_defs.CalibRecordConcentrateFields + CalibRecordSensorFields = generic_defs.CalibRecordSensorFields + + dd_enum_repository = DD_Defs() Index: leahi_dialin/common/generic_defs.py =================================================================== diff -u -r6c90336ac2cd8cf34ac620cff431a847d9ddf557 -r1f7b5ac840adf6740b023706fcb73691c33a9be7 --- leahi_dialin/common/generic_defs.py (.../generic_defs.py) (revision 6c90336ac2cd8cf34ac620cff431a847d9ddf557) +++ leahi_dialin/common/generic_defs.py (.../generic_defs.py) (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -17,27 +17,31 @@ from enum import unique from ..utils.enums import DialinEnum +from .dd_defs import DDPressureSensorNames, DDTemperatureSensorNames, DDConcentratePumpNames, DDDialysatePumpNames +from .disp_defs import AcidTypes, BicarbTypes @unique class DataTypes(DialinEnum): - NONE = (0, ' Integer - S32 = (2, ' Integer - F32 = (3, ' Float - BOOL = (4, ' Integer + NONE = (0, ' Integer + S32 = (2, ' Integer + F32 = (3, ' Float + BOOL = (4, ' Integer # After this point the Data Types are extra ones used only in Dialin - U08 = (5, ' Integer - U16 = (6, ' Integer - S16 = (7, ' Integer - BOOL_U08 = (8, ' Integer - NUM_OF_DATA_TYPES = (9, None, 0) # Number of Data Types - None + U08 = (5, ' Integer + U16 = (6, ' Integer + S16 = (7, ' Integer + BOOL_U08 = (8, ' Integer + BYTES_10 = (9, ' Integer + BYTES_20 = (10, ' Integer + NUM_OF_DATA_TYPES = (11, None, 0) # Number of Data Types - None def __new__(cls, value, unpack_fmt, unpack_size): obj = object.__new__(cls) - obj._value_ = value # keeps .value as int - obj.unpack_fmt = unpack_fmt # attach extra attribute - obj.unpack_size = unpack_size # attach extra attribute + obj._value_ = value # keeps .value as int + obj.unpack_fmt = unpack_fmt # attach extra attribute + obj.unpack_size = unpack_size # attach extra attribute return obj def unpack_attrib(self) -> str: @@ -59,3 +63,304 @@ 'BOOL_U08': [], 'NUM_OF_DATA_TYPES': [], } + + +@unique +class RecordsBaseEnum(DialinEnum): + def __new__(cls, value, unpack_type, unpack_length: int=1): + obj = object.__new__(cls) + obj._value_ = value # keeps .value as int + obj.unpack_type = unpack_type # attach extra attribute + obj.unpack_length = unpack_length # attach extra attribute + return obj + + def datatype(self) -> DataTypes: + return self.unpack_type + + def multichar_length(self) -> int: + return self.unpack_length + + +@unique +class RecordTypes(DialinEnum): + SYSTEM_RECORD = 0 # System Record + SERVICE_RECORD = 1 # System Record + CALIBRATION_RECORD = 2 # System Record + INSTITUTIONAL_RECORD = 3 # System Record + USAGE_INFORMATION_RECORD = 4 # System Record + NUM_OF_RECORD_TYPES = 5 # Number of Record Types + +RecordTypes._str_list = { + # Official Name : Accepted strings + 'SYSTEM_RECORD': [], + 'SERVICE_RECORD': [], + 'CALIBRATION_RECORD': [], + 'INSTITUTIONAL_RECORD': [], + 'USAGE_INFORMATION_RECORD': [], + 'NUM_OF_RECORD_TYPES': [], +} + + +@unique +class SystemRecordFields(RecordsBaseEnum): + TOP_LEVEL_PN = (0, DataTypes.U08, 10) # Top level part number + TOP_LEVEL_SN = (1, DataTypes.U08, 20) # Top level serial number + MFG_LOCATION = (2, DataTypes.U32) # Manufacturing Location + MFG_DATE = (3, DataTypes.U32) # Manufacturing Date + CRC = (4, DataTypes.U16) # CRC + NUM_OF_SYSTEM_RECORD_FIELDS = (5, DataTypes.NONE) # Number of System Record Fields + +SystemRecordFields._str_list = { + # Official Name : Accepted strings + 'TOP_LEVEL_PN': ['pn', 'part number'], + 'TOP_LEVEL_SN': ['sn', 'serial number'], + 'MFG_LOCATION': ['location', 'manufacturing location'], + 'MFG_DATE': ['date', 'manufacturing date'], + 'CRC': [], + 'NUM_OF_SYSTEM_RECORD_FIELDS': [], +} + + +@unique +class ServiceRecordFields(DialinEnum): + SERVICE_LOC = (0, DataTypes.U08) # DD service location + LAST_SERVICE_EPOCH_DATE = (1, DataTypes.U32) # DD last service date in epoch + SERVICE_INTERVAL_SECONDS = (2, DataTypes.U32) # DD service interval in seconds + LAST_RESET_TIME_EPOCH = (3, DataTypes.U32) # Last time the record was reset in epoch + CRC = (4, DataTypes.U16) # CRC + NUM_OF_SERVICE_RECORD_FIELDS = (5, DataTypes.NONE) # Number of Service Record Fields + +ServiceRecordFields._str_list = { + # Official Name : Accepted strings + 'SERVICE_LOC': [], + 'LAST_SERVICE_EPOCH_DATE': [], + 'SERVICE_INTERVAL_SECONDS': [], + 'LAST_RESET_TIME_EPOCH': [], + 'CRC': [], + 'NUM_OF_SERVICE_RECORD_FIELDS': [], +} + + +@unique +class CalibRecordAccelerometerFields(DialinEnum): + ACCEL_X_OFFSET = (0, DataTypes.F32) # DD accelerometer X axis offset + ACCEL_Y_OFFSET = (1, DataTypes.F32) # DD accelerometer Y axis offset + ACCEL_Z_OFFSET = (2, DataTypes.F32) # DD accelerometer Z axis offset + CALIBRATION_TIME = (3, DataTypes.U32) # Calibration time + CRC = (4, DataTypes.U16) # CRC + NUM_OF_CALIBRATION_RECORD_ACCELEROMETER_FIELDS = (5, DataTypes.NONE) # Number of Calibration Record Accelerometer's Fields + +CalibRecordAccelerometerFields._str_list = { + # Official Name : Accepted strings + 'ACCEL_X_OFFSET': [], + 'ACCEL_Y_OFFSET': [], + 'ACCEL_Z_OFFSET': [], + 'CALIBRATION_TIME': [], + 'CRC': [], + 'NUM_OF_CALIBRATION_RECORD_ACCELEROMETER_FIELDS': [], +} + + +@unique +class CalibRecordBloodLeakFields(DialinEnum): + SET_POINT = (0, DataTypes.F32) # DD Blood leak sensor set point + CALIBRATION_TIME = (3, DataTypes.U32) # Calibration time + CRC = (4, DataTypes.U16) # CRC + NUM_OF_CALIBRATION_RECORD_BLOOD_LEAK_FIELDS = (5, DataTypes.NONE) # Number of Calibration Record Accelerometer's Fields + +CalibRecordBloodLeakFields._str_list = { + # Official Name : Accepted strings + 'SET_POINT': [], + 'CALIBRATION_TIME': [], + 'CRC': [], + 'NUM_OF_CALIBRATION_RECORD_BLOOD_LEAK_FIELDS': [], +} + + +@unique +class CalibRecordConcentrateFields(DialinEnum): + CONCENTRATE_MIX_RATIO = (0, DataTypes.F32) # Acid or Bicarb Concentrate mix ratio. + FULL_BOTTLE_VOLUME_ML = (1, DataTypes.F32) # Acid or Bicarb full bottle volume in milliliters. + CONDUCTIVITY_USPCM = (2, DataTypes.F32) # Acid or Bicarb conductivity in uS/cm. + BOTTLE_TEMPERATURE_C = (3, DataTypes.F32) # Acid or Bicarb bottle temperature in C. + CALIBRATION_TIME = (4, DataTypes.U32) # Calibration time + CRC = (5, DataTypes.U16) # CRC + NUM_OF_CALIBRATION_RECORD_CONCENTRATE_FIELDS = (6, DataTypes.NONE) # Number of Calibration Record Acid and Bicarb Concentrate's Fields + +CalibRecordConcentrateFields._str_list = { + # Official Name : Accepted strings + 'CONCENTRATE_MIX_RATIO': [], + 'FULL_BOTTLE_VOLUME_ML': [], + 'CONDUCTIVITY_USPCM': [], + 'BOTTLE_TEMPERATURE_C': [], + 'CALIBRATION_TIME': [], + 'CRC': [], + 'NUM_OF_CALIBRATION_RECORD_CONCENTRATE_FIELDS': [], +} + + +@unique +class CalibRecordSensorFields(DialinEnum): + FORTH_ORDER_COEFF = (0, DataTypes.F32) # Sensor's Fourth order coefficient + THIRD_ORDER_COEFF = (1, DataTypes.F32) # Sensor's Third order coefficient + SECOND_ORDER_COEFF = (2, DataTypes.F32) # Sensor's Second order coefficient + GAIN = (3, DataTypes.F32) # Sensor's Gain + OFFSET = (4, DataTypes.F32) # Sensor's Offset + CALIBRATION_TIME = (5, DataTypes.U32) # Sensor's Calibration time + CRC = (6, DataTypes.U16) # Sensor's CRC + NUM_OF_CALIBRATION_RECORD_SENSOR_FIELDS = (7, DataTypes.NONE) # Number of Calibration Record Sensor's Fields + +CalibRecordSensorFields._str_list = { + # Official Name : Accepted strings + 'FORTH_ORDER_COEFF': [], + 'THIRD_ORDER_COEFF': [], + 'SECOND_ORDER_COEFF': [], + 'GAIN': [], + 'OFFSET': [], + 'CALIBRATION_TIME': [], + 'CRC': [], + 'NUM_OF_CALIBRATION_RECORD_SENSOR_FIELDS': [], +} + + +@unique +class CalibrationRecordFields(DialinEnum): + def __new__(cls): + obj = object.__new__(cls) + i = 0 + for pres_sensor in DDPressureSensorNames: + for field_name in CalibRecordSensorFields: + obj._name_ = f'{pres_sensor.name}_{field_name.name}' + obj._value_ = i + i += 1 + for temp_sensor in DDTemperatureSensorNames: + for field_name in CalibRecordSensorFields: + obj._name_ = f'{temp_sensor.name}_{field_name.name}' + obj._value_ = i + i += 1 + for conc_pump in DDConcentratePumpNames: + for field_name in CalibRecordSensorFields: + obj._name_ = f'{conc_pump.name}_{field_name.name}' + obj._value_ = i + i += 1 + for dial_pump in DDDialysatePumpNames: + # Custom request for D12 to include Target Speed + if dial_pump is DDDialysatePumpNames.D12_PUMP: + obj._name_ = f'{dial_pump.name}_TARGET_SPEED' + obj._value_ = i + i += 1 + for field_name in CalibRecordSensorFields: + obj._name_ = f'{dial_pump.name}_{field_name.name}' + obj._value_ = i + i += 1 + for acid in AcidTypes: + for field_name in CalibRecordConcentrateFields: + obj._name_ = f'{acid.name}_{field_name.name}' + obj._value_ = i + i += 1 + for bicarb in BicarbTypes: + for field_name in CalibRecordConcentrateFields: + obj._name_ = f'{bicarb.name}_{field_name.name}' + obj._value_ = i + i += 1 + for bicarb in BicarbTypes: + for field_name in CalibRecordConcentrateFields: + obj._name_ = f'{bicarb.name}_{field_name.name}' + obj._value_ = i + i += 1 + # Accelerometer + for field_name in CalibRecordAccelerometerFields: + obj._name_ = f'ACCEL_{field_name.name}' + obj._value_ = i + i += 1 + # Blood Leak sensor + for field_name in CalibRecordBloodLeakFields: + obj._name_ = f'BLOOD_LEAK_{field_name.name}' + obj._value_ = i + i += 1 + return obj + + # Dialysate Pump + # Acid concentrates + # Bicarb Concentrates + # Accelerometer + # Blood Leak sensor + +@unique +class InstitutionalRecordFields(DialinEnum): + MIN_DIALYSATE_SYSTEM_FLOW_MLPM = (0, DataTypes.U32) # Min dialysate flow in mL/min + MAX_DIALYSATE_SYSTEM_FLOW_MLPM = (1, DataTypes.U32) # Max dialysate flow in mL/min + MIN_DIALYSATE_TEMP_C = (2, DataTypes.F32) # Min dialysate temperature in C + MAX_DIALYSATE_TEMP_C = (3, DataTypes.F32) # Max dialysate temperature in C + ACID_CONCENTRATE = (4, DataTypes.F32) # Acid concentrate + BICARB_CARTRIDGE_SIZE_G = (5, DataTypes.F32) # Bicarbonate cartridge size in grams + MIN_SODIUM_MEQPL = (6, DataTypes.F32) # Min sodium in mEq/L + MAX_SODIUM_MEQPL = (7, DataTypes.F32) # Max sodium in mEq/L + MIN_BICARBONATE_MEQPL = (8, DataTypes.F32) # Min bicarbonate in mEq/L + MAX_BICARBONATE_MEQPL = (9, DataTypes.F32) # Max bicarbonate in mEq/L + MIN_RO_REJECTION_RATIO_PCT = (10, DataTypes.U32) # Min RO rejection ratio in percent + DISINFECTION_FREQUENCY = (11, DataTypes.U32) # Disinfection days between cycles + DISINFECTION_CYCLE_TIME = (12, DataTypes.F32) # Disinfection Cycle Time + MIN_INLET_WATER_CIND_AKARN_LIMIT_USPCM = (13, DataTypes.F32) # Min inlet water conductivity alarm limit in uS/cm + MAX_INLET_WATER_CIND_AKARN_LIMIT_USPCM = (14, DataTypes.F32) # Max inlet water conductivity alarm limit in uS/cm + ACID_CONCENTRATE_JUG_SIZE_L = (15, DataTypes.F32) # acid concentrate jug size in Liters + MIN_ACID_ALARM_LIMIT_PCT = (16, DataTypes.F32) # Min acid alarm limit in percent + MIN_BICARB_ALARM_LIMIT_PCT = (17, DataTypes.F32) # Min bicarbonate alarm limit in percent + POST_TREAT_DRAIN_OPTION = (18, DataTypes.U32) # Dialysate Post Treatment Drain OptionĀ  + POST_TREAT_DRY_BICARB_OPTION = (19, DataTypes.U32) # Dry Bicarbonate Post Treatment OptionĀ  + CALIBRATION_TIME = (20, DataTypes.U32) # Calibration time in epoch. + CRC = (21, DataTypes.U16) # CRC + NUM_OF_INSTITUTIONAL_RECORD_FIELDS = (22, DataTypes.NONE) # Number of Institutional Record Fields + +InstitutionalRecordFields._str_list = { + # Official Name : Accepted strings + 'MIN_DIALYSATE_SYSTEM_FLOW_MLPM': [], + 'MAX_DIALYSATE_SYSTEM_FLOW_MLPM': [], + 'MIN_DIALYSATE_TEMP_C': [], + 'MAX_DIALYSATE_TEMP_C': [], + 'ACID_CONCENTRATE': [], + 'BICARB_CARTRIDGE_SIZE_G': [], + 'MIN_SODIUM_MEQPL': [], + 'MAX_SODIUM_MEQPL': [], + 'MIN_BICARBONATE_MEQPL': [], + 'MAX_BICARBONATE_MEQPL': [], + 'MIN_RO_REJECTION_RATIO_PCT': [], + 'DISINFECTION_FREQUENCY': [], + 'DISINFECTION_CYCLE_TIME': [], + 'MIN_INLET_WATER_CIND_AKARN_LIMIT_USPCM': [], + 'MAX_INLET_WATER_CIND_AKARN_LIMIT_USPCM': [], + 'ACID_CONCENTRATE_JUG_SIZE_L': [], + 'MIN_ACID_ALARM_LIMIT_PCT': [], + 'MIN_BICARB_ALARM_LIMIT_PCT': [], + 'POST_TREAT_DRAIN_OPTION': [], + 'POST_TREAT_DRY_BICARB_OPTION': [], + 'CALIBRATION_TIME': [], + 'CRC': [], + 'NUM_OF_INSTITUTIONAL_RECORD_FIELDS': [], +} + + +@unique +class UsageInformationRecordFields(DialinEnum): + RO_WATER_GEN_TOTAL_L = (0, DataTypes.F32) # Total RO water generated in liters. (Cannot be reset) + RO_WATER_GEN_SINCE_LAST_SERVICE_L = (1, DataTypes.F32) # RO water generated since last treatment in liters + LAST_BASIC_FLUSH_COMPLETE_DATE_EPOCH = (2, DataTypes.U32) # Last basic flush complete date in epoch. + LAST_HEAT_DISINFECT_COMPLETE_DATE_EPOCH = (3, DataTypes.U32) # Last heat disinfect complete date in epoch. + LAST_HEAT_ACTIVE_COOL_COMPLETE_DATE_EPOCH = (4, DataTypes.U32) # Last heat disinfect active cool complete date in epoch. + LAST_FILTER_FLUSH_COMPLETE_DATE_EPOCH = (5, DataTypes.U32) # Last filter flush complete date in epoch. + LAST_RESET_TIME_EPOCH = (6, DataTypes.U32) # Last time the record was reset in epoch. + CRC = (7, DataTypes.U16) # CRC + NUM_OF_USAGE_INFO_RECORD_FIELDS = (8, DataTypes.NONE) # Number of Usage Information Record Fields + +UsageInformationRecordFields._str_list = { + # Official Name : Accepted strings + 'RO_WATER_GEN_TOTAL_L': [], + 'RO_WATER_GEN_SINCE_LAST_SERVICE_L': [], + 'LAST_BASIC_FLUSH_COMPLETE_DATE_EPOCH': [], + 'LAST_HEAT_DISINFECT_COMPLETE_DATE_EPOCH': [], + 'LAST_HEAT_ACTIVE_COOL_COMPLETE_DATE_EPOCH': [], + 'LAST_FILTER_FLUSH_COMPLETE_DATE_EPOCH': [], + 'LAST_RESET_TIME_EPOCH': [], + 'CRC': [], + 'NUM_OF_USAGE_INFO_RECORD_FIELDS': [], +} \ No newline at end of file Index: leahi_dialin/common/msg_ids.py =================================================================== diff -u -r099095611e541d69aee3afc90ec06a2046836079 -r1f7b5ac840adf6740b023706fcb73691c33a9be7 --- leahi_dialin/common/msg_ids.py (.../msg_ids.py) (revision 099095611e541d69aee3afc90ec06a2046836079) +++ leahi_dialin/common/msg_ids.py (.../msg_ids.py) (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -20,54 +20,54 @@ # Branch: staging @unique class MsgIds(DialinEnum): - MSG_ID_UNUSED = 0x0 - MSG_ID_ALARM_STATUS_DATA = 0x1 - MSG_ID_ALARM_TRIGGERED = 0x2 - MSG_ID_ALARM_CLEARED = 0x3 - MSG_ID_ALARM_CONDITION_CLEARED = 0x4 - MSG_ID_USER_ALARM_SILENCE_REQUEST = 0x5 - MSG_ID_UI_ALARM_USER_ACTION_REQUEST = 0x6 - MSG_ID_TD_ALARM_INFORMATION_DATA = 0x7 - MSG_ID_DD_ALARM_INFO_DATA = 0x8 - MSG_ID_UI_ACTIVE_ALARMS_LIST_REQUEST = 0x9 - MSG_ID_TD_ACTIVE_ALARMS_LIST_REQUEST_RESPONSE = 0xA - MSG_ID_UI_SET_ALARM_AUDIO_VOLUME_LEVEL_CMD_REQUEST = 0xB - MSG_ID_TD_ALARM_AUDIO_VOLUME_SET_RESPONSE = 0xC - MSG_ID_FW_VERSIONS_REQUEST = 0xD + MSG_ID_UNUSED = 0x0 + MSG_ID_ALARM_STATUS_DATA = 0x1 + MSG_ID_ALARM_TRIGGERED = 0x2 + MSG_ID_ALARM_CLEARED = 0x3 + MSG_ID_ALARM_CONDITION_CLEARED = 0x4 + MSG_ID_USER_ALARM_SILENCE_REQUEST = 0x5 + MSG_ID_UI_ALARM_USER_ACTION_REQUEST = 0x6 + MSG_ID_TD_ALARM_INFORMATION_DATA = 0x7 + MSG_ID_DD_ALARM_INFO_DATA = 0x8 + MSG_ID_UI_ACTIVE_ALARMS_LIST_REQUEST = 0x9 + MSG_ID_TD_ACTIVE_ALARMS_LIST_REQUEST_RESPONSE = 0xA + MSG_ID_UI_SET_ALARM_AUDIO_VOLUME_LEVEL_CMD_REQUEST = 0xB + MSG_ID_TD_ALARM_AUDIO_VOLUME_SET_RESPONSE = 0xC + MSG_ID_FW_VERSIONS_REQUEST = 0xD MSG_ID_TD_VERSION_RESPONSE = 0xE MSG_ID_DD_VERSION_RESPONSE = 0xF - MSG_ID_UI_CHECK_IN = 0x10 - MSG_ID_TD_BLOOD_PUMP_DATA = 0x11 - MSG_ID_TD_OP_MODE_DATA = 0x12 - MSG_ID_DD_OP_MODE_DATA = 0x13 - MSG_ID_DD_COMMAND_RESPONSE = 0x14 - MSG_ID_TD_UI_VERSION_INFO_REQUEST = 0x15 - MSG_ID_UI_VERSION_INFO_RESPONSE = 0x16 - MSG_ID_TD_EVENT = 0x17 - MSG_ID_DD_EVENT = 0x18 - MSG_ID_TD_DD_ALARMS_REQUEST = 0x19 - MSG_ID_UI_TD_RESET_IN_SERVICE_MODE_REQUEST = 0x1A - MSG_ID_DD_VALVES_STATES_DATA = 0x1B - MSG_ID_DD_PRESSURES_DATA = 0x1C - MSG_ID_TD_VOLTAGES_DATA = 0x1D - MSG_ID_TD_BUBBLES_DATA = 0x1E - MSG_ID_DD_CONDUCTIVITY_DATA = 0x1F - MSG_ID_TD_AIR_PUMP_DATA = 0x20 - MSG_ID_TD_SWITCHES_DATA = 0x21 - MSG_ID_POWER_OFF_WARNING = 0x22 - MSG_ID_OFF_BUTTON_PRESS_REQUEST = 0x23 + MSG_ID_UI_CHECK_IN = 0x10 + MSG_ID_TD_BLOOD_PUMP_DATA = 0x11 + MSG_ID_TD_OP_MODE_DATA = 0x12 + MSG_ID_DD_OP_MODE_DATA = 0x13 + MSG_ID_DD_COMMAND_RESPONSE = 0x14 + MSG_ID_TD_UI_VERSION_INFO_REQUEST = 0x15 + MSG_ID_UI_VERSION_INFO_RESPONSE = 0x16 + MSG_ID_TD_EVENT = 0x17 + MSG_ID_DD_EVENT = 0x18 + MSG_ID_TD_DD_ALARMS_REQUEST = 0x19 + MSG_ID_UI_TD_RESET_IN_SERVICE_MODE_REQUEST = 0x1A + MSG_ID_DD_VALVES_STATES_DATA = 0x1B + MSG_ID_DD_PRESSURES_DATA = 0x1C + MSG_ID_TD_VOLTAGES_DATA = 0x1D + MSG_ID_TD_BUBBLES_DATA = 0x1E + MSG_ID_DD_CONDUCTIVITY_DATA = 0x1F + MSG_ID_TD_AIR_PUMP_DATA = 0x20 + MSG_ID_TD_SWITCHES_DATA = 0x21 + MSG_ID_POWER_OFF_WARNING = 0x22 + MSG_ID_OFF_BUTTON_PRESS_REQUEST = 0x23 MSG_ID_TD_PRESSURE_DATA = 0x24 - MSG_ID_DD_CONCENTRATE_PUMP_DATA = 0x25 - MSG_ID_DD_TEMPERATURE_DATA = 0x26 - MSG_ID_DIALYSATE_PUMPS_DATA = 0x27 - MSG_ID_DD_HEATERS_DATA = 0x28 - MSG_ID_DD_LEVEL_DATA = 0x29 - MSG_ID_TD_AIR_TRAP_DATA = 0x2A - MSG_ID_TD_VALVES_DATA = 0x2B + MSG_ID_DD_CONCENTRATE_PUMP_DATA = 0x25 + MSG_ID_DD_TEMPERATURE_DATA = 0x26 + MSG_ID_DIALYSATE_PUMPS_DATA = 0x27 + MSG_ID_DD_HEATERS_DATA = 0x28 + MSG_ID_DD_LEVEL_DATA = 0x29 + MSG_ID_TD_AIR_TRAP_DATA = 0x2A + MSG_ID_TD_VALVES_DATA = 0x2B 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_BAL_CHAMBER_DATA = 0x2E + MSG_ID_DD_GEN_DIALYSATE_MODE_DATA = 0x2F MSG_ID_DD_GEN_DIALYSATE_REQUEST_DATA = 0x30 MSG_ID_FP_VALVES_STATES_DATA = 0x31 MSG_ID_FP_RO_PUMP_DATA = 0x32 @@ -377,9 +377,21 @@ MSG_ID_DD_BICARB_CHAMBER_FILL_REQUEST_OVERRIDE_REQUEST = 0xA059 MSG_ID_DD_BICART_DRAIN_REQUEST_OVERRIDE_REQUEST = 0xA05A MSG_ID_DD_BICART_CARTRIDGE_SELECT_OVERRIDE_REQUEST = 0xA05B + MSG_ID_DD_NVM_GET_RECORD = 0xA05C + MSG_ID_DD_NVM_SEND_SYSTEM_RECORD = 0xA05D + MSG_ID_DD_NVM_SET_SYSTEM_RECORD = 0xA05E + MSG_ID_DD_NVM_SEND_SERVICE_RECORD = 0xA05F + MSG_ID_DD_NVM_SET_SERVICE_RECORD = 0xA060 + MSG_ID_DD_NVM_SEND_CALIBRATION_RECORD = 0xA061 + MSG_ID_DD_NVM_SET_CALIBRATION_RECORD = 0xA062 + MSG_ID_DD_NVM_SEND_INSTITUTIONAL_RECORD = 0xA063 + MSG_ID_DD_NVM_SET_INSTITUTIONAL_RECORD = 0xA064 + MSG_ID_DD_NVM_SEND_USAGE_INFO_RECORD = 0xA065 + MSG_ID_DD_NVM_SET_USAGE_INFO_RECORD = 0xA066 MSG_ID_DD_SET_CONDUCTIVITY_MODEL_REQUEST = 0xA100 MSG_ID_DD_CONDUCTIVITY_SENSOR_RESISTANCE_OVERRIDE_REQUEST = 0xA101 + # Placeholder messages MSG_ID_DD_ALARM_STATE_OVERRIDE_REQUEST = 0xAF03 Index: leahi_dialin/common/td_defs_proxy.py =================================================================== diff -u -r636775bd0ba262967bcf06e194658b97720e2517 -r1f7b5ac840adf6740b023706fcb73691c33a9be7 --- leahi_dialin/common/td_defs_proxy.py (.../td_defs_proxy.py) (revision 636775bd0ba262967bcf06e194658b97720e2517) +++ leahi_dialin/common/td_defs_proxy.py (.../td_defs_proxy.py) (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -95,4 +95,19 @@ TDTreatmentModalityTypes = td_defs.TDTreatmentModalityTypes TDTreatmentHDFDilution = td_defs.TDTreatmentHDFDilution + # Records + RecordTypes = generic_defs.RecordTypes + SystemRecordFields = generic_defs.SystemRecordFields + ServiceRecordFields = generic_defs.ServiceRecordFields + CalibrationRecordFields = generic_defs.CalibrationRecordFields + InstitutionalRecordFields = generic_defs.InstitutionalRecordFields + UsageInformationRecordFields = generic_defs.UsageInformationRecordFields + + # Record support + CalibRecordAccelerometerFields = generic_defs.CalibRecordAccelerometerFields + CalibRecordBloodLeakFields = generic_defs.CalibRecordBloodLeakFields + CalibRecordConcentrateFields = generic_defs.CalibRecordConcentrateFields + CalibRecordSensorFields = generic_defs.CalibRecordSensorFields + + td_enum_repository = TD_Defs() Index: leahi_dialin/dd/dialysate_delivery.py =================================================================== diff -u -r1f2bf6d939eb4033dbedb7d7005494cc12fccbc6 -r1f7b5ac840adf6740b023706fcb73691c33a9be7 --- leahi_dialin/dd/dialysate_delivery.py (.../dialysate_delivery.py) (revision 1f2bf6d939eb4033dbedb7d7005494cc12fccbc6) +++ leahi_dialin/dd/dialysate_delivery.py (.../dialysate_delivery.py) (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -21,6 +21,7 @@ from .modules.concentrate_pump import DDConcentratePumps from .modules.conductivity_sensors import DDConductivitySensors from .modules.dialysate_pump import DDDialysatePumps +from .modules.drybicart import DDDryBicart from .modules.events import DDEvents from .modules.gen_dialysate import DDGenDialysate from .modules.heaters import DDHeaters @@ -29,8 +30,8 @@ from .modules.pressure_sensors import DDPressureSensors from .modules.pre_gen_dialysate import DDPreGenDialysate from .modules.rinse_pump import DDRinsePump +from .modules.records import DDRecords from .modules.spent_chamber_fill import DDSpentChamberFill -from .modules.drybicart import DDDryBicart from .modules.temperature_sensors import DDTemperatureSensors from .modules.dd_test_configs import DDTestConfig from .modules.ultrafiltration import DDUltrafiltration @@ -124,6 +125,7 @@ self.concentrate_pumps = DDConcentratePumps(self.can_interface, self.logger) #: The Concentrat Pumps module self.conductivity_sensors = DDConductivitySensors(self.can_interface, self.logger) #: The Conductivity Sensors module self.dialysate_pumps = DDDialysatePumps(self.can_interface, self.logger) #: The Dialysate Pumps module + self.drybicart = DDDryBicart(self.can_interface, self.logger) #: The Dry Bicarb module self.events = DDEvents(self.can_interface, self.logger) #: The Events module self.gen_dialysate = DDGenDialysate(self.can_interface, self.logger) #: The Generate Dialysate module self.heaters = DDHeaters(self.can_interface, self.logger) #: The Heaters module @@ -132,8 +134,8 @@ self.pressure_sensors = DDPressureSensors(self.can_interface, self.logger) #: The Pressure Sensors module self.pre_gen_dialysate = DDPreGenDialysate(self.can_interface, self.logger) #: The Pre Generate Dialysate module self.rinse_pump = DDRinsePump(self.can_interface, self.logger) #: The Rinse Pump module + self.records = DDRecords(self.can_interface, self.logger) #: The Records (System, Service, Calibration, Institutional, Usage Information) module self.spent_chamber_fill = DDSpentChamberFill(self.can_interface, self.logger) #: The Spent Chamber module - self.drybicart = DDDryBicart(self.can_interface, self.logger) #: The Dry Bicarb module self.temperature_sensors = DDTemperatureSensors(self.can_interface, self.logger) #: The Temperature Sensors module self.test_configs = DDTestConfig(self.can_interface, self.logger) #: The Test Configs module self.ultrafiltration = DDUltrafiltration(self.can_interface, self.logger) #: The Ultrafiltration module Index: leahi_dialin/dd/modules/events.py =================================================================== diff -u -r3e6eac0e751fd74569068bc8754f0828cd4fcd84 -r1f7b5ac840adf6740b023706fcb73691c33a9be7 --- leahi_dialin/dd/modules/events.py (.../events.py) (revision 3e6eac0e751fd74569068bc8754f0828cd4fcd84) +++ leahi_dialin/dd/modules/events.py (.../events.py) (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -215,7 +215,7 @@ last_op_mode_message = op_modes_list[-1] # Check if this is not the very first Sub Mode Change message - if len(sub_mode_list != 0): + if len(sub_mode_list) != 0: # Get the timestamps of the last messages of both list for comparison prev_op_mode_timestamp = datetime.strptime(last_op_mode_message[0], '%Y-%m-%d %H:%M:%S.%f') prev_sub_mode_timestamp = datetime.strptime(sub_mode_list[-1][0], '%Y-%m-%d %H:%M:%S.%f') Index: leahi_dialin/dd/modules/records.py =================================================================== diff -u --- leahi_dialin/dd/modules/records.py (revision 0) +++ leahi_dialin/dd/modules/records.py (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -0,0 +1,421 @@ +########################################################################### +# +# 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 pressure_sensors.py +# +# @author (last) Zoltan Miskolci +# @date (last) 04-May-2026 +# @author (original) Sean +# @date (original) 14-Apr-2020 +# +############################################################################ + +# Module imports +from logging import Logger + +# Project imports +from leahi_dialin.common import dd_enum_repository +from leahi_dialin.common.generic_defs import DataTypes +from leahi_dialin.common.msg_defs import MsgIds +from leahi_dialin.common.override_templates import cmd_generic_override +from leahi_dialin.protocols.CAN import CanMessenger, CanChannels +from leahi_dialin.utils.abstract_classes import AbstractSubSystem +from leahi_dialin.utils.base import publish +from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray, byte_to_bytearray + + +class DDRecords(AbstractSubSystem): + """ + DD interface containing pressure related commands. + """ + + def __init__(self, can_interface: CanMessenger, logger: Logger): + """ + @param can_interface: The CanMessenger object + """ + super().__init__() + self.can_interface = can_interface + self.logger = logger + + if self.can_interface is not None: + self.can_interface.register_receiving_publication_function(channel_id = CanChannels.dd_sync_broadcast_ch_id, + message_id = MsgIds.MSG_ID_DD_NVM_SEND_SYSTEM_RECORD.value, + function = self._handler_system_record_sync) + self.can_interface.register_receiving_publication_function(channel_id = CanChannels.dd_sync_broadcast_ch_id, + message_id = MsgIds.MSG_ID_DD_NVM_SEND_SERVICE_RECORD.value, + function = self._handler_service_record_sync) + self.can_interface.register_receiving_publication_function(channel_id = CanChannels.dd_sync_broadcast_ch_id, + message_id = MsgIds.MSG_ID_DD_NVM_SEND_CALIBRATION_RECORD.value, + function = self._handler_calibration_record_sync) + self.can_interface.register_receiving_publication_function(channel_id = CanChannels.dd_sync_broadcast_ch_id, + message_id = MsgIds.MSG_ID_DD_NVM_SEND_INSTITUTIONAL_RECORD.value, + function = self._handler_institutional_record_sync) + self.can_interface.register_receiving_publication_function(channel_id = CanChannels.dd_sync_broadcast_ch_id, + message_id = MsgIds.MSG_ID_DD_NVM_SEND_USAGE_INFO_RECORD.value, + function = self._handler_usage_info_record_sync) + + self.system_records_timestamp = 0 #: The timestamp of the latest System Records message + self.service_records_timestamp = 0 #: The timestamp of the latest Service Records message + self.calibration_records_timestamp = 0 #: The timestamp of the latest Calibration Records message + self.institutional_records_timestamp = 0 #: The timestamp of the latest Institutional Records message + self.usage_info_records_timestamp = 0 #: The timestamp of the latest Usage Information Records message + + self.system_records = { } #: The System Records data in dictionary format + self.service_records = { } #: The Service Records data in dictionary format + self.calibration_records = { } #: The Calibration Records data in dictionary format + self.institutional_records = { } #: The Institutional Records data in dictionary format + self.usage_info_records = { } #: The Usage Information Records data in dictionary format + + self.pager_system_record = 0 + self.pager_service_record = 0 + self.pager_calibration_record = 0 + self.pager_institutional_record = 0 + self.pager_usage_info_record = 0 + + for sys_record in dd_enum_repository.SystemRecordFields: + self.system_records[sys_record.name] = None + + for serv_record in dd_enum_repository.ServiceRecordFields: + self.service_records[serv_record.name] = None + + for cal_record in dd_enum_repository.CalibrationRecordFields: + self.calibration_records[cal_record.name] = None + + for inst_record in dd_enum_repository.InstitutionalRecordFields: + self.institutional_records[inst_record.name] = None + + for usage_record in dd_enum_repository.UsageInformationRecordFields: + self.usage_info_records[usage_record.name] = None + + + @publish(["msg_id_dd_nvm_send_system_record", "system_records", "system_records_timestamp"]) + def _handler_system_record_sync(self, message, timestamp = 0.0): + """ + Handles published DD System Record data messages. DD System Records are captured + for reference. + + @param message: published data message + @return: none + """ + # Get the payload related values + msg_list =[] + msg_list.append(('current_page', DataTypes.U32)) + msg_list.append(('all_pages', DataTypes.U32)) + msg_list.append(('payload_count', DataTypes.U32)) + + result = self.process_into_vars(decoder_list = msg_list, + message = message) + + # Get the record data + record_list = [] + for i in range(0, result['payload_count']): + sys_record = dd_enum_repository.SystemRecordFields(i + self.pager_system_record) + if sys_record.multichar_length > 1: + name = f'{sys_record.name}_1' + else: + name = sys_record.name + record_list.append((name, sys_record.datatype)) + self.process_into_dict(dict_to_update = self.system_records, + decoder_list = record_list, + message = message, + start_from_byte = len(msg_list) * DataTypes.U32.size) + + # Increase the pager by the payload count to know where the next message should resume, or reset when it's the last message + if result['current_page'] == result['all_pages']: + self.pager_system_record = 0 + else: + self.pager_system_record =+ result['payload_count'] + + self.system_records_timestamp = timestamp + + + @publish(["msg_id_dd_nvm_send_service_record", "service_records", "service_records_timestamp"]) + def _handler_service_record_sync(self, message, timestamp = 0.0): + """ + Handles published DD Service Record data messages. DD Service Records are captured + for reference. + + @param message: published data message + @return: none + """ + _generic_handler(self = self, + message = message, + service_name = dd_enum_repository.ServiceRecordFields, + pager_record = self.pager_service_record) + # # Get the payload related values + # msg_list =[] + # msg_list.append(('current_page', DataTypes.U32)) + # msg_list.append(('all_pages', DataTypes.U32)) + # msg_list.append(('payload_count', DataTypes.U32)) + + # result = self.process_into_vars(decoder_list = msg_list, + # message = message) + + # # Get the record data + # record_list = [] + # for i in range(0, result['payload_count']): + # record = dd_enum_repository.ServiceRecordFields(i + self.pager_service_record) + # record_list.append((record.name, record.datatype)) + # self.process_into_dict(dict_to_update = self.service_records, + # decoder_list = record_list, + # message = message, + # start_from_byte = len(msg_list) * DataTypes.U32.size) + + # # Increase the pager by the payload count to know where the next message should resume, or reset when it's the last message + # if result['current_page'] == result['all_pages']: + # self.pager_service_record = 0 + # else: + # self.pager_service_record =+ result['payload_count'] + + self.service_records_timestamp = timestamp + + + @publish(["msg_id_dd_nvm_send_calibration_record", "calibration_records", "calibration_records_timestamp"]) + def _handler_calibration_record_sync(self, message, timestamp = 0.0): + """ + Handles published DD Calibration Record data messages. DD Calibration Records are captured + for reference. + + @param message: published data message + @return: none + """ + dd_enum_repository.CalibrationRecordFields + _generic_handler(self = self, + message = message, + service_name = dd_enum_repository.CalibrationRecordFields, + pager_record = self.pager_calibration_record) + self.calibration_records_timestamp = timestamp + + + @publish(["msg_id_dd_nvm_send_institutional_record", "institutional_records", "institutional_records_timestamp"]) + def _handler_institutional_record_sync(self, message, timestamp = 0.0): + """ + Handles published DD Institutional Record data messages. DD Institutional Records are captured + for reference. + + @param message: published data message + @return: none + """ + _generic_handler(self = self, + message = message, + service_name = dd_enum_repository.InstitutionalRecordFields, + pager_record = self.pager_institutional_record) + self.institutional_records_timestamp = timestamp + + + @publish(["msg_id_dd_nvm_send_usage_info_record", "usage_info_records", "usage_info_records_timestamp"]) + def _handler_usage_info_record_sync(self, message, timestamp = 0.0): + """ + Handles published DD Usage Information Record data messages. DD Usage Information Records are captured + for reference. + + @param message: published data message + @return: none + """ + _generic_handler(self = self, + message = message, + service_name = dd_enum_repository.ServiceRecordFields, + pager_record = self.pager_usage_info_record) + self.usage_info_records_timestamp = timestamp + + + def cmd_initiate_service_mode(self) -> int: + """ + Constructs and sends a request to change to Service operation mode via CAN bus. + Constraints: + Must be logged into DD. + Transition from current to requested op mode must be legal. + + @return: 1 if successful, zero otherwise + """ + service_mode = dd_enum_repository.DDOpModes.MODE_SERV + + payload = integer_to_bytearray(service_mode.value) + + return cmd_generic_override( + payload = payload, + reset = None, + channel_id = CanChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_SET_OPERATION_MODE_OVERRIDE_REQUEST, + entity_name = 'DD Operation Mode', + override_text = f'set to {service_mode.name}', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_request_system_records(self) -> int: + """ + Constructs and sends a request for System Records. + Constraints: + Must be logged into DD. + Must be in Service mode. + + @return: 1 if successful, zero otherwise + """ + payload = integer_to_bytearray(dd_enum_repository.RecordTypes.SYSTEM_RECORD.value) + + return cmd_generic_override( + payload = payload, + reset = None, + channel_id = CanChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_NVM_GET_RECORD, + entity_name = f'DD System Record request', + override_text = '', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_request_service_records(self) -> int: + """ + Constructs and sends a request for Service Records. + Constraints: + Must be logged into DD. + Must be in Service mode. + + @return: 1 if successful, zero otherwise + """ + payload = integer_to_bytearray(dd_enum_repository.RecordTypes.SERVICE_RECORD.value) + + return cmd_generic_override( + payload = payload, + reset = None, + channel_id = CanChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_NVM_GET_RECORD, + entity_name = f'DD Service Record request', + override_text = '', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_request_calibration_records(self) -> int: + """ + Constructs and sends a request for Calibration Records. + Constraints: + Must be logged into DD. + Must be in Service mode. + + @return: 1 if successful, zero otherwise + """ + payload = integer_to_bytearray(dd_enum_repository.RecordTypes.CALIBRATION_RECORD.value) + + return cmd_generic_override( + payload = payload, + reset = None, + channel_id = CanChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_NVM_GET_RECORD, + entity_name = f'DD Calibration Record request', + override_text = '', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_request_institutional_records(self) -> int: + """ + Constructs and sends a request for Institutional Records. + Constraints: + Must be logged into DD. + Must be in Service mode. + + @return: 1 if successful, zero otherwise + """ + payload = integer_to_bytearray(dd_enum_repository.RecordTypes.INSTITUTIONAL_RECORD.value) + + return cmd_generic_override( + payload = payload, + reset = None, + channel_id = CanChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_NVM_GET_RECORD, + entity_name = f'DD Institutional Record request', + override_text = '', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_request_usage_information_records(self) -> int: + """ + Constructs and sends a request for Usage Information Records. + Constraints: + Must be logged into DD. + Must be in Service mode. + + @return: 1 if successful, zero otherwise + """ + payload = integer_to_bytearray(dd_enum_repository.RecordTypes.USAGE_INFORMATION_RECORD.value) + + return cmd_generic_override( + payload = payload, + reset = None, + channel_id = CanChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_NVM_GET_RECORD, + entity_name = f'DD Usage Information Record request', + override_text = '', + logger = self.logger, + can_interface = self.can_interface) + + + def cmd_set_system_records(self, + part_number: chr[10], + serial_number: chr[20], + manufacturing_location: int, + manufacturing_date: int) -> int: + """ + Constructs and sends a command for setting the System Records. + Constraints: + Must be logged into DD. + Must be in Service mode. + + @return: 1 if successful, zero otherwise + """ + payload = integer_to_bytearray(1) # Current Page + payload += integer_to_bytearray(1) # All Page Count + payload += integer_to_bytearray(dd_enum_repository.SystemRecordFields.NUM_OF_SYSTEM_RECORD_FIELDS.value) # Payload count + for c in part_number: + payload += byte_to_bytearray(c) + for c in serial_number: + payload += byte_to_bytearray(c) + payload += integer_to_bytearray(manufacturing_location) + payload += integer_to_bytearray(manufacturing_date) + crc = '' + payload += integer_to_bytearray(crc) + + return cmd_generic_override( + payload = payload, + reset = None, + channel_id = CanChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_DD_NVM_SET_SYSTEM_RECORD, + entity_name = f'New DD System Record', + override_text = 'being set', + logger = self.logger, + can_interface = self.can_interface) + + + +# ================================================= Private Methods ================================================= +def _generic_handler(self: DDRecords, message, service_name, pager_record): + # Get the payload related values + msg_list =[] + msg_list.append(('current_page', DataTypes.U32)) + msg_list.append(('all_pages', DataTypes.U32)) + msg_list.append(('payload_count', DataTypes.U32)) + result = self.process_into_vars(decoder_list = msg_list, + message = message) + + # Get the record data + record_list = [] + for i in range(0, result['payload_count']): + record = service_name(i + pager_record) + record_list.append((record.name, record.datatype)) + self.process_into_dict(dict_to_update = self.service_records, + decoder_list = record_list, + message = message, + start_from_byte = len(msg_list) * DataTypes.U32.size) + + # Increase the pager by the payload count to know where the next message should resume, or reset when it's the last message + if result['current_page'] == result['all_pages']: + pager_record = 0 + else: + pager_record =+ result['payload_count'] \ No newline at end of file Index: leahi_dialin/fp/modules/events.py =================================================================== diff -u -r1f2bf6d939eb4033dbedb7d7005494cc12fccbc6 -r1f7b5ac840adf6740b023706fcb73691c33a9be7 --- leahi_dialin/fp/modules/events.py (.../events.py) (revision 1f2bf6d939eb4033dbedb7d7005494cc12fccbc6) +++ leahi_dialin/fp/modules/events.py (.../events.py) (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -149,7 +149,7 @@ event_id = struct.unpack(DataTypes.U32.unpack_attrib(), bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] - + # Convert the event ID to enum compensated_event_id = event_id - dd_enum_repository.DDEventList.NUM_OF_DD_EVENT_IDS.value event_enum = fp_enum_repository.FPEventList(compensated_event_id) @@ -215,7 +215,7 @@ last_op_mode_message = op_modes_list[-1] # Check if this is not the very first Sub Mode Change message - if len(sub_mode_list != 0): + if len(sub_mode_list) != 0: # Get the timestamps of the last messages of both list for comparison prev_op_mode_timestamp = datetime.strptime(last_op_mode_message[0], '%Y-%m-%d %H:%M:%S.%f') prev_sub_mode_timestamp = datetime.strptime(sub_mode_list[-1][0], '%Y-%m-%d %H:%M:%S.%f') Index: leahi_dialin/td/modules/events.py =================================================================== diff -u -r3e6eac0e751fd74569068bc8754f0828cd4fcd84 -r1f7b5ac840adf6740b023706fcb73691c33a9be7 --- leahi_dialin/td/modules/events.py (.../events.py) (revision 3e6eac0e751fd74569068bc8754f0828cd4fcd84) +++ leahi_dialin/td/modules/events.py (.../events.py) (revision 1f7b5ac840adf6740b023706fcb73691c33a9be7) @@ -210,7 +210,7 @@ last_op_mode_message = op_modes_list[-1] # Check if this is not the very first Sub Mode Change message - if len(sub_mode_list != 0): + if len(sub_mode_list) != 0: # Get the timestamps of the last messages of both list for comparison prev_op_mode_timestamp = datetime.strptime(last_op_mode_message[0], '%Y-%m-%d %H:%M:%S.%f') prev_sub_mode_timestamp = datetime.strptime(sub_mode_list[-1][0], '%Y-%m-%d %H:%M:%S.%f')