Index: dialin/dg/calibration_record.py =================================================================== diff -u -rbe687b87ec7dbbb312fc9dc67fd422119e43e64c -r04d9678a26c46fe1567d9e8eecd80414a94ee4bc --- dialin/dg/calibration_record.py (.../calibration_record.py) (revision be687b87ec7dbbb312fc9dc67fd422119e43e64c) +++ dialin/dg/calibration_record.py (.../calibration_record.py) (revision 04d9678a26c46fe1567d9e8eecd80414a94ee4bc) @@ -48,26 +48,20 @@ self.current_message = 0 self.total_messages = 0 self.received_msg_length = 0 + self._is_getting_cal_in_progress = False self.cal_data = 0 self._raw_cal_record = [] - self._write_fw_data_to_excel = True - self._is_getting_cal_in_progress = False self._utilities = NVOpsUtils(logger=self.logger) - # DG calibration_record main record - self.dg_calibration_record = OrderedDict() + # DG Calibration_record main record + self.dg_calibration_record = self._prepare_dg_calibration_record() if self.can_interface is not None: channel_id = DenaliChannels.dg_to_dialin_ch_id msg_id = MsgIds.MSG_ID_DG_SEND_CALIBRATION_RECORD.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_dg_calibration_sync) - # Prepare the calibration_record record by putting sub-dictionaries together - self._prepare_dg_calibration_record() - # Prepare the excel report and workspace - self._utilities.prepare_excel_report('DG', 'Calibration') - def is_reading_record_done(self): """ Handles getting the status of reading record @@ -78,41 +72,47 @@ def get_dg_calibration_record(self): """ - Handles getting DG calibration data from firmware. + Gets the existing calibration record + @return: (OrderedDict) the calibration record, None if calibration record is being received + """ + if not self._is_getting_cal_in_progress: + return self.dg_calibration_record + return None + def _reset_getting_calibration_record_in_progress(self): + """ + Private method to set the cal in progress flag to False @return: None """ + self._is_getting_cal_in_progress = False - # If getting the calibration is in progress, do not start another process - if not self._is_getting_cal_in_progress: - self._is_getting_cal_in_progress = True - # Clear the list for the next call - self._raw_cal_record.clear() - # Run the firmware commands to get the calibration_record record - self._request_dg_fw_calibration_record() - - def _request_dg_fw_calibration_record(self): + def cmd_request_dg_calibration_record(self): """ Handles getting DG calibration_record record from firmware. - @return: 1 if successful, zero otherwise + @return: True if successful, False otherwise """ - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, - message_id=MsgIds.MSG_ID_DG_GET_CALIBRATION_RECORD.value) - self.logger.debug('Getting DG calibration record') + self.logger.debug("Requesting a dg calibration record...") - received_message = self.can_interface.send(message) + if not self._is_getting_cal_in_progress: + self._is_getting_cal_in_progress = True - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=MsgIds.MSG_ID_DG_GET_CALIBRATION_RECORD.value) + + received_message = self.can_interface.send(message, time_out=5) + + # If there is content... + if received_message is not None: + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + self.logger.debug("Timeout!!!!") - return False - @_publish(["current_message", "total_messages", "received_msg_length", "service_data"]) + self.logger.debug("Request cancelled: an existing request is in progress.") + return False + def _handler_dg_calibration_sync(self, message): """ Handles published DG calibration_record record messages. DG calibration records are captured for @@ -122,6 +122,7 @@ @return: None """ + self.logger.debug("DG calibration sync handler...") curr = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] total = struct.unpack('i', bytearray( @@ -142,40 +143,35 @@ # Continue getting calibration_record records until the all the calibration_record messages are received. # Concatenate the calibration_record records to each other. - if self.current_message <= self.total_messages: + if self.current_message < self.total_messages: self._raw_cal_record += (message['message'][self._RECORD_START_INDEX + self._RECORD_SPECS_BYTES:end_of_data_index]) - if self.current_message == self.total_messages: - # Done with getting all the calibration data. - self._is_getting_cal_in_progress = False - # If all the messages have been received, call another function to process the raw data - self._utilities.process_received_record_from_fw(self.dg_calibration_record, - self._raw_cal_record, - write_to_excel=self._write_fw_data_to_excel) + elif self.current_message == self.total_messages: + # Done with getting all the calibration data. + self._is_getting_cal_in_progress = False + # If all the messages have been received, call another function to process the raw data + self._utilities.process_received_record_from_fw(self.dg_calibration_record, self._raw_cal_record) + self._handler_received_complete_dg_calibration_record() - def set_dg_calibration_record(self): + @_publish(["dg_calibration_record"]) + def _handler_received_complete_dg_calibration_record(self): """ + Publishes the received calibration record + + @return: None + """ + self.logger.debug("Received a complete dg calibration record.") + + def cmd_set_dg_calibration_record(self, dg_calibration_record: OrderedDict): + """ Handles updating the DG calibration record with the newest calibration_record data of a hardware and sends it to FW. - @return: none + @return: True upon success, False otherwise """ - # Read the data from firmware but do not update the excel document - # At this step, another read from firmware is requested internally to update the dictionary. - # The values in the dictionary is compared against the excel report and if they are different, it automatically - # sets the calibration time and calculates the CRC for that group. By default once a read from firmware is - # requested, the excel report is updated automatically. - self._write_fw_data_to_excel = False - self.get_dg_calibration_record() - # Wait until reading calibration record from firmware is updated - while self._utilities.get_reading_record_status() is not True: - time.sleep(self._DIALIN_RECORD_UPDATE_DELAY_S) - # Write the excel record - self._utilities.write_excel_record_to_calibration_record(self.dg_calibration_record) + record_packets = self._utilities.prepare_record_to_send_to_fw(dg_calibration_record) - record_packets = self._utilities.prepare_record_to_send_to_fw(self.dg_calibration_record) - self.logger.debug('Setting DG calibration started') # Update all the data packets with the last message count since is the number of messages that firmware @@ -198,12 +194,17 @@ self.logger.debug("Timeout!!!!") return False + self.logger.debug("Finished sending DG calibration record.") + return True + def _prepare_dg_calibration_record(self): """ - Handles assembling the sub dictionaries of each hardware group to make the main DG calibration record. + Handles assembling the sub dictionaries of each hardware group to make a DG calibration record. - @return: None + @return: (OrderedDict) the assembled record """ + result = OrderedDict() + groups_byte_size = 0 # Call the other functions to get the dictionaries of each hardware group. All the dictionaries are # ordered dictionaries to maintain the order in which they are inserted. The results are a tuple, the first @@ -219,7 +220,7 @@ # Update the groups bytes size so far to be use to padding later groups_byte_size += byte_size # Update the calibration record - self.dg_calibration_record.update(record) + result.update(record) # Build the CRC of the main calibration_record record record_crc = OrderedDict({'crc': [' self.MIN_PAYLOAD_BYTES_SPACE: - current_payload_length += data_type_bytes - temp_buffer[self.PAYLOAD_TOTAL_MSG_INDEX] = struct.pack(' self.MIN_PAYLOAD_BYTES_SPACE: - - current_payload_length += data_type_bytes - # Insert a 4-byte 0 to the index of the total messages. This is a place holder and it will - # be updated with the right value later. - temp_buffer[self.PAYLOAD_TOTAL_MSG_INDEX] = struct.pack(' self._MIN_PAYLOAD_BYTES_SPACE: - current_payload_length += data_type_bytes - # Insert a 4-byte 0 to the index of the total messages. This is a place holder and it will - # be updated with the right value later. - temp_buffer[self._PAYLOAD_TOTAL_MSG_INDEX] = struct.pack(' self._MIN_PAYLOAD_BYTES_SPACE: + current_payload_length += data_type_bytes + # Insert a 4-byte 0 to the index of the total messages. This is a place holder and it will + # be updated with the right value later. + temp_buffer[self._PAYLOAD_TOTAL_MSG_INDEX] = struct.pack('> 8) & 0x0000FFFF - crc = left ^ self.CRC_16_TABLE[data[i] ^ (right & 0x00FF)] + crc = left ^ cls.CRC_16_TABLE[data[i] ^ (right & 0x00FF)] l -= 1 i += 1 Index: tests/test_calibration.py =================================================================== diff -u --- tests/test_calibration.py (revision 0) +++ tests/test_calibration.py (revision 04d9678a26c46fe1567d9e8eecd80414a94ee4bc) @@ -0,0 +1,182 @@ +import sys +import struct + +from dialin import HD, AbstractObserver + +sys.path.append("../") +from dialin.dg.dialysate_generator import DG +from dialin.utils.nv_ops_utils import NVOpsUtils +from time import sleep + + +def process_calibration_record(read=False): + + cal = dg.calibration_record + print(cal.tmp_record) + + try: + if read: + cal.cmd_request_dg_calibration_record() + while True: + sleep(0.5) + if cal.cal_data != 0: + if cal.is_reading_record_done(): + break + else: + cal.cmd_set_dg_calibration_record() + + print(cal.tmp_record) + + except KeyboardInterrupt: + pass + + +def process_system_record(read=False): + + sys = dg.system_record + print(sys.dg_system_record) + + try: + if read: + sys.get_dg_system_record() + while True: + sleep(0.5) + if sys.is_reading_record_done(): + if sys.is_reading_record_done(): + break + else: + sys.set_dg_system_record() + + print(sys.dg_system_record) + + except KeyboardInterrupt: + pass + + +def process_service_record(read=False): + + sys = dg.service_record + print(sys.dg_service_record) + + try: + if read: + sys.cmd_request_dg_service_record() + while True: + sleep(0.5) + if sys.is_reading_record_done(): + if sys.is_reading_record_done(): + break + else: + sys.set_dg_service_record() + + print(sys.dg_service_record) + + except KeyboardInterrupt: + pass + +def test_crc(): + val = NVOpsUtils.crc_16(b''.join([ + struct.pack("