コード例 #1
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")
コード例 #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(cls, source_bytes: bytes):

        data = bytearray(source_bytes)
        tag = data.pop(0)
        if tag != cls.TAG:
            raise ValueError(
                f"Tag {tag} is not correct for ActionResponse. Should be {cls.TAG}"
            )
        action_type = enumerations.ActionType(data.pop(0))

        if action_type != enumerations.ActionType.NORMAL:
            raise ValueError(
                f"Bytes are not representing a ActionResponseNormal. Action type "
                f"is {action_type}")

        invoke_id_and_priority = InvokeIdAndPriority.from_bytes(
            data.pop(0).to_bytes(1, "big"))

        status = enumerations.ActionResultStatus(data.pop(0))
        has_data = bool(data.pop(0))
        if has_data:
            data_is_error = data.pop(0) == 1
            if not data_is_error:
                raise ValueError(
                    "Data is not a ActionResponseNormalWithError, maybe a "
                    "ActionResponseNormal")
            assert len(data) == 1
            error = enumerations.DataAccessResult(data.pop(0))

        else:
            raise ValueError("No error data in ActionResponseWithError")

        return cls(invoke_id_and_priority=invoke_id_and_priority,
                   status=status,
                   error=error)
コード例 #4
0
    def parse_list_response(source_bytes: bytes, amount: int):
        data = bytearray(source_bytes)
        dlms_data_items = list()
        for index in range(0, amount):
            answer_selection = data.pop(0)
            if answer_selection == 0:
                # DLMS data
                parser = dlms_data.DlmsDataParser()
                obj = parser.parse(data, limit=1)
                rest = parser.get_buffer_tail()
                dlms_data_items.append(obj[0])
                data = rest
            elif answer_selection == 1:
                # Data Access Result
                dlms_data_items.append(enums.DataAccessResult(data.pop(0)))
            else:
                raise ValueError("Not a valid answer selection byte")

        return dlms_data_items
コード例 #5
0
ファイル: set.py プロジェクト: pwitab/dlms-cosem
    def from_bytes(cls, source_bytes: bytes):
        data = bytearray(source_bytes)
        tag = data.pop(0)
        if tag != cls.TAG:
            raise ValueError(
                f"Tag for SetResponse is not correct. Got {tag}, should be {cls.TAG}"
            )

        type_choice = enums.SetResponseType(data.pop(0))
        if type_choice is not enums.SetResponseType.NORMAL:
            raise ValueError(
                "The type of the SetResponse is not for a SetResponseNormal"
            )

        invoke_id_and_priority = InvokeIdAndPriority.from_bytes(
            data.pop(0).to_bytes(1, "big")
        )

        result = enums.DataAccessResult(data.pop(0))

        return cls(result=result, invoke_id_and_priority=invoke_id_and_priority)
コード例 #6
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 != 1:
            raise ValueError(
                f"The data choice is not 1 to indicate error but: {choice}")

        error = enums.DataAccessResult(data.pop(0))

        return cls(error, invoke_id_and_priority)