Пример #1
0
    def from_bytes(cls, source_bytes: bytes):
        data = bytearray(source_bytes)
        tag = data.pop(0)
        if tag != cls.TAG:
            raise ValueError(
                f"Tag is not correct. Should be {cls.TAG} but is {tag}")
        response_type = enums.GetResponseType(data.pop(0))
        if response_type != cls.RESPONSE_TYPE:
            raise ValueError(
                f"The response type byte: {response_type} is not for a GetResponseNormal"
            )
        invoke_id_and_priority = InvokeIdAndPriority.from_bytes(
            data.pop(0).to_bytes(1, "big"))
        last_block = bool(data.pop(0))
        if not last_block:
            raise ValueError(
                f"Last block is not set to true in a GetResponseLastBlock.")
        block_number = int.from_bytes(data[:4], "big")
        data = data[4:]
        choice = data.pop(0)
        if choice != 0:
            raise ValueError(
                f"The data choice is not 0 to indicate data but: {choice}")

        data_length, data = dlms_cosem.dlms_data.decode_variable_integer(data)
        if data_length != len(data):
            raise ValueError(
                "The octet string in block data is not of the correct length")

        return cls(bytes(data), block_number, invoke_id_and_priority)
Пример #2
0
    def from_bytes(cls, source_bytes: bytes):
        data = bytearray(source_bytes)
        tag = data.pop(0)
        if tag != cls.TAG:
            raise ValueError(
                f"Tag is not correct. Should be {cls.TAG} but is {tag}")
        response_type = enums.GetResponseType(data.pop(0))
        if response_type != cls.RESPONSE_TYPE:
            raise ValueError(
                f"The response type byte: {response_type} is not for a GetResponseNormal"
            )
        invoke_id_and_priority = InvokeIdAndPriority.from_bytes(
            data.pop(0).to_bytes(1, "big"))
        last_block = bool(data.pop(0))
        if not last_block:
            raise ValueError(
                f"Last block is not set to true in a GetResponseLastBlock.")
        block_number = int.from_bytes(data[:4], "big")
        data = data[4:]
        choice = data.pop(0)
        if choice != 1:
            raise ValueError(
                f"The data choice is not 1 to indicate error but: {choice}")

        assert len(data) == 1
        error = enums.DataAccessResult(data.pop(0))
        return cls(error, block_number, invoke_id_and_priority)
Пример #3
0
    def from_bytes(source_bytes: bytes):
        data = bytearray(source_bytes)
        tag = data.pop(0)
        if tag != GetResponseFactory.TAG:
            raise ValueError(
                f"Tag is not correct. Should be {GetResponseFactory.TAG} but is {tag}"
            )
        response_type = enums.GetResponseType(data.pop(0))
        invoke_id_and_priority = InvokeIdAndPriority.from_bytes(
            data.pop(0).to_bytes(1, "big"))
        if response_type == enums.GetResponseType.NORMAL:
            # check if it is an error or data response by assesing the choice.
            choice = data.pop(0)
            if choice == 0:
                return GetResponseNormal(
                    invoke_id_and_priority=invoke_id_and_priority,
                    data=bytes(data))
            elif choice == 1:
                assert len(data) == 1  # should only be one byte left.
                error = enums.DataAccessResult(data.pop(0))
                return GetResponseNormalWithError(
                    invoke_id_and_priority=invoke_id_and_priority, error=error)
        elif response_type == enums.GetResponseType.WITH_BLOCK:
            last_block = bool(data.pop(0))
            block_number = int.from_bytes(data[:4], "big")
            data = data[4:]
            choice = data.pop(0)
            if choice == 0:
                data_length, data = dlms_cosem.dlms_data.decode_variable_integer(
                    data)
                if data_length != len(data):
                    raise ValueError(
                        "The octet string in block data is not of the correct length"
                    )

                if last_block:
                    return GetResponseLastBlock(bytes(data), block_number,
                                                invoke_id_and_priority)
                else:
                    return GetResponseWithBlock(bytes(data), block_number,
                                                invoke_id_and_priority)
            elif choice == 1:
                assert len(data) == 1  # should only be one byte left.
                error = enums.DataAccessResult(data.pop(0))
                if last_block:
                    return GetResponseLastBlockWithError(
                        error, block_number, invoke_id_and_priority)
                else:
                    raise ValueError(
                        "It is not possible to send an error on a "
                        "GetResponseWithBlock. When an error occurs it "
                        "should always be sent in a GetResponseLastBlockWithError"
                    )

        elif response_type == enums.GetResponseType.WITH_LIST:
            return GetResponseWithList.from_bytes(bytes(source_bytes))

        else:
            raise ValueError("Response type is not a valid GetResponse type")
Пример #4
0
    def from_bytes(cls, source_bytes: bytes):
        data = bytearray(source_bytes)
        tag = data.pop(0)
        if tag != cls.TAG:
            raise ValueError(
                f"Tag is not correct. Should be {cls.TAG} but is {tag}")
        response_type = enums.GetResponseType(data.pop(0))
        if response_type != cls.RESPONSE_TYPE:
            raise ValueError(
                f"The response type byte: {response_type} is not for a GetResponseNormal"
            )
        invoke_id_and_priority = InvokeIdAndPriority.from_bytes(
            data.pop(0).to_bytes(1, "big"))
        choice = data.pop(0)
        if choice != 0:
            raise ValueError(
                f"The data choice is not 0 to indicate data but: {choice}")

        return cls(bytes(data), invoke_id_and_priority)