Index: dialin/dg/calibration.py =================================================================== diff -u -r6d387cadbda3027d23510126942eaa9f6317d357 -r6154b064dd181c32b09982c04ca9ddbca41bf509 --- dialin/dg/calibration.py (.../calibration.py) (revision 6d387cadbda3027d23510126942eaa9f6317d357) +++ dialin/dg/calibration.py (.../calibration.py) (revision 6154b064dd181c32b09982c04ca9ddbca41bf509) @@ -1,5 +1,6 @@ import struct +from collections import OrderedDict from ..utils.conversions import integer_to_bytearray from ..common.msg_defs import MsgIds, MsgFieldPositions from ..protocols.CAN import (DenaliMessage, DenaliChannels) @@ -14,7 +15,22 @@ """ CALIBRATION_RECORD_START_INDEX = 6 + CALIBRATION_RECORD_SPECS_BYTES = 12 + DEFAULT_GAIN_VALUE = 1 + DEFAULT_OFFSET_VALUE = 0 + DEFAULT_RATIO_VALUE = 1 + DEFAULT_CONSTANT_VALUE = 0 + DEFAULT_CAL_TIME_VALUE = 0 + DEFAULT_CAL_CRC_VALUE = 0 + CURRENT_MESSAGE_NUM_INDEX = 0 + TOTAL_MESSAGES_NUM_INDEX = 4 + PAYLOAD_LENGTH_INDEX = 8 + PAYLOAD_START_INDEX = 12 + + # DG calibration main record + DG_CALIBRATION_RECORD = OrderedDict() + def __init__(self, can_interface, logger: Logger): """ @@ -33,34 +49,25 @@ if self.can_interface is not None: - channel_id = DenaliChannels.dg_sync_broadcast_ch_id + channel_id = DenaliChannels.dg_to_dialin_ch_id msg_id = MsgIds.MSG_ID_DG_SEND_CALIBRATION_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_dg_calibration_sync) + # Prepare the calibration record by putting sub-dictionaries together + self._prepare_dg_calibration_record() - @_publish(["current_message", "total_messages", "length", "cal_data"]) - def _handler_dg_calibration_sync(self, message): + def get_dg_calibration_data(self): """ - Handles published ro pump data messages. RO pump data are captured - for reference. + Handles getting dg calibration data from firmware. - @param message: published RO pump data message - @return: None """ - curr = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] - total = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] - length = struct.unpack('i', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + # Clear the list for the next call + self.raw_cal_record.clear() + # Run the firmware commands to get the calibration record + self._request_dg_fw_calibration_data() - self.current_message = curr - self.total_messages = total - self.length = length - self.cal_data = message['message'][self.CALIBRATION_RECORD_START_INDEX:] - - def get_dg_calibration_data(self): + def _request_dg_fw_calibration_data(self): """ Handles getting DG calibration record from firmware. @@ -81,6 +88,221 @@ self.logger.debug("Timeout!!!!") return False + @_publish(["current_message", "total_messages", "length", "cal_data"]) #TODO do we need to publish these? + def _handler_dg_calibration_sync(self, message): + """ + Handles published DG calibration record messages. DG calibration records are captured for processing and + updating the DG calibration record. + + @param message: published DG calibration record data message + + @return: None + """ + curr = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + total = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + length = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + + self.current_message = curr + self.total_messages = total + self.length = length + # The end of calibration record payload is from the start index + 12 bytes for the current message + total + # messages + the length of calibration. The rest is the CAN messaging CRC that is not needed to be kept + end_of_data_index = self.CALIBRATION_RECORD_START_INDEX + self.CALIBRATION_RECORD_SPECS_BYTES + self.length + + # Get the calibration data only + self.cal_data = message['message'][self.CALIBRATION_RECORD_START_INDEX:end_of_data_index] + + # Continue getting calibration records until the all the calibration messages are received. Concatenate the + # calibration records to each other + if self.current_message <= self.total_messages: + self.raw_cal_record += (message['message'][self.CALIBRATION_RECORD_START_INDEX + + self.CALIBRATION_RECORD_SPECS_BYTES:end_of_data_index]) + # If all the messages have been received, call another function to process the raw data + if self.current_message == self.total_messages: + + self._update_dg_calibration_record_from_fw() + + def _update_dg_calibration_record_from_fw(self): + """ + Handles parsing the calibration messages that were received from DG firmware. + + @return: None + """ + value_bytes = 0 + raw_payload_temp_start_index = 0 + data = '' + # Convert the concatenated raw data into a byte array since the struct library requires byte arrays. + self.raw_cal_record = bytearray(self.raw_cal_record) + + # Loop though the keys for the main calibration dictionary + # DG_Calibration : {pressure_sensors : { ppi : { gain: ['