########################################################################### # # Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. # # THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN # WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. # # @file generic_defs.py # # @author (last) Zoltan Miskolci # @date (last) 04-May-2026 # @author (last) Zoltan Miskolci # @date (last) 01-May-2026 # ############################################################################ 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 # 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 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 return obj def unpack_attrib(self) -> str: return self.unpack_fmt def size(self) -> int: return self.unpack_size DataTypes._str_list = { # Official Name : Accepted strings 'NONE': [], 'U32': [], 'S32': [], 'F32': [], 'BOOL': ['boolean'], 'U08': ['u8'], 'U16': [], 'S16': [], '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': [], }