How to use the zigpy.types.Struct function in zigpy

To help you get started, we’ve selected a few zigpy examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github zigpy / zigpy / tests / test_struct.py View on Github external
class TestStruct1(t.Struct):
            b: typing.Optional[t.uint8_t]
            a: t.uint8_t

    with pytest.raises(TypeError):

        class TestStruct2(t.Struct):
            b: typing.Optional[t.uint8_t]
            a: t.uint8_t
            c: typing.Optional[t.uint8_t]

    # Every field must be annotated
    with pytest.raises(TypeError):

        class BadTestStruct3(t.Struct):
            a = 5

    # In-class constants are allowed
    class TestStruct3(t.Struct):
        CONSTANT1: int = 123
        CONSTANT2 = 1234
        _private1: int = 456
        _private2 = 4567

    assert not TestStruct3.fields()
    assert TestStruct3.CONSTANT1 == 123
    assert TestStruct3.CONSTANT2 == 1234
    assert TestStruct3._private1 == 456
    assert TestStruct3._private2 == 4567

    # This is fine
github zigpy / zigpy / tests / test_struct.py View on Github external
pass

    # Fields cannot have values
    with pytest.raises(TypeError):

        class TestStruct6(t.Struct):
            a: t.uint8_t = 2

    # unless they are a StructField
    class TestStruct7(t.Struct):
        a: t.uint8_t = t.StructField()

    # Fields can only have a single concrete type
    with pytest.raises(TypeError):

        class TestStruct8(t.Struct):
            bad: typing.Union[t.uint8_t, t.uint16_t]
github zigpy / zigpy / tests / test_struct.py View on Github external
def test_old_style_struct():
    with pytest.raises(TypeError):
        # `_fields` would typically be ignored but this would be very bad
        class OldStruct(t.Struct):
            _fields = [("foo", t.uint8_t)]
github zigpy / zigpy / tests / test_struct.py View on Github external
def test_nested_structs():
    class InnerStruct(t.Struct):
        b: t.uint8_t
        c: t.uint8_t

    class OuterStruct(t.Struct):
        a: t.uint8_t
        inner: typing.Optional[InnerStruct]
        d: typing.Optional[t.uint8_t]

    s1, remaining = OuterStruct.deserialize(b"\x00\x01\x02")
    assert not remaining
    assert s1.a == 0
    assert s1.inner.b == 1
    assert s1.inner.c == 2
    assert s1.d is None

    s2, remaining = OuterStruct.deserialize(b"\x00\x01\x02\x03")
    assert not remaining
    assert s2.a == 0
    assert s2.inner.b == 1
    assert s2.inner.c == 2
github zigpy / zigpy / tests / test_struct.py View on Github external
def test_struct_subclass_extension(data):
    class TestStruct(t.Struct):
        foo: t.uint8_t

    class TestStructSubclass(TestStruct):
        bar: t.uint8_t = t.StructField(requires=lambda s: s.foo == 0x01)

    class TestCombinedStruct(t.Struct):
        foo: t.uint8_t
        bar: t.uint8_t = t.StructField(requires=lambda s: s.foo == 0x01)

    assert len(TestStructSubclass.fields()) == 2
    assert len(TestCombinedStruct.fields()) == 2

    error1 = None
    error2 = None

    try:
        ts1, remaining1 = TestStructSubclass.deserialize(data)
    except Exception as e:
        error1 = e

    try:
        ts2, remaining2 = TestCombinedStruct.deserialize(data)
github zigpy / zigpy / zigpy / zcl / foundation.py View on Github external
direction: t.uint8_t
    attrid: t.uint16_t


class DiscoverAttributesResponseRecord(t.Struct):
    attrid: t.uint16_t
    datatype: t.uint8_t


class AttributeAccessControl(t.bitmap8):
    READ = 0x01
    WRITE = 0x02
    REPORT = 0x04


class DiscoverAttributesExtendedResponseRecord(t.Struct):
    attrid: t.uint16_t
    datatype: t.uint8_t
    acl: AttributeAccessControl


