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