########################################################################### # # 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 # ================================================== Enum Creators: DataTypes ================================================== @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 NUM_OF_DATA_TYPES = (9, 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': [], } # ================================================== Enum Creators: Record Base ================================================== @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 # ================================================== Enum Creators: Record Sub Fields ================================================== @unique class CalibRecordAccelerometerFields(RecordsBaseEnum): 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(RecordsBaseEnum): 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(RecordsBaseEnum): 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(RecordsBaseEnum): 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': [], } # ================================================== Enum Creators: Record Fields ================================================== @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): IS_RO_FEATURED = (0, DataTypes.BOOL) # Is RO featured or defeatured IS_RO_BOOST_PUMP_ADDED = (1, DataTypes.BOOL) # Is RO have boost pump or not TOP_LEVEL_PN = (2, DataTypes.U08, 10) # Top level part number TOP_LEVEL_SN = (3, DataTypes.U08, 20) # Top level serial number MFG_LOCATION = (4, DataTypes.U08) # Manufacturing Location MFG_DATE = (5, DataTypes.U32) # Manufacturing Date CRC = (6, DataTypes.U16) # CRC NUM_OF_SYSTEM_RECORD_FIELDS = (7, 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(RecordsBaseEnum): IS_HDF_ONLINE_FLUID = (0, DataTypes.BOOL) # DD Is HDF Online WATER_RECOVERY = (1, DataTypes.U32) # DD Water Recovery SERVICE_LOC = (2, DataTypes.U08) # DD service location LAST_SERVICE_EPOCH_DATE = (3, DataTypes.U32) # DD last service date in epoch SERVICE_INTERVAL_SECONDS = (4, DataTypes.U32) # DD service interval in seconds LAST_RESET_TIME_EPOCH = (5, DataTypes.U32) # Last time the record was reset in epoch CRC = (6, DataTypes.U16) # CRC NUM_OF_SERVICE_RECORD_FIELDS = (7, DataTypes.NONE) # Number of Service Record Fields ServiceRecordFields._str_list = { # Official Name : Accepted strings 'IS_HDF_ONLINE_FLUID': [], 'WATER_RECOVERY': [], 'SERVICE_LOC': [], 'LAST_SERVICE_EPOCH_DATE': [], 'SERVICE_INTERVAL_SECONDS': [], 'LAST_RESET_TIME_EPOCH': [], 'CRC': [], 'NUM_OF_SERVICE_RECORD_FIELDS': [], } def get_calibration_record_fields() -> RecordsBaseEnum: # Creating the enum members list i = 0 members = {} for pres_sensor in DDPressureSensorNames: if 'num_' in pres_sensor.name.lower(): continue for field_name in CalibRecordSensorFields: if 'num_' in field_name.name.lower(): continue members[f'PRES__{pres_sensor.name}__{field_name.name}'] = (i, field_name.datatype()) i += 1 for temp_sensor in DDTemperatureSensorNames: if 'num_' in temp_sensor.name.lower(): continue for field_name in CalibRecordSensorFields: if 'num_' in field_name.name.lower(): continue members[f'TEMP__{temp_sensor.name}__{field_name.name}'] = (i, field_name.datatype()) i += 1 for conc_pump in DDConcentratePumpNames: if 'num_' in conc_pump.name.lower(): continue for field_name in CalibRecordSensorFields: if 'num_' in field_name.name.lower(): continue members[f'CONC__{conc_pump.name}__{field_name.name}'] = (i, field_name.datatype()) i += 1 for dial_pump in DDDialysatePumpNames: if 'num_' in dial_pump.name.lower(): continue elif 'd48' in dial_pump.name.lower(): members[f'DIAL__{dial_pump.name}_TARGET_SPEED'] = (i, DataTypes.F32) i += 1 for field_name in CalibRecordSensorFields: if 'num_' in field_name.name.lower(): continue members[f'DIAL__{dial_pump.name}__{field_name.name}'] = (i, field_name.datatype()) i += 1 for acid in AcidTypes: if 'num_' in acid.name.lower(): continue for field_name in CalibRecordConcentrateFields: if 'num_' in field_name.name.lower(): continue members[f'ACID__{acid.name}__{field_name.name}'] = (i, field_name.datatype()) i += 1 for bicarb in BicarbTypes: if 'num_' in bicarb.name.lower(): continue for field_name in CalibRecordConcentrateFields: if 'num_' in field_name.name.lower(): continue members[f'BICARB__{bicarb.name}__{field_name.name}'] = (i, field_name.datatype()) i += 1 for field_name in CalibRecordAccelerometerFields: if 'num_' in field_name.name.lower(): continue members[f'ACCEL__{field_name.name}'] = (i, field_name.datatype()) i += 1 for field_name in CalibRecordBloodLeakFields: if 'num_' in field_name.name.lower(): continue members[f'BLOOD_LEAK__{field_name.name}'] = (i, field_name.datatype()) i += 1 members[f'NUM_OF_CALIBRATION_RECORD_FIELDS'] = (i, DataTypes.NONE) # Enum creation CalibrationRecordFields = RecordsBaseEnum('CalibrationRecordFields', members,) # Setting the _str_list values for the enum CalibrationRecordFields._str_list = {} for member in members: CalibrationRecordFields._str_list[member] = [] return CalibrationRecordFields @unique class InstitutionalRecordFields(RecordsBaseEnum): 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 MIN_ACID_CONCENTRATE = (4, DataTypes.U32) # Min Acid concentrate MAX_ACID_CONCENTRATE = (5, DataTypes.U32) # Max Acid concentrate MIN_BICARB_CARTRIDGE_SIZE_G = (6, DataTypes.U32) # Min Bicarbonate cartridge size in grams MAX_BICARB_CARTRIDGE_SIZE_G = (7, DataTypes.U32) # Max Bicarbonate cartridge size in grams MIN_SODIUM_MEQPL = (8, DataTypes.U32) # Min sodium in mEq/L MAX_SODIUM_MEQPL = (9, DataTypes.U32) # Max sodium in mEq/L MIN_BICARBONATE_MEQPL = (10, DataTypes.U32) # Min bicarbonate in mEq/L MAX_BICARBONATE_MEQPL = (11, DataTypes.U32) # Max bicarbonate in mEq/L MIN_RO_REJECTION_RATIO_PCT = (12, DataTypes.U32) # Min RO rejection ratio in percent DISINFECTION_FREQUENCY = (13, DataTypes.U32) # Disinfection days between cycles DISINFECTION_CYCLE_TIME = (14, DataTypes.F32) # Disinfection Cycle Time MIN_INLET_WATER_CIND_AKARN_LIMIT_USPCM = (15, DataTypes.F32) # Min inlet water conductivity alarm limit in uS/cm MAX_INLET_WATER_CIND_AKARN_LIMIT_USPCM = (16, DataTypes.F32) # Max inlet water conductivity alarm limit in uS/cm ACID_CONCENTRATE_JUG_SIZE_L = (17, DataTypes.F32) # acid concentrate jug size in Liters MIN_ACID_ALARM_LIMIT_PCT = (18, DataTypes.F32) # Min acid alarm limit in percent MIN_BICARB_ALARM_LIMIT_PCT = (19, DataTypes.F32) # Min bicarbonate alarm limit in percent POST_TREAT_DRAIN_OPTION = (20, DataTypes.U32) # Dialysate Post Treatment Drain OptionĀ  POST_TREAT_DRY_BICARB_OPTION = (21, DataTypes.U32) # Dry Bicarbonate Post Treatment OptionĀ  CALIBRATION_TIME = (22, DataTypes.U32) # Calibration time in epoch. CRC = (23, DataTypes.U16) # CRC NUM_OF_INSTITUTIONAL_RECORD_FIELDS = (24, 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(RecordsBaseEnum): 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': [], }