class Command(t.enum8):
    """ZCL Foundation Global Command IDs."""

    Read_Attributes = 0x00
    Read_Attributes_rsp = 0x01
    Write_Attributes = 0x02
    Write_Attributes_Undivided = 0x03
    Write_Attributes_rsp = 0x04
    Write_Attributes_No_Response = 0x05
    Configure_Reporting = 0x06
    Configure_Reporting_rsp = 0x07
github zigpy / zigpy / zigpy / zdo / types.py View on Github external
import typing

import zigpy.types as t


class PowerDescriptor(t.Struct):
    byte_1: t.uint8_t
    byte_2: t.uint8_t

    # TODO: interpret the four 4-bit fields


class SimpleDescriptor(t.Struct):
    endpoint: t.uint8_t
    profile: t.uint16_t
    device_type: t.uint16_t
    device_version: t.uint8_t
    input_clusters: t.LVList(t.uint16_t)
    output_clusters: t.LVList(t.uint16_t)


class SizePrefixedSimpleDescriptor(SimpleDescriptor):
    def serialize(self):
        data = super().serialize()
        return len(data).to_bytes(1, "little") + data

    @classmethod
    def deserialize(cls, data):
        if not data or data[0] == 0:
github zigpy / zigpy / zigpy / zdo / types.py View on Github external
class Route(t.Struct):
    """Route Descriptor"""

    DstNWK: t.NWK
    RouteStatus: t.uint8_t
    NextHop: t.NWK


class Routes(t.Struct):
    Entries: t.uint8_t
    StartIndex: t.uint8_t
    RoutingTableList: t.LVList(Route)


class NwkUpdate(t.Struct):
    CHANNEL_CHANGE_REQ = 0xFE
    CHANNEL_MASK_MANAGER_ADDR_CHANGE_REQ = 0xFF

    ScanChannels: t.Channels
    ScanDuration: t.uint8_t
    ScanCount: t.uint8_t
    nwkUpdateId: t.uint8_t
    nwkManagerAddr: t.NWK

    def serialize(self) -> bytes:
        """Serialize data."""
        r = self.ScanChannels.serialize() + self.ScanDuration.serialize()
        if self.ScanDuration <= 0x05:
            r += self.ScanCount.serialize()
        if self.ScanDuration in (
            self.CHANNEL_CHANGE_REQ,
github zigpy / zigpy / zigpy / zcl / foundation.py View on Github external
r += " direction=%s attrid=%s" % (self.direction, self.attrid)
        r += ">"
        return r


class ConfigureReportingResponse(t.List(ConfigureReportingResponseRecord)):
    def serialize(self):
        failed = [record for record in self if record.status != Status.SUCCESS]
        if failed:
            return b"".join(
                [ConfigureReportingResponseRecord(i).serialize() for i in failed]
            )
        return Status.SUCCESS.serialize()


class ReadReportingConfigRecord(t.Struct):
    direction: t.uint8_t
    attrid: t.uint16_t


class DiscoverAttributesResponseRecord(t.Struct):
    attrid: t.uint16_t
    datatype: t.uint8_t


class AttributeAccessControl(t.bitmap8):
    READ = 0x01
    WRITE = 0x02
    REPORT = 0x04


class DiscoverAttributesExtendedResponseRecord(t.Struct):
github zigpy / zigpy / zigpy / zdo / types.py View on Github external
"""Mgmt_Lqi_rsp"""

    Entries: t.uint8_t
    StartIndex: t.uint8_t
    NeighborTableList: t.LVList(Neighbor)


class Route(t.Struct):
    """Route Descriptor"""

    DstNWK: t.NWK
    RouteStatus: t.uint8_t
    NextHop: t.NWK


class Routes(t.Struct):
    Entries: t.uint8_t
    StartIndex: t.uint8_t
    RoutingTableList: t.LVList(Route)


class NwkUpdate(t.Struct):
    CHANNEL_CHANGE_REQ = 0xFE
    CHANNEL_MASK_MANAGER_ADDR_CHANGE_REQ = 0xFF

    ScanChannels: t.Channels
    ScanDuration: t.uint8_t
    ScanCount: t.uint8_t
    nwkUpdateId: t.uint8_t
    nwkManagerAddr: t.NWK

    def serialize(self) -> bytes: