Пример #1
0
    def to_representation(self):
        header = f"{constants.SOH}{self.command}{self.command_type}"
        if self.data_set:
            body = f"{constants.STX}{self.data_set.to_representation()}{constants.ETX}"
        else:
            body = f"{constants.ETX}"

        message = f"{header}{body}"
        return utils.add_bcc(message)
Пример #2
0
    def to_representation(self):
        if self.partial_blocks:
            command = "R3"
            rows_per_block = self.rows_per_block
        else:
            command = "R1"
            rows_per_block = ""

        rep = (
            f"{constants.SOH}{command}{constants.STX}{self.archive}:V.{self.attribute}"
            f"({self.position};{self.start};{self.end};{rows_per_block}){constants.ETX}"
        )
        return utils.add_bcc(rep)
Пример #3
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
Пример #4
0
    def to_representation(self):
        # TODO: this is not valid in case reading out partial blocks.
        rep = f"{constants.STX}{self.data_block.to_representation()}{constants.ETX}"

        return utils.add_bcc(rep)
Пример #5
0
    def to_representation(self):
        data = (
            f"{constants.STX}{self.data_block.to_representation()}{constants.END_CHAR}"
            f"{constants.LINE_END}{constants.ETX}")

        return utils.add_bcc(data)
Пример #6
0
 def test_add_bcc1(self):
     data = "\x01P0\x02(1234567)\x03"
     correct_data = "\x01P0\x02(1234567)\x03P"
     with_bcc = add_bcc(data)
     assert with_bcc == correct_data