def read_profile(self, start_date: date, end_date: date): """ Reads some profile """ if not (isinstance(start_date, date) or isinstance(end_date, date)): assert "Not proper date for reading profile" self.startup() self.ack_with_option_select("programming") response = self.read_response() if not utils.bcc_valid(response.to_bytes()): assert "Not a valid bcc" self._send_profile_request(start_date, end_date) response = self.read_response() # Result if not utils.bcc_valid(response.to_bytes()): assert "Not a valid bcc" return self._arrange_profile_data(response)
def from_representation(cls, string_data): _in_data = string_data if not utils.bcc_valid(string_data): raise ValueError("BCC not valid") _in_data = _in_data[1:-2] # remove stx -- etx bcc data_block = DataBlock.from_representation(_in_data) return cls(data_block=data_block)
def from_representation(cls, string_data): if not utils.bcc_valid(string_data): raise ValueError("BCC not valid") _message = string_data[:-1] # remove bcc header = _message[:3] body = _message[3:] command = header[1] command_type = header[2] data_set = DataSet.from_representation(body[1:-1]) return cls(command, command_type, data_set)
def read(self, timeout=None): """ Will read a normal readout. Supports both full and partial block readout. When using partial blocks it will recreate the messages as it was not sent with partial blocks :param timeout: :return: """ start_chars = [b"\x01", b"\x02"] end_chars = [b"\x03", b"\x04"] total_data = b"" packets = 0 start_char_received = False start_char = None end_char = None timeout = timeout or self.timeout while True: in_data = b"" duration = 0 start_time = time.time() while True: b = self.recv(1) duration = time.time() - start_time if duration > self.timeout: raise TimeoutError( f"Read in {self.__class__.__name__} timed out") if b == b'\x15' or b == b'\x06': in_data += b logger.debug( f"Received {in_data!r} over transport: {self.__class__.__name__}" ) return in_data if not start_char_received: # is start char? if b in start_chars: in_data += b start_char_received = True start_char = b continue else: continue else: # is end char? if b in end_chars: in_data += b end_char = b break else: in_data += b continue packets += 1 bcc = self.recv(1) in_data += bcc logger.debug( f"Received {in_data!r} over transport: {self.__class__.__name__}" ) if start_char == b"\x01": # This is a command message, probably Password challange. total_data += in_data break if end_char == b"\x04": # EOT (partial read) # we received a partial block if not utils.bcc_valid(in_data): # Nack and read again self.send(constants.NACK.encode(constants.ENCODING)) continue else: # ack and read next self.send(constants.ACK.encode(constants.ENCODING)) # remove bcc and eot and add line end. in_data = in_data[:-2] + constants.LINE_END.encode( constants.ENCODING) if packets > 1: # remove the leading STX in_data = in_data[1:] total_data += in_data continue if end_char == b"\x03": # Either it was the only message or we got the last message. if not utils.bcc_valid(in_data): # Nack and read again self.send(constants.NACK.encode(constants.ENCODING)) continue else: if packets > 1: in_data = in_data[1:] # removing the leading STX total_data += in_data if packets > 1: # The last bcc is not correct compared to the whole # message. But we have verified all the bccs along the way so # we just compute it so the message is usable. total_data = utils.add_bcc(total_data[:-1]) break return total_data