Index: leahi_dialin/common/__init__.py =================================================================== diff -u -r20c821bd230fc7689a0275a2918981669ff5cc19 -rc1bff8da59cff294d67d90dd1e1f102dd5b65466 --- leahi_dialin/common/__init__.py (.../__init__.py) (revision 20c821bd230fc7689a0275a2918981669ff5cc19) +++ leahi_dialin/common/__init__.py (.../__init__.py) (revision c1bff8da59cff294d67d90dd1e1f102dd5b65466) @@ -21,7 +21,8 @@ else: from .alarm_defs import * from .alarm_priorities import * - from .td_defs_proxy import td_enum_repository from .dd_defs_proxy import dd_enum_repository + from .disp_defs_proxy import disp_enum_repository from .fp_defs_proxy import fp_enum_repository + from .td_defs_proxy import td_enum_repository from .ui_defs import * Index: leahi_dialin/common/dd_defs.py =================================================================== diff -u -r465679409a5fe6f6007ddffca1fd3e89ead9d9c4 -rc1bff8da59cff294d67d90dd1e1f102dd5b65466 --- leahi_dialin/common/dd_defs.py (.../dd_defs.py) (revision 465679409a5fe6f6007ddffca1fd3e89ead9d9c4) +++ leahi_dialin/common/dd_defs.py (.../dd_defs.py) (revision c1bff8da59cff294d67d90dd1e1f102dd5b65466) @@ -521,7 +521,7 @@ DDTemperatureSensorNames._str_list = { # Official Name : Accepted strings - 'D16_TEMP': ['d1'], + 'D1_TEMP': ['d1'], 'D78_TEMP': ['d78'], 'D4_TEMP': ['d4'], 'D50_TEMP': ['d50'], @@ -537,6 +537,7 @@ 'D99_AVG_TEMP': ['d99 avg', 'd99 average'], 'D28_AVG_TEMP': ['d28 avg', 'd28 average'], 'D30_AVG_TEMP': ['d39 avg', 'd39 average'], + 'D1_AVG_TEMP': ['d1 avg', 'd1 average'], 'D9_TEMP': ['d9'], 'D66_TEMP': ['d66'], 'D51_TEMP': ['d51'], Index: leahi_dialin/common/generic_defs.py =================================================================== diff -u -rfa06efd219892c67eabb3099a4af3dea4304edb5 -rc1bff8da59cff294d67d90dd1e1f102dd5b65466 --- leahi_dialin/common/generic_defs.py (.../generic_defs.py) (revision fa06efd219892c67eabb3099a4af3dea4304edb5) +++ leahi_dialin/common/generic_defs.py (.../generic_defs.py) (revision c1bff8da59cff294d67d90dd1e1f102dd5b65466) @@ -144,7 +144,7 @@ @unique class CalibRecordSensorFields(RecordsBaseEnum): - FORTH_ORDER_COEFF = (0, DataTypes.F32) # Sensor's Fourth order coefficient + FOURTH_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 @@ -264,8 +264,8 @@ 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) + elif 'd12' 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(): Index: leahi_dialin/dd/modules/records.py =================================================================== diff -u -rfa06efd219892c67eabb3099a4af3dea4304edb5 -rc1bff8da59cff294d67d90dd1e1f102dd5b65466 --- leahi_dialin/dd/modules/records.py (.../records.py) (revision fa06efd219892c67eabb3099a4af3dea4304edb5) +++ leahi_dialin/dd/modules/records.py (.../records.py) (revision c1bff8da59cff294d67d90dd1e1f102dd5b65466) @@ -20,7 +20,7 @@ from time import sleep # Project imports -from leahi_dialin.common import dd_enum_repository +from leahi_dialin.common import dd_enum_repository, disp_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 @@ -36,15 +36,6 @@ DD interface containing pressure related commands. """ - CALIB_RECORDS_PRESSURE_SENSORS = 'pressure_sensors' - CALIB_RECORDS_TEMPERATURE_SENSORS = 'temperature_sensors' - CALIB_RECORDS_CONCENTRATE_PUMPS = 'concentrate_pump' - CALIB_RECORDS_DIALYSATE_PUMPS = 'dialysate_pumps' - CALIB_RECORDS_ACID_CONCENTRATE = 'acid_concentrate' - CALIB_RECORDS_BICARB_CONCENTRATE = 'bicarb_concentrate' - CALIB_RECORDS_ACCELEROMETER = 'accelerometer' - CALIB_RECORDS_BLOOD_LEAK = 'blood_leak' - def __init__(self, can_interface: CanMessenger, logger: Logger): """ @param can_interface: The CanMessenger object @@ -629,7 +620,7 @@ can_interface = self.can_interface) - def cmd_set_calibration_records(self, calibration_records: dict) -> int: + def cmd_set_calibration_records(self, calibration_records: dict={}) -> int: """ Constructs and sends a command for setting the Calibration Records. Constraints: @@ -640,72 +631,180 @@ @return: 1 if successful, zero otherwise """ msg_id_pairing = { - self.CALIB_RECORDS_PRESSURE_SENSORS: MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_PRESSURE_SENSOR, - self.CALIB_RECORDS_TEMPERATURE_SENSORS: MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_TEMP_SENSOR, - self.CALIB_RECORDS_CONCENTRATE_PUMPS: MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_D48_PUMP, - self.CALIB_RECORDS_DIALYSATE_PUMPS: MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_CONC_PUMP, - self.CALIB_RECORDS_ACID_CONCENTRATE: MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_ACID_CONCENTRATE, - self.CALIB_RECORDS_BICARB_CONCENTRATE: MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_BICARB_CONCENTRATE, - self.CALIB_RECORDS_ACCELEROMETER: MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_ACCEL_SENSOR, - self.CALIB_RECORDS_BLOOD_LEAK: MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_BLOOD_LEAK_SENSOR, + 'PRES': MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_PRESSURE_SENSOR, + 'TEMP': MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_TEMP_SENSOR, + 'CONC': MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_D48_PUMP, + 'DIAL': MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_CONC_PUMP, + 'ACID': MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_ACID_CONCENTRATE, + 'BICARB': MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_BICARB_CONCENTRATE, + 'ACCEL': MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_ACCEL_SENSOR, + 'BLOOD_LEAK': MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_BLOOD_LEAK_SENSOR, } - # Make a dictionary to store all the send functions for later send send_data = [] - for key in calibration_records: - if key.lower() in [self.CALIB_RECORDS_PRESSURE_SENSORS, self.CALIB_RECORDS_TEMPERATURE_SENSORS, self.CALIB_RECORDS_CONCENTRATE_PUMPS, self.CALIB_RECORDS_DIALYSATE_PUMPS]: - for sensor in calibration_records[key]: - # Exception handling as D12 has an extra field (target speed) - if sensor in [dd_enum_repository.DDDialysatePumpNames.D12_PUMP]: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_sensor, - sensor_enum = sensor, - msg_id = MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_D12_PUMP, - dialysate_pump_target_speed = calibration_records[key][sensor]['target_speed'], - forth_order_coeff = calibration_records[key][sensor]['forth_order_coeff'], - third_order_coeff = calibration_records[key][sensor]['third_order_coeff'], - second_order_coeff = calibration_records[key][sensor]['second_order_coeff'], - gain = calibration_records[key][sensor]['gain'], - offset = calibration_records[key][sensor]['offset'], - calibration_time = calibration_records[key][sensor]['calibration_time'])) - else: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_sensor, - sensor_enum = sensor, - msg_id = msg_id_pairing[key], - forth_order_coeff = calibration_records[key][sensor]['forth_order_coeff'], - third_order_coeff = calibration_records[key][sensor]['third_order_coeff'], - second_order_coeff = calibration_records[key][sensor]['second_order_coeff'], - gain = calibration_records[key][sensor]['gain'], - offset = calibration_records[key][sensor]['offset'], - calibration_time = calibration_records[key][sensor]['calibration_time'])) - elif key.lower() in [self.CALIB_RECORDS_ACID_CONCENTRATE, self.CALIB_RECORDS_BICARB_CONCENTRATE]: - for sensor in calibration_records[key]: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_concentrate, - msg_id = msg_id_pairing[key], - concentrate_mix_ratio = calibration_records[key][sensor]['concentrate_mix_ratio'], - volume_ml = calibration_records[key][sensor]['volume_ml'], - conductivity_uspcm = calibration_records[key][sensor]['conductivity_uspcm'], - temperature_c = calibration_records[key][sensor]['temperature_c'], - calibration_time = calibration_records[key][sensor]['calibration_time'])) - elif key.lower() in [self.CALIB_RECORDS_ACCELEROMETER]: - for sensor in calibration_records[key]: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_accelerometer, - msg_id = msg_id_pairing[key], - accel_x_offset = calibration_records[key][sensor]['accel_x_offset'], - accel_y_offset = calibration_records[key][sensor]['accel_y_offset'], - accel_z_offset = calibration_records[key][sensor]['accel_z_offset'], - calibration_time = calibration_records[key][sensor]['calibration_time'])) - elif key.lower() in [self.CALIB_RECORDS_BLOOD_LEAK]: - for sensor in calibration_records[key]: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_blood_leak, - msg_id = msg_id_pairing[key], - set_point = calibration_records[key][sensor]['set_point'], - calibration_time = calibration_records[key][sensor]['calibration_time'])) - + checked = [] + for record_enum in dd_enum_repository.CalibrationRecordFields: + record_parts = record_enum.name.split('__') + group = record_parts[0] + + # If a message already sent, then just go to the next value + if 'NUM_' in group or \ + group in checked or \ + record_parts[1] in checked: + continue + + if group in ['PRES', 'TEMP', 'CONC', 'DIAL']: + # Set the sensor name + if group == 'PRES': + sensor = dd_enum_repository.DDPressureSensorNames.from_str(record_parts[1]) + elif group == 'TEMP': + sensor = dd_enum_repository.DDTemperatureSensorNames.from_str(record_parts[1]) + elif group == 'CONC': + sensor = dd_enum_repository.DDConcentratePumpNames.from_str(record_parts[1]) + elif group == 'DIAL': + sensor = dd_enum_repository.DDDialysatePumpNames.from_str(record_parts[1]) + else: + sensor = 'UNKNOWN' + + # Set the arguments for the call + args = [] + kwargs = {} + target_speed_entry_name = f'{group}__{sensor.name}__TARGET_SPEED' + fourth_order_coeff_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordSensorFields.FOURTH_ORDER_COEFF.name}' + third_order_coeff_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordSensorFields.THIRD_ORDER_COEFF.name}' + second_order_coeff_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordSensorFields.SECOND_ORDER_COEFF.name}' + gain_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordSensorFields.GAIN.name}' + offset_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordSensorFields.OFFSET.name}' + calibration_time_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordSensorFields.CALIBRATION_TIME.name}' + + kwargs['sensor_enum'] = sensor + if sensor == dd_enum_repository.DDDialysatePumpNames.D12_PUMP: + kwargs['msg_id'] = MsgIds.MSG_ID_UI_DD_NVM_SET_CAL_D12_PUMP + else: + kwargs['msg_id'] = msg_id_pairing[group] + + if target_speed_entry_name in calibration_records and calibration_records[target_speed_entry_name] is not None: + kwargs['dialysate_pump_target_speed'] = calibration_records[target_speed_entry_name] + + if fourth_order_coeff_entry_name in calibration_records and calibration_records[fourth_order_coeff_entry_name] is not None: + kwargs['forth_order_coeff'] = calibration_records[fourth_order_coeff_entry_name] + + if third_order_coeff_entry_name in calibration_records and calibration_records[third_order_coeff_entry_name] is not None: + kwargs['third_order_coeff'] = calibration_records[third_order_coeff_entry_name] + + if second_order_coeff_entry_name in calibration_records and calibration_records[second_order_coeff_entry_name] is not None: + kwargs['second_order_coeff'] = calibration_records[second_order_coeff_entry_name] + + if gain_entry_name in calibration_records and calibration_records[gain_entry_name] is not None: + kwargs['gain'] = calibration_records[gain_entry_name] + + if offset_entry_name in calibration_records and calibration_records[offset_entry_name] is not None: + kwargs['offset'] = calibration_records[offset_entry_name] + + if calibration_time_entry_name in calibration_records and calibration_records[calibration_time_entry_name] is not None: + kwargs['calibration_time'] = calibration_records[calibration_time_entry_name] + + checked.append(record_parts[1]) + # Skip sending if dictionary is provided but all entry for the sensor was None (except sensor_enum and MSG_ID, because those are neccesary) + if calibration_records != {} and len(kwargs) == 2: + continue + + # Create the send data function + send_data.append(partial(self.cmd_set_calibration_records_sensor, *args, **kwargs)) + + elif group in ['ACID', 'BICARB']: + if group == 'ACID': + sensor = disp_enum_repository.AcidTypes.from_str(record_parts[1]) + elif group == 'BICARB': + sensor = disp_enum_repository.BicarbTypes.from_str(record_parts[1]) + else: + sensor = 'unknown' + + # Set the arguments for the call + args = [] + kwargs = {} + concentrate_mix_ratio_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordConcentrateFields.CONCENTRATE_MIX_RATIO.name}' + volume_ml_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordConcentrateFields.FULL_BOTTLE_VOLUME_ML.name}' + conductivity_uspcm_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordConcentrateFields.CONDUCTIVITY_USPCM.name}' + temperature_c_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordConcentrateFields.BOTTLE_TEMPERATURE_C.name}' + calibration_time_entry_name = f'{group}__{sensor.name}__{dd_enum_repository.CalibRecordConcentrateFields.CALIBRATION_TIME.name}' + + kwargs['msg_id'] = msg_id_pairing[group] + if concentrate_mix_ratio_entry_name in calibration_records and calibration_records[concentrate_mix_ratio_entry_name] is not None: + kwargs['concentrate_mix_ratio'] = calibration_records[concentrate_mix_ratio_entry_name] + + if volume_ml_entry_name in calibration_records and calibration_records[volume_ml_entry_name] is not None: + kwargs['volume_ml'] = calibration_records[volume_ml_entry_name] + + if conductivity_uspcm_entry_name in calibration_records and calibration_records[conductivity_uspcm_entry_name] is not None: + kwargs['conductivity_uspcm'] = calibration_records[conductivity_uspcm_entry_name] + + if temperature_c_entry_name in calibration_records and calibration_records[temperature_c_entry_name] is not None: + kwargs['temperature_c'] = calibration_records[temperature_c_entry_name] + + if calibration_time_entry_name in calibration_records and calibration_records[calibration_time_entry_name] is not None: + kwargs['calibration_time'] = calibration_records[calibration_time_entry_name] + + checked.append(record_parts[1]) + # Skip sending if dictionary is provided but all entry for the sensor was None (except MSG_ID, because that is neccesary) + if calibration_records != {} and len(kwargs) == 1: + continue + + # Store the function but do not execute it + send_data.append(partial(self.cmd_set_calibration_records_concentrate, *args, **kwargs)) + + elif group in ['ACCEL']: + # Set the arguments for the call + args = [] + kwargs = {} + accel_x_offset_entry_name = f'{group}__{dd_enum_repository.CalibRecordAccelerometerFields.ACCEL_X_OFFSET.name}' + accel_y_offset_entry_name = f'{group}__{dd_enum_repository.CalibRecordAccelerometerFields.ACCEL_Y_OFFSET.name}' + accel_z_offset_entry_name = f'{group}__{dd_enum_repository.CalibRecordAccelerometerFields.ACCEL_Z_OFFSET.name}' + calibration_time_entry_name = f'{group}__{dd_enum_repository.CalibRecordAccelerometerFields.CALIBRATION_TIME.name}' + + kwargs['msg_id'] = msg_id_pairing[group] + if accel_x_offset_entry_name in calibration_records and calibration_records[accel_x_offset_entry_name] is not None: + kwargs['accel_x_offset'] = calibration_records[accel_x_offset_entry_name] + + if accel_y_offset_entry_name in calibration_records and calibration_records[accel_y_offset_entry_name] is not None: + kwargs['accel_y_offset'] = calibration_records[accel_y_offset_entry_name] + + if accel_z_offset_entry_name in calibration_records and calibration_records[accel_z_offset_entry_name] is not None: + kwargs['accel_z_offset'] = calibration_records[accel_z_offset_entry_name] + + if calibration_time_entry_name in calibration_records and calibration_records[calibration_time_entry_name] is not None: + kwargs['calibration_time'] = calibration_records[calibration_time_entry_name] + + checked.append(group) + # Skip sending if dictionary is provided but all entry for the sensor was None (except MSG_ID, because that is neccesary) + if calibration_records != {} and len(kwargs) == 1: + continue + + # Store the function but do not execute it + send_data.append(partial(self.cmd_set_calibration_records_accelerometer, *args, **kwargs)) + + elif group in ['BLOOD_LEAK']: + # Set the arguments for the call + args = [] + kwargs = {} + set_point_entry_name = f'{group}__{dd_enum_repository.CalibRecordBloodLeakFields.SET_POINT.name}' + calibration_time_entry_name = f'{group}__{dd_enum_repository.CalibRecordBloodLeakFields.CALIBRATION_TIME.name}' + + kwargs['msg_id'] = msg_id_pairing[group] + if set_point_entry_name in calibration_records and calibration_records[set_point_entry_name] is not None: + kwargs['set_point'] = calibration_records[set_point_entry_name] + + if calibration_time_entry_name in calibration_records and calibration_records[calibration_time_entry_name] is not None: + kwargs['calibration_time'] = calibration_records[calibration_time_entry_name] + + checked.append(group) + # Skip sending if dictionary is provided but all entry for the sensor was None (except MSG_ID, because that is neccesary) + if calibration_records != {} and len(kwargs) == 1: + continue + + # Store the function but do not execute it + send_data.append(partial(self.cmd_set_calibration_records_blood_leak, *args, **kwargs)) + # Execute the stored functions one by one # Remove the ones that got 1 (successfully recieved) as response # Retry the ones that are failed 2 more times @@ -733,47 +832,34 @@ """ # Make a dictionary to store all the send functions for later send send_data = [] - total_payload = b'' for record_enum in dd_enum_repository.InstitutionalRecordFields: # Set the enum_id to identify which parameter is being sent U08 - 1 byte - 0->255 !! payload = byte_to_bytearray(record_enum.value) - if record_enum == dd_enum_repository.InstitutionalRecordFields.NUM_OF_INSTITUTIONAL_RECORD_FIELDS: + if record_enum in [dd_enum_repository.InstitutionalRecordFields.CRC, dd_enum_repository.InstitutionalRecordFields.NUM_OF_INSTITUTIONAL_RECORD_FIELDS]: # Skip the Number of fields continue - - elif record_enum == dd_enum_repository.InstitutionalRecordFields.CRC: - # If field is CRC, skip the reading, crc will be calculated - pass - - elif record_enum.name in institutional_records and institutional_records[record_enum.name] is not None: - # If record present in the dict and value is not None - value = institutional_records[record_enum.name] - - else: + elif institutional_records == {}: # Set default values if it's missing from the provided dictionary if record_enum.datatype() in [DataTypes.U32, DataTypes.BOOL, DataTypes.S32, DataTypes.U16, DataTypes.U08, DataTypes.BOOL_U08]: value = 0 elif record_enum.datatype() in [DataTypes.F32]: value = 0.0 + elif record_enum.name in institutional_records and institutional_records[record_enum.name] is not None: + # If record present in the dict and value is not None + value = institutional_records[record_enum.name] + else: + # If record is not present in the dict or it doesn't have value, skip sending it + continue - # Calculate the CRC for the total institutional record (should be the last message) - if record_enum == dd_enum_repository.InstitutionalRecordFields.CRC: - payload += unsigned_short_to_bytearray(self.crc16(total_payload)) - - # Else just send the data - elif record_enum.datatype() in [DataTypes.U32, DataTypes.BOOL, DataTypes.S32]: + if record_enum.datatype() in [DataTypes.U32, DataTypes.BOOL, DataTypes.S32]: payload += integer_to_bytearray(value) - total_payload += integer_to_bytearray(value) elif record_enum.datatype() in [DataTypes.F32]: payload += float_to_bytearray(value) - total_payload += float_to_bytearray(value) elif record_enum.datatype() in [DataTypes.U16]: payload += unsigned_short_to_bytearray(value) - total_payload += unsigned_short_to_bytearray(value) elif record_enum.datatype() in [DataTypes.U08, DataTypes.BOOL_U08]: payload += byte_to_bytearray(value) - total_payload += byte_to_bytearray(value) send_data.append(partial(cmd_generic_override, payload = payload, Index: leahi_dialin/td/modules/records.py =================================================================== diff -u -r0bc2d3976315c12417c992717621a0284bbedef4 -rc1bff8da59cff294d67d90dd1e1f102dd5b65466 --- leahi_dialin/td/modules/records.py (.../records.py) (revision 0bc2d3976315c12417c992717621a0284bbedef4) +++ leahi_dialin/td/modules/records.py (.../records.py) (revision c1bff8da59cff294d67d90dd1e1f102dd5b65466) @@ -17,6 +17,7 @@ # Module imports from logging import Logger from functools import partial +from time import sleep # Project imports from leahi_dialin.common import td_enum_repository @@ -657,67 +658,99 @@ @return: 1 if successful, zero otherwise """ msg_id_pairing = { - self.CALIB_RECORDS_PRESSURE_SENSORS: MsgIds.MSG_ID_TD_NVM_SET_CAL_PRESSURE_SENSOR, - self.CALIB_RECORDS_TEMPERATURE_SENSORS: MsgIds.MSG_ID_TD_NVM_SET_CAL_TEMP_SENSOR, - self.CALIB_RECORDS_CONCENTRATE_PUMPS: MsgIds.MSG_ID_TD_NVM_SET_CAL_D48_PUMP, - self.CALIB_RECORDS_DIALYSATE_PUMPS: MsgIds.MSG_ID_TD_NVM_SET_CAL_CONC_PUMP, - self.CALIB_RECORDS_ACID_CONCENTRATE: MsgIds.MSG_ID_TD_NVM_SET_CAL_ACID_CONCENTRATE, - self.CALIB_RECORDS_BICARB_CONCENTRATE: MsgIds.MSG_ID_TD_NVM_SET_CAL_BICARB_CONCENTRATE, - self.CALIB_RECORDS_ACCELEROMETER: MsgIds.MSG_ID_TD_NVM_SET_CAL_ACCEL_SENSOR, - self.CALIB_RECORDS_BLOOD_LEAK: MsgIds.MSG_ID_TD_NVM_SET_CAL_BLOOD_LEAK_SENSOR, + 'PRES': MsgIds.MSG_ID_UI_TD_NVM_SET_CAL_PRESSURE_SENSOR, + 'TEMP': MsgIds.MSG_ID_UI_TD_NVM_SET_CAL_TEMP_SENSOR, + 'ACCEL': MsgIds.MSG_ID_UI_TD_NVM_SET_CAL_ACCEL_SENSOR, } - - # Make a dictionary to store all the send functions for later send send_data = [] - for key in calibration_records: - if key.lower() in [self.CALIB_RECORDS_PRESSURE_SENSORS, self.CALIB_RECORDS_TEMPERATURE_SENSORS, self.CALIB_RECORDS_CONCENTRATE_PUMPS, self.CALIB_RECORDS_DIALYSATE_PUMPS]: - for sensor in calibration_records[key]: - # Exception handling as D12 has an extra field (target speed) - if sensor in [td_enum_repository.TDDialysatePumpNames.D12_PUMP]: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_sensor(sensor_enum = sensor, - msg_id = MsgIds.MSG_ID_TD_NVM_SET_CAL_D12_PUMP, - dialysate_pump_target_speed = calibration_records[key][sensor]['target_speed'], - forth_order_coeff = calibration_records[key][sensor]['forth_order_coeff'], - third_order_coeff = calibration_records[key][sensor]['third_order_coeff'], - second_order_coeff = calibration_records[key][sensor]['second_order_coeff'], - gain = calibration_records[key][sensor]['gain'], - offset = calibration_records[key][sensor]['offset'], - calibration_time = calibration_records[key][sensor]['calibration_time']))) - else: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_sensor(sensor_enum = sensor, - msg_id = msg_id_pairing[key], - forth_order_coeff = calibration_records[key][sensor]['forth_order_coeff'], - third_order_coeff = calibration_records[key][sensor]['third_order_coeff'], - second_order_coeff = calibration_records[key][sensor]['second_order_coeff'], - gain = calibration_records[key][sensor]['gain'], - offset = calibration_records[key][sensor]['offset'], - calibration_time = calibration_records[key][sensor]['calibration_time']))) - elif key.lower() in [self.CALIB_RECORDS_ACID_CONCENTRATE, self.CALIB_RECORDS_BICARB_CONCENTRATE]: - for sensor in calibration_records[key]: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_concentrate(msg_id = msg_id_pairing[key], - concentrate_mix_ratio = calibration_records[key][sensor]['concentrate_mix_ratio'], - volume_ml = calibration_records[key][sensor]['volume_ml'], - conductivity_uspcm = calibration_records[key][sensor]['conductivity_uspcm'], - temperature_c = calibration_records[key][sensor]['temperature_c'], - calibration_time = calibration_records[key][sensor]['calibration_time']))) - elif key.lower() in [self.CALIB_RECORDS_ACCELEROMETER]: - for sensor in calibration_records[key]: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_accelerometer(msg_id = msg_id_pairing[key], - accel_x_offset = calibration_records[key][sensor]['accel_x_offset'], - accel_y_offset = calibration_records[key][sensor]['accel_y_offset'], - accel_z_offset = calibration_records[key][sensor]['accel_z_offset'], - calibration_time = calibration_records[key][sensor]['calibration_time']))) - elif key.lower() in [self.CALIB_RECORDS_BLOOD_LEAK]: - for sensor in calibration_records[key]: - # Store the function but do not execute it - send_data.append(partial(self.cmd_set_calibration_records_blood_leak(msg_id = msg_id_pairing[key], - set_point = calibration_records[key][sensor]['set_point'], - calibration_time = calibration_records[key][sensor]['calibration_time']))) - + checked = [] + for record_enum in td_enum_repository.CalibrationRecordFields: + record_parts = record_enum.name.split('__') + group = record_parts[0] + + # If a message already sent, then just go to the next value + if 'NUM_' in group or \ + group in checked or \ + record_parts[1] in checked: + continue + + if group in ['PRES', 'TEMP']: + # Set the sensor name + if group == 'PRES': + sensor = td_enum_repository.DDPressureSensorNames.from_str(record_parts[1]) + elif group == 'TEMP': + sensor = td_enum_repository.DDTemperatureSensorNames.from_str(record_parts[1]) + else: + sensor = 'UNKNOWN' + + # Set the arguments for the call + args = [] + kwargs = {} + fourth_order_coeff_entry_name = f'{group}__{sensor.name}__{td_enum_repository.CalibRecordSensorFields.FOURTH_ORDER_COEFF.name}' + third_order_coeff_entry_name = f'{group}__{sensor.name}__{td_enum_repository.CalibRecordSensorFields.THIRD_ORDER_COEFF.name}' + second_order_coeff_entry_name = f'{group}__{sensor.name}__{td_enum_repository.CalibRecordSensorFields.SECOND_ORDER_COEFF.name}' + gain_entry_name = f'{group}__{sensor.name}__{td_enum_repository.CalibRecordSensorFields.GAIN.name}' + offset_entry_name = f'{group}__{sensor.name}__{td_enum_repository.CalibRecordSensorFields.OFFSET.name}' + calibration_time_entry_name = f'{group}__{sensor.name}__{td_enum_repository.CalibRecordSensorFields.CALIBRATION_TIME.name}' + + kwargs['sensor_enum'] = sensor + kwargs['msg_id'] = msg_id_pairing[group] + if fourth_order_coeff_entry_name in calibration_records and calibration_records[fourth_order_coeff_entry_name] is not None: + kwargs['forth_order_coeff'] = calibration_records[fourth_order_coeff_entry_name] + + if third_order_coeff_entry_name in calibration_records and calibration_records[third_order_coeff_entry_name] is not None: + kwargs['third_order_coeff'] = calibration_records[third_order_coeff_entry_name] + + if second_order_coeff_entry_name in calibration_records and calibration_records[second_order_coeff_entry_name] is not None: + kwargs['second_order_coeff'] = calibration_records[second_order_coeff_entry_name] + + if gain_entry_name in calibration_records and calibration_records[gain_entry_name] is not None: + kwargs['gain'] = calibration_records[gain_entry_name] + + if offset_entry_name in calibration_records and calibration_records[offset_entry_name] is not None: + kwargs['offset'] = calibration_records[offset_entry_name] + + if calibration_time_entry_name in calibration_records and calibration_records[calibration_time_entry_name] is not None: + kwargs['calibration_time'] = calibration_records[calibration_time_entry_name] + + checked.append(record_parts[1]) + # Skip sending if dictionary is provided but all entry for the sensor was None (except sensor_enum and MSG_ID, because those are neccesary) + if calibration_records != {} and len(kwargs) == 2: + continue + + # Create the send data function + send_data.append(partial(self.cmd_set_calibration_records_sensor, *args, **kwargs)) + + elif group in ['ACCEL']: + # Set the arguments for the call + args = [] + kwargs = {} + accel_x_offset_entry_name = f'{group}__{td_enum_repository.CalibRecordAccelerometerFields.ACCEL_X_OFFSET.name}' + accel_y_offset_entry_name = f'{group}__{td_enum_repository.CalibRecordAccelerometerFields.ACCEL_Y_OFFSET.name}' + accel_z_offset_entry_name = f'{group}__{td_enum_repository.CalibRecordAccelerometerFields.ACCEL_Z_OFFSET.name}' + calibration_time_entry_name = f'{group}__{td_enum_repository.CalibRecordAccelerometerFields.CALIBRATION_TIME.name}' + + kwargs['msg_id'] = msg_id_pairing[group] + if accel_x_offset_entry_name in calibration_records and calibration_records[accel_x_offset_entry_name] is not None: + kwargs['accel_x_offset'] = calibration_records[accel_x_offset_entry_name] + + if accel_y_offset_entry_name in calibration_records and calibration_records[accel_y_offset_entry_name] is not None: + kwargs['accel_y_offset'] = calibration_records[accel_y_offset_entry_name] + + if accel_z_offset_entry_name in calibration_records and calibration_records[accel_z_offset_entry_name] is not None: + kwargs['accel_z_offset'] = calibration_records[accel_z_offset_entry_name] + + if calibration_time_entry_name in calibration_records and calibration_records[calibration_time_entry_name] is not None: + kwargs['calibration_time'] = calibration_records[calibration_time_entry_name] + + checked.append(group) + # Skip sending if dictionary is provided but all entry for the sensor was None (except MSG_ID, because that is neccesary) + if calibration_records != {} and len(kwargs) == 1: + continue + + # Store the function but do not execute it + send_data.append(partial(self.cmd_set_calibration_records_accelerometer, *args, **kwargs)) + # Execute the stored functions one by one # Remove the ones that got 1 (successfully recieved) as response # Retry the ones that are failed 2 more times @@ -730,9 +763,10 @@ failed.append(func) send_data = failed retry += 1 + sleep(0.005) # Wait 50ms between sends - def cmd_set_institutional_records(self, institutional_records: dict) -> int: + def cmd_set_institutional_records(self, institutional_records: dict={}) -> int: """ Constructs and sends a command for setting the Institutional Records. Constraints: @@ -744,47 +778,45 @@ """ # Make a dictionary to store all the send functions for later send send_data = [] - total_payload = b'' for record_enum in td_enum_repository.InstitutionalRecordFields: - if record_enum in institutional_records: - value = institutional_records[record_enum] - else: + # Set the enum_id to identify which parameter is being sent U08 - 1 byte - 0->255 !! + payload = byte_to_bytearray(record_enum.value) + + if record_enum in [td_enum_repository.InstitutionalRecordFields.CRC, td_enum_repository.InstitutionalRecordFields.NUM_OF_INSTITUTIONAL_RECORD_FIELDS]: + # Skip the Number of fields + continue + elif institutional_records == {}: # Set default values if it's missing from the provided dictionary if record_enum.datatype() in [DataTypes.U32, DataTypes.BOOL, DataTypes.S32, DataTypes.U16, DataTypes.U08, DataTypes.BOOL_U08]: value = 0 elif record_enum.datatype() in [DataTypes.F32]: value = 0.0 + elif record_enum.name in institutional_records and institutional_records[record_enum.name] is not None: + # If record present in the dict and value is not None + value = institutional_records[record_enum.name] + else: + # If record is not present in the dict or it doesn't have value, skip sending it + continue - # Set the enum_id to identify which parameter is being sent U08 - 1 byte - 0->255 !! - payload = byte_to_bytearray(record_enum.value) - - # Calculate the CRC for the total institutional record (should be the last message) - if record_enum == td_enum_repository.InstitutionalRecordFields.CRC: - payload += unsigned_short_to_bytearray(self.crc16(total_payload)) - - # Else just send the data - elif record_enum.datatype() in [DataTypes.U32, DataTypes.BOOL, DataTypes.S32]: + if record_enum.datatype() in [DataTypes.U32, DataTypes.BOOL, DataTypes.S32]: payload += integer_to_bytearray(value) - total_payload += integer_to_bytearray(value) elif record_enum.datatype() in [DataTypes.F32]: payload += float_to_bytearray(value) - total_payload += float_to_bytearray(value) elif record_enum.datatype() in [DataTypes.U16]: payload += unsigned_short_to_bytearray(value) - total_payload += unsigned_short_to_bytearray(value) elif record_enum.datatype() in [DataTypes.U08, DataTypes.BOOL_U08]: payload += byte_to_bytearray(value) - total_payload += byte_to_bytearray(value) - send_data.append(partial(cmd_generic_override(payload = payload, - reset = None, - channel_id = CanChannels.dialin_to_td_ch_id, - msg_id = MsgIds.MSG_ID_TD_NVM_SET_INSTITUTIONAL_RECORD, - entity_name = f'TD Institutional Record', - override_text = 'being set', - logger = self.logger, - can_interface = self.can_interface))) - + send_data.append(partial(cmd_generic_override, + payload = payload, + reset = None, + channel_id = CanChannels.dialin_to_dd_ch_id, + msg_id = MsgIds.MSG_ID_UI_DD_NVM_SET_INSTITUTIONAL_RECORD, + entity_name = f'TD Institutional Record', + override_text = 'being set', + logger = self.logger, + can_interface = self.can_interface)) + # Execute the stored functions one by one # Remove the ones that got 1 (successfully recieved) as response # Retry the ones that are failed 2 more times @@ -797,6 +829,7 @@ failed.append(func) send_data = failed retry += 1 + sleep(0.005) # Wait 50ms between sends def cmd_set_usage_info_records(self,