Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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