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,