Esempio n. 1
0
def test_request_optional(cluster):
    schema = [
        t.uint8_t, t.uint16_t,
        t.Optional(t.uint16_t),
        t.Optional(t.uint8_t)
    ]

    res = cluster.request(True, 0, schema)
    assert type(res.exception()) == ValueError
    assert cluster._endpoint.request.call_count == 0
    cluster._endpoint.request.reset_mock()

    res = cluster.request(True, 0, schema, 1)
    assert type(res.exception()) == ValueError
    assert cluster._endpoint.request.call_count == 0
    cluster._endpoint.request.reset_mock()

    cluster.request(True, 0, schema, 1, 2)
    assert cluster._endpoint.request.call_count == 1
    cluster._endpoint.request.reset_mock()

    cluster.request(True, 0, schema, 1, 2, 3)
    assert cluster._endpoint.request.call_count == 1
    cluster._endpoint.request.reset_mock()

    cluster.request(True, 0, schema, 1, 2, 3, 4)
    assert cluster._endpoint.request.call_count == 1
    cluster._endpoint.request.reset_mock()

    res = cluster.request(True, 0, schema, 1, 2, 3, 4, 5)
    assert type(res.exception()) == ValueError
    assert cluster._endpoint.request.call_count == 0
    cluster._endpoint.request.reset_mock()
Esempio n. 2
0
async def test_request_optional(cluster):
    schema = [t.uint8_t, t.uint16_t, t.Optional(t.uint16_t), t.Optional(t.uint8_t)]
    cluster.endpoint.request = MagicMock()

    res = cluster.request(True, 0, schema)
    assert isinstance(res.exception(), ValueError)
    assert cluster._endpoint.request.call_count == 0
    cluster._endpoint.request.reset_mock()

    res = cluster.request(True, 0, schema, 1)
    assert isinstance(res.exception(), ValueError)
    assert cluster._endpoint.request.call_count == 0
    cluster._endpoint.request.reset_mock()

    cluster.request(True, 0, schema, 1, 2)
    assert cluster._endpoint.request.call_count == 1
    cluster._endpoint.request.reset_mock()

    cluster.request(True, 0, schema, 1, 2, 3)
    assert cluster._endpoint.request.call_count == 1
    cluster._endpoint.request.reset_mock()

    cluster.request(True, 0, schema, 1, 2, 3, 4)
    assert cluster._endpoint.request.call_count == 1
    cluster._endpoint.request.reset_mock()

    res = cluster.request(True, 0, schema, 1, 2, 3, 4, 5)
    assert isinstance(res.exception(), TypeError)
    assert cluster._endpoint.request.call_count == 0
    cluster._endpoint.request.reset_mock()
Esempio n. 3
0
class Alarms(Cluster):
    """ Attributes and commands for sending notifications and
    configuring alarm functionality."""

    cluster_id = 0x0009
    ep_attribute = "alarms"
    attributes = {
        # Alarm Information
        0x0000: ("alarm_count", t.uint16_t)
    }
    server_commands = {
        0x0000: ("reset", (t.uint8_t, t.uint16_t), False),
        0x0001: ("reset_all", (), False),
        0x0002: ("get_alarm", (), False),
        0x0003: ("reset_log", (), False),
        0x0004: ("publish_event_log", (), False),
    }
    client_commands = {
        0x0000: ("alarm", (t.uint8_t, t.uint16_t), False),
        0x0001: (
            "get_alarm_response",
            (
                t.uint8_t,
                t.Optional(t.uint8_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint32_t),
            ),
            True,
        ),
        0x0002: ("get_event_log", (), False),
    }
Esempio n. 4
0
def test_optional():
    d, r = t.Optional(t.uint8_t).deserialize(b'')
    assert d is None
    assert r == b''

    d, r = t.Optional(t.uint8_t).deserialize(b'\x001234aaa')
    assert d == 0
    assert r == b'1234aaa'
Esempio n. 5
0
def test_optional():
    d, r = t.Optional(t.uint8_t).deserialize(b"")
    assert d is None
    assert r == b""

    d, r = t.Optional(t.uint8_t).deserialize(b"\x001234aaa")
    assert d == 0
    assert r == b"1234aaa"
Esempio n. 6
0
    def deserialize(cls, data):
        r = cls()
        r.status, data = Status.deserialize(data)
        if r.status == Status.SUCCESS:
            r.direction, data = t.Optional(t.uint8_t).deserialize(data)
            if r.direction is not None:
                r.direction = ReportingDirection(r.direction)
            r.attrid, data = t.Optional(t.uint16_t).deserialize(data)
            return r, data

        r.direction, data = ReportingDirection.deserialize(data)
        r.attrid, data = t.uint16_t.deserialize(data)
        return r, data
Esempio n. 7
0
class DevelcoIASZone(CustomCluster, IasZone):
    """IAS Zone."""

    manufacturer_client_commands = {
        0x0000: (
            "status_change_notification",
            (
                IasZone.ZoneStatus,
                t.bitmap8,
                t.Optional(t.uint8_t),
                t.Optional(t.uint16_t),
            ),
            False,
        )
    }
Esempio n. 8
0
class SmartThingsIasZone(CustomCluster, IasZone):
    """IasZone cluster patched to support SmartThings spec violations."""

    client_commands = IasZone.client_commands.copy()
    client_commands[0x0000] = (
        "status_change_notification",
        (
            IasZone.ZoneStatus,
            t.bitmap8,
            # SmartThings never sends these two
            t.Optional(t.uint8_t),
            t.Optional(t.uint16_t),
        ),
        False,
    )
Esempio n. 9
0
class DevelcoIasZone(CustomCluster, IasZone):
    """Custom IasZone for Develco."""

    client_commands = {
        0x0000: (
            "status_change_notification",
            (
                IasZone.ZoneStatus,
                t.Optional(t.bitmap8),
                t.Optional(t.uint8_t),
                t.Optional(t.uint16_t),
            ),
            False,
        ),
        0x0001: ("enroll", (IasZone.ZoneType, t.uint16_t), False),
    }
Esempio n. 10
0
def test_struct_optional_init():
    class TestStruct(t.Struct):
        _fields = [("a", t.uint8_t), ("b", t.uint16_t),
                   ("c", t.CharacterString)]

    ts = TestStruct(1, 0x0100, "TestStruct")
    ts_copy = TestStruct(ts)
    ts_optional = t.Optional(TestStruct)(ts)

    assert ts.serialize() == ts_copy.serialize() == ts_optional.serialize()
Esempio n. 11
0
def test_optional_struct_special_case():
    class TestStruct(t.Struct):
        foo: t.uint8_t

    OptionalTestStruct = t.Optional(TestStruct)

    assert OptionalTestStruct.deserialize(b"") == (None, b"")
    assert OptionalTestStruct.deserialize(b"\x00") == (
        OptionalTestStruct(foo=0x00),
        b"",
    )
Esempio n. 12
0
class Scenes(Cluster):
    """Attributes and commands for scene configuration and
    manipulation."""

    cluster_id = 0x0005
    ep_attribute = "scenes"
    attributes = {
        # Scene Management Information
        0x0000: ("count", t.uint8_t),
        0x0001: ("current_scene", t.uint8_t),
        0x0002: ("current_group", t.uint16_t),
        0x0003: ("scene_valid", t.Bool),
        0x0004: ("name_support", t.bitmap8),
        0x0005: ("last_configured_by", t.EUI64),
    }
    server_commands = {
        0x0000: (
            "add",
            (t.uint16_t, t.uint8_t, t.uint16_t, t.CharacterString),
            False,
        ),  # + extension field sets
        0x0001: ("view", (t.uint16_t, t.uint8_t), False),
        0x0002: ("remove", (t.uint16_t, t.uint8_t), False),
        0x0003: ("remove_all", (t.uint16_t, ), False),
        0x0004: ("store", (t.uint16_t, t.uint8_t), False),
        0x0005: ("recall", (t.uint16_t, t.uint8_t), False),
        0x0006: ("get_scene_membership", (t.uint16_t, ), False),
        0x0040: ("enhanced_add", (), False),
        0x0041: ("enhanced_view", (), False),
        0x0042: ("copy", (), False),
    }
    client_commands = {
        0x0000: ("add_response", (t.uint8_t, t.uint16_t, t.uint8_t), True),
        0x0001: (
            "view_response",
            (t.uint8_t, t.uint16_t, t.uint8_t),
            True,
        ),  # + 3 more optionals
        0x0002: ("remove_response", (t.uint8_t, t.uint16_t, t.uint8_t), True),
        0x0003: ("remove_all_response", (t.uint8_t, t.uint16_t), True),
        0x0004: ("store_response", (t.uint8_t, t.uint16_t, t.uint8_t), True),
        0x0006: (
            "get_scene_membership_response",
            (t.uint8_t, t.uint8_t, t.uint16_t,
             t.Optional(t.LVList(t.uint8_t))),
            True,
        ),
        0x0040: ("enhanced_add_response", (), True),
        0x0041: ("enhanced_view_response", (), True),
        0x0042: ("copy_response", (), True),
    }
Esempio n. 13
0
class DeviceState(pt.Command):
    SCHEMA = (
        pt.DeviceState,
        t.uint8_t,
        t.Optional(t.uint8_t),
    )

    device_state = attr.ib(factory=SCHEMA[0])
    reserved_2 = attr.ib(factory=SCHEMA[1])
    reserved_3 = attr.ib(factory=SCHEMA[2])

    def pretty_print(self, *args):
        self.device_state.pretty_print()
        self.print("Reserved: {} Shall be ignored".format(self.reserved_2))
        self.print("Reserved: {} Shall be ignored".format(self.reserved_3))
Esempio n. 14
0
class PowerProfile(Cluster):
    cluster_id = 0x001A
    ep_attribute = "power_profile"
    attributes = {
        0x0000: ("total_profile_num", t.uint8_t),
        0x0001: ("multiple_scheduling", t.uint8_t),
        0x0002: ("energy_formatting", t.bitmap8),
        0x0003: ("energy_remote", t.Bool),
        0x0004: ("schedule_mode", t.bitmap8),
    }

    class ScheduleRecord(t.Struct):
        _fields = [("phase_id", t.uint8_t), ("scheduled_time", t.uint16_t)]

    class PowerProfilePhase(t.Struct):
        _fields = [
            ("energy_phase_id", t.uint8_t),
            ("macro_phase_id", t.uint8_t),
            ("expected_duration", t.uint16_t),
            ("peak_power", t.uint16_t),
            ("energy", t.uint16_t),
        ]

    class PowerProfile(t.Struct):
        _fields = [
            ("power_profile_id", t.uint8_t),
            ("energy_phase_id", t.uint8_t),
            ("power_profile_remote_control", t.Bool),
            ("power_profile_state", t.uint8_t),
        ]

    server_commands = {
        0x0000: ("power_profile_request", (t.uint8_t, ), False),
        0x0001: ("power_profile_state_request", (), False),
        0x0002: (
            "get_power_profile_price_response",
            (t.uint8_t, t.uint16_t, t.uint32_t, t.uint8_t),
            True,
        ),
        0x0003: (
            "get_overall_schedule_price_response",
            (t.uint16_t, t.uint32_t, t.uint8_t),
            True,
        ),
        0x0004: (
            "energy_phases_schedule_notification",
            (t.uint8_t, t.LVList(ScheduleRecord)),
            False,
        ),
        0x0005: (
            "energy_phases_schedule_response",
            (t.uint8_t, t.LVList(ScheduleRecord)),
            True,
        ),
        0x0006:
        ("power_profile_schedule_constraints_request", (t.uint8_t, ), False),
        0x0007: ("energy_phases_schedule_state_request", (t.uint8_t, ), False),
        0x0008: (
            "get_power_profile_price_extended_response",
            (t.uint8_t, t.uint16_t, t.uint32_t, t.uint8_t),
            True,
        ),
    }
    client_commands = {
        0x0000: (
            "power_profile_notification",
            (t.uint8_t, t.uint8_t, t.LVList(PowerProfilePhase)),
            False,
        ),
        0x0001: (
            "power_profile_response",
            (t.uint8_t, t.uint8_t, t.LVList(PowerProfilePhase)),
            True,
        ),
        0x0002:
        ("power_profile_state_response", (t.LVList(PowerProfile), ), True),
        0x0003: ("get_power_profile_price", (t.uint8_t, ), False),
        0x0004: ("power_profile_state_notification",
                 (t.LVList(PowerProfile), ), False),
        0x0005: ("get_overall_schedule_price", (), False),
        0x0006: ("energy_phases_schedule_request", (), False),
        0x0007: ("energy_phases_schedule_state_response", (t.uint8_t,
                                                           t.uint8_t), True),
        0x0008: (
            "energy_phases_schedule_state_notification",
            (t.uint8_t, t.uint8_t),
            False,
        ),
        0x0009: (
            "power_profile_schedule_constraints_notification",
            (t.uint8_t, t.uint16_t, t.uint16_t),
            False,
        ),
        0x000A: (
            "power_profile_schedule_constraints_response",
            (t.uint8_t, t.uint16_t, t.uint16_t),
            True,
        ),
        0x000B: (
            "get_power_profile_price_extended",
            (t.bitmap8, t.uint8_t, t.Optional(t.uint16_t)),
            False,
        ),
    }
Esempio n. 15
0
class Ota(Cluster):
    cluster_id = 0x0019
    ep_attribute = "ota"
    attributes = {
        0x0000: ("upgrade_server_id", t.EUI64),
        0x0001: ("file_offset", t.uint32_t),
        0x0002: ("current_file_version", t.uint32_t),
        0x0003: ("current_zigbee_stack_version", t.uint16_t),
        0x0004: ("downloaded_file_version", t.uint32_t),
        0x0005: ("downloaded_zigbee_stack_version", t.uint16_t),
        0x0006: ("image_upgrade_status", t.enum8),
        0x0007: ("manufacturer_id", t.uint16_t),
        0x0008: ("image_type_id", t.uint16_t),
        0x0009: ("minimum_block_req_delay", t.uint16_t),
        0x000A: ("image_stamp", t.uint32_t),
    }
    server_commands = {
        0x0001: (
            "query_next_image",
            (t.uint8_t, t.uint16_t, t.uint16_t, t.uint32_t,
             t.Optional(t.uint16_t)),
            False,
        ),
        0x0003: (
            "image_block",
            (
                t.uint8_t,
                t.uint16_t,
                t.uint16_t,
                t.uint32_t,
                t.uint32_t,
                t.uint8_t,
                t.Optional(t.EUI64),
                t.Optional(t.uint16_t),
            ),
            False,
        ),
        0x0004: (
            "image_page",
            (
                t.uint8_t,
                t.uint16_t,
                t.uint16_t,
                t.uint32_t,
                t.uint32_t,
                t.uint8_t,
                t.uint16_t,
                t.uint16_t,
                t.Optional(t.EUI64),
            ),
            False,
        ),
        0x0006: (
            "upgrade_end",
            (foundation.Status, t.uint16_t, t.uint16_t, t.uint32_t),
            False,
        ),
        0x0008: (
            "query_specific_file",
            (t.EUI64, t.uint16_t, t.uint16_t, t.uint32_t, t.uint16_t),
            False,
        ),
    }
    client_commands = {
        0x0000: (
            "image_notify",
            (
                t.uint8_t,
                t.uint8_t,
                t.Optional(t.uint16_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint32_t),
            ),
            False,
        ),
        0x0002: (
            "query_next_image_response",
            (
                foundation.Status,
                t.Optional(t.uint16_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint32_t),
                t.Optional(t.uint32_t),
            ),
            True,
        ),
        0x0005: (
            "image_block_response",
            (
                foundation.Status,
                t.uint16_t,
                t.uint16_t,
                t.uint32_t,
                t.uint32_t,
                t.LVBytes,
            ),
            True,
        ),
        0x0007: (
            "upgrade_end_response",
            (t.uint16_t, t.uint16_t, t.uint32_t, t.uint32_t, t.uint32_t),
            True,
        ),
        0x0009: (
            "query_specific_file_response",
            (
                foundation.Status,
                t.Optional(t.uint16_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint32_t),
                t.Optional(t.uint32_t),
            ),
            True,
        ),
    }

    def handle_cluster_request(self, tsn, command_id, args):
        self.create_catching_task(
            self._handle_cluster_request(tsn, command_id, args),
            exceptions=(AssertionError, asyncio.TimeoutError, DeliveryError),
        )

    async def _handle_cluster_request(self, tsn, command_id, args):
        """Parse OTA commands."""
        cmd_name = self.server_commands.get(command_id, [command_id])[0]

        if cmd_name == "query_next_image":
            await self._handle_query_next_image(*args, tsn=tsn)
        elif cmd_name == "image_block":
            await self._handle_image_block(*args, tsn=tsn)
        elif cmd_name == "upgrade_end":
            await self._handle_upgrade_end(*args, tsn=tsn)
        else:
            self.debug(
                "no '%s' OTA command handler for '%s %s': %s",
                cmd_name,
                self.endpoint.manufacturer,
                self.endpoint.model,
                args,
            )

    async def _handle_query_next_image(self, field_ctrl, manufacturer_id,
                                       image_type, current_file_version,
                                       hardware_version, *, tsn):
        self.debug(
            ("OTA query_next_image handler for '%s %s': "
             "field_control=%s, manufacture_id=%s, image_type=%s, "
             "current_file_version=%s, hardware_version=%s"),
            self.endpoint.manufacturer,
            self.endpoint.model,
            field_ctrl,
            manufacturer_id,
            image_type,
            current_file_version,
            hardware_version,
        )

        img = await self.endpoint.device.application.ota.get_ota_image(
            manufacturer_id, image_type)

        if img is not None:
            should_update = img.should_update(manufacturer_id, image_type,
                                              current_file_version,
                                              hardware_version)
            self.debug(
                "OTA image version: %s, size: %s. Update needed: %s",
                img.version,
                img.header.image_size,
                should_update,
            )
            if should_update:
                self.info("Updating: %s %s", self.endpoint.manufacturer,
                          self.endpoint.model)
                await self.query_next_image_response(
                    foundation.Status.SUCCESS,
                    img.key.manufacturer_id,
                    img.key.image_type,
                    img.version,
                    img.header.image_size,
                    tsn=tsn,
                )
                return
        else:
            self.debug("No OTA image is available")
        await self.query_next_image_response(
            foundation.Status.NO_IMAGE_AVAILABLE, tsn=tsn)

    async def _handle_image_block(self,
                                  field_ctr,
                                  manufacturer_id,
                                  image_type,
                                  file_version,
                                  file_offset,
                                  max_data_size,
                                  request_node_addr,
                                  block_request_delay,
                                  *,
                                  tsn=None):
        self.debug(
            ("OTA image_block handler for '%s %s': field_control=%s, "
             "manufacturer_id=%s, image_type=%s, file_version=%s, "
             "file_offset=%s, max_data_size=%s, request_node_addr=%s"
             "block_request_delay=%s"),
            self.endpoint.manufacturer,
            self.endpoint.model,
            field_ctr,
            manufacturer_id,
            image_type,
            file_version,
            file_offset,
            max_data_size,
            request_node_addr,
            block_request_delay,
        )
        img = await self.endpoint.device.application.ota.get_ota_image(
            manufacturer_id, image_type)
        if img is None or img.version != file_version:
            self.debug("OTA image is not available")
            await self.image_block_response(foundation.Status.ABORT, tsn=tsn)
            return
        self.debug("OTA upgrade progress: %0.1f",
                   100.0 * file_offset / img.header.image_size)
        try:
            await self.image_block_response(
                foundation.Status.SUCCESS,
                img.key.manufacturer_id,
                img.key.image_type,
                img.version,
                file_offset,
                img.get_image_block(file_offset, max_data_size),
                tsn=tsn,
            )
        except ValueError:
            await self.image_block_response(
                foundation.Status.MALFORMED_COMMAND, tsn=tsn)

    async def _handle_upgrade_end(self, status, manufacturer_id, image_type,
                                  file_ver, *, tsn):
        self.debug(
            ("OTA upgrade_end handler for '%s %s': status=%s, "
             "manufacturer_id=%s, image_type=%s, file_version=%s"),
            self.endpoint.manufacturer,
            self.endpoint.model,
            status,
            manufacturer_id,
            image_type,
            file_ver,
        )
        await self.upgrade_end_response(manufacturer_id,
                                        image_type,
                                        file_ver,
                                        0x00000000,
                                        0x00000000,
                                        tsn=tsn)
Esempio n. 16
0
class RSSILocation(Cluster):
    """Attributes and commands that provide a means for
    exchanging location information and channel parameters
    among devices."""

    cluster_id = 0x000B
    ep_attribute = "rssi_location"
    attributes = {
        # Location Information
        0x0000: ("type", t.uint8_t),
        0x0001: ("method", t.enum8),
        0x0002: ("age", t.uint16_t),
        0x0003: ("quality_measure", t.uint8_t),
        0x0004: ("num_of_devices", t.uint8_t),
        # Location Settings
        0x0010: ("coordinate1", t.int16s),
        0x0011: ("coordinate2", t.int16s),
        0x0012: ("coordinate3", t.int16s),
        0x0013: ("power", t.int16s),
        0x0014: ("path_loss_exponent", t.uint16_t),
        0x0015: ("reporting_period", t.uint16_t),
        0x0016: ("calc_period", t.uint16_t),
        0x0017: ("num_rssi_measurements", t.uint16_t),
    }
    server_commands = {
        0x0000: (
            "set_absolute_location",
            (t.int16s, t.int16s, t.int16s, t.int8s, t.uint16_t),
            False,
        ),
        0x0001: (
            "set_dev_config",
            (t.int16s, t.uint16_t, t.uint16_t, t.uint8_t, t.uint16_t),
            False,
        ),
        0x0002: ("get_dev_config", (t.EUI64, ), False),
        0x0003: ("get_location_data", (t.bitmap8, t.uint8_t, t.EUI64), False),
        0x0004: (
            "rssi_response",
            (t.EUI64, t.int16s, t.int16s, t.int16s, t.int8s, t.uint8_t),
            True,
        ),
        0x0005: ("send_pings", (t.EUI64, t.uint8_t, t.uint16_t), False),
        0x0006: (
            "anchor_node_announce",
            (t.EUI64, t.int16s, t.int16s, t.int16s),
            False,
        ),
    }

    class NeighborInfo(t.Struct):
        _fields = [
            ("neighbor", t.EUI64),
            ("x", t.int16s),
            ("y", t.int16s),
            ("z", t.int16s),
            ("rssi", t.int8s),
            ("num_measurements", t.uint8_t),
        ]

    client_commands = {
        0x0000: (
            "dev_config_response",
            (
                foundation.Status,
                t.Optional(t.int16s),
                t.Optional(t.uint16_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint16_t),
            ),
            True,
        ),
        0x0001: (
            "location_data_response",
            (
                foundation.Status,
                t.Optional(t.uint8_t),
                t.Optional(t.int16s),
                t.Optional(t.int16s),
                t.Optional(t.int16s),
                t.Optional(t.uint16_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint16_t),
            ),
            True,
        ),
        0x0002: ("location_data_notification", (), False),
        0x0003: ("compact_location_data_notification", (), False),
        0x0004: ("rssi_ping", (t.uint8_t, ), False),  # data8
        0x0005: ("rssi_req", (), False),
        0x0006:
        ("report_rssi_measurements", (t.EUI64, t.LVList(NeighborInfo)), False),
        0x0007: ("request_own_location", (t.EUI64, ), False),
    }
Esempio n. 17
0
async def zcl_cmd(app, listener, ieee, cmd, data, service, event_data, params):
    from zigpy import types as t

    # Verify parameter presence

    if ieee is None:
        msg = ERR003_PARAMETER_MISSING.format("ieee")
        LOGGER.error(msg)
        raise Exception(msg)

    dev = app.get_device(ieee=ieee)

    # Decode endpoint
    if params[p.EP_ID] is None or params[p.EP_ID] == "":
        params[p.EP_ID] = u.find_endpoint(dev, params[p.CLUSTER_ID])

    if params[p.EP_ID] not in dev.endpoints:
        LOGGER.error("Endpoint %s not found for '%s'", params[p.EP_ID],
                     repr(ieee))

    if params[p.CLUSTER_ID] not in dev.endpoints[params[p.EP_ID]].in_clusters:
        LOGGER.error(
            "Cluster 0x%04X not found for '%s', endpoint %s",
            params[p.CLUSTER_ID],
            repr(ieee),
            params[p.EP_ID],
        )

    # Extract parameters

    # Endpoint to send command to
    ep_id = params[p.EP_ID]
    # Cluster to send command to
    cluster_id = params[p.CLUSTER_ID]
    # The command to send
    cmd_id = params[p.CMD_ID]
    if cmd_id is None:
        raise Exception(ERR003_PARAMETER_MISSING, P.CMD)

    # The direction (to in or out cluster)
    dir_int = params[p.DIR]

    # Get manufacturer
    manf = params[p.MANF]

    # Get tries
    tries = params[p.TRIES]

    # Get expect_reply
    expect_reply = params[p.EXPECT_REPLY]

    cmd_args = params[p.ARGS]

    # Direction 0 = Client to Server, as in protocol bit
    is_in_cluster = dir_int == 0

    if ep_id not in dev.endpoints:
        msg = f"Endpoint {ep_id} not found for '{repr(ieee)}'"
        LOGGER.error(msg)
        raise Exception(msg)

    endpoint = dev.endpoints[ep_id]

    org_cluster_cmd_defs = {}

    # Exception caught in the try/catch below to throw after
    #   restoring cluster definitions
    caught_e = None

    try:
        if is_in_cluster:
            if cluster_id not in endpoint.in_clusters:
                msg = ERR004_NOT_IN_CLUSTER.format(cluster_id, repr(ieee),
                                                   ep_id)
                LOGGER.error(msg)
                raise Exception(msg)
            else:
                cluster = endpoint.in_clusters[cluster_id]

            if (cluster_id == 5) and (cmd_id == 0):
                org_cluster_cmd_defs[0] = cluster.server_commands[0]
                cluster.server_commands[0] = (
                    "add",
                    (
                        t.uint16_t,
                        t.uint8_t,
                        t.uint16_t,
                        t.CharacterString,
                        t.Optional(t.List[t.uint8_t]),
                    ),
                    False,
                )
            if "tries" in inspect.getfullargspec(cluster.command)[0]:
                await cluster.command(
                    cmd_id,
                    *cmd_args,
                    manufacturer=manf,
                    expect_reply=expect_reply,
                    tries=tries,
                )
            else:
                await cluster.command(
                    cmd_id,
                    *cmd_args,
                    manufacturer=manf,
                    expect_reply=expect_reply,
                )
        else:
            if cluster_id not in endpoint.out_clusters:
                msg = ERR005_NOT_OUT_CLUSTER.format(cluster_id, repr(ieee),
                                                    ep_id)
                LOGGER.error(msg)
                raise Exception(msg)
            else:
                cluster = endpoint.out_clusters[cluster_id]

            # Note: client_command not tested
            await cluster.client_command(cmd_id, *cmd_args, manufacturer=manf)
    except Exception as e:
        caught_e = e
    finally:
        # Restore replaced cluster command definitions
        # LOGGER.debug("replaced %s", org_cluster_cmd_defs)
        for key, _value in org_cluster_cmd_defs.items():
            if is_in_cluster:
                cluster.server_commands[key] = org_cluster_cmd_defs[key]
            else:
                cluster.client_commands[key] = org_cluster_cmd_defs[key]
        if caught_e is not None:
            raise caught_e
Esempio n. 18
0
 ZDOCmd.Mgmt_Bind_req: (("StartIndex", t.uint8_t),),
 # ... TODO optional stuff ...
 ZDOCmd.Mgmt_Leave_req: (("DeviceAddress", t.EUI64), ("Options", t.bitmap8)),
 ZDOCmd.Mgmt_Permit_Joining_req: (
     ("PermitDuration", t.uint8_t),
     ("TC_Significant", t.Bool),
 ),
 ZDOCmd.Mgmt_NWK_Update_req: (("NwkUpdate", NwkUpdate),),
 # ... TODO optional stuff ...
 # Responses
 # Device and Service Discovery Server Responses
 ZDOCmd.NWK_addr_rsp: (
     STATUS,
     IEEE,
     NWK,
     ("NumAssocDev", t.Optional(t.uint8_t)),
     ("StartIndex", t.Optional(t.uint8_t)),
     ("NWKAddressAssocDevList", t.Optional(t.List[t.NWK])),
 ),
 ZDOCmd.IEEE_addr_rsp: (
     STATUS,
     IEEE,
     NWK,
     ("NumAssocDev", t.Optional(t.uint8_t)),
     ("StartIndex", t.Optional(t.uint8_t)),
     ("NWKAddrAssocDevList", t.Optional(t.List[t.NWK])),
 ),
 ZDOCmd.Node_Desc_rsp: (
     STATUS,
     NWKI,
     ("NodeDescriptor", t.Optional(NodeDescriptor)),
Esempio n. 19
0
class LightLink(Cluster):
    cluster_id = 0x1000
    ep_attribute = 'lightlink'
    attributes = {}
    server_commands = {
        0x0000: ('scan', (
            t.uint32_t,
            t.bitmap8,
            t.bitmap8,
        ), False),
        0x0002: ('device_information', (
            t.uint32_t,
            t.uint8_t,
        ), False),
        0x0006: ('identify', (
            t.uint32_t,
            t.uint16_t,
        ), False),
        0x0007: ('reset_to_factory_new', (t.uint32_t, ), False),
        0x0010: ('network_start', NET_START, False),
        0x0012: ('network_join_router', NET_JOIN, False),
        0x0014: ('network_join_end_device', NET_JOIN, False),
        0x0016: ('network_update', (
            t.uint32_t,
            t.EUI64,
            t.uint8_t,
            t.uint8_t,
            t.NWK,
            t.NWK,
        ), False),
        0x0041: ('get_group_identifiers', (t.uint8_t, ), False),
        0x0042: ('get_endpoint_list', (t.uint8_t, ), False),
    }
    client_commands = {
        0x0001:
        ('scan_rsp', (t.uint32_t, t.uint8_t, t.bitmap8, t.bitmap8, t.bitmap16,
                      t.uint32_t, t.EUI64, t.uint8_t, t.uint8_t, t.NWK, t.NWK,
                      t.uint8_t, t.uint8_t, t.Optional(t.uint8_t),
                      t.Optional(t.uint16_t), t.Optional(t.uint16_t),
                      t.Optional(t.uint8_t), t.Optional(t.uint8_t)), True),
        0x0003: ('device_information_rsp', (
            t.uint32_t,
            t.uint8_t,
            t.uint8_t,
            t.LVList(DeviceInfoRecord),
        ), True),
        0x0011: ('network_start_rsp', (
            t.uint32_t,
            foundation.Status,
            t.EUI64,
            t.uint8_t,
            t.uint8_t,
            t.uint16_t,
        ), True),
        0x0013: ('network_join_router_rsp', (
            t.uint32_t,
            foundation.Status,
        ), True),
        0x0015: ('network_join_end_device_rsp', (
            t.uint32_t,
            foundation.Status,
        ), True),
        0x0040: ('endpoint_information', (
            t.EUI64,
            t.NWK,
            t.uint8_t,
            t.uint16_t,
            t.uint16_t,
            t.uint8_t,
        ), True),
        0x0041: ('get_group_identifiers_rsp', (
            t.uint8_t,
            t.uint8_t,
            t.LVList(GroupInfoRecord),
        ), True),
        0x0042: ('get_endpoint_list_rsp',
                 (t.uint8_t, t.uint8_t, t.LVList(EndpointInfoRecord)), True),
    }
Esempio n. 20
0
                                                    MultiAddress)),
    # Network Management Server Services Requests
    # ... TODO optional stuff ...
    ZDOCmd.Mgmt_Lqi_req: (('StartIndex', t.uint8_t), ),
    ZDOCmd.Mgmt_Rtg_req: (('StartIndex', t.uint8_t), ),
    # ... TODO optional stuff ...
    ZDOCmd.Mgmt_Leave_req: (('DeviceAddress', t.EUI64), ('Options',
                                                         t.bitmap8)),
    ZDOCmd.Mgmt_Permit_Joining_req: (('PermitDuration', t.uint8_t),
                                     ('TC_Significant', t.Bool)),
    # ... TODO optional stuff ...

    # Responses
    # Device and Service Discovery Server Responses
    ZDOCmd.NWK_addr_rsp:
    (STATUS, IEEE, NWK, ('NumAssocDev', t.Optional(t.uint8_t)),
     ('StartIndex', t.Optional(t.uint8_t)), ('NWKAddressAssocDevList',
                                             t.Optional(t.List(t.NWK)))),
    ZDOCmd.IEEE_addr_rsp: (STATUS, IEEE, NWK, ('NumAssocDev',
                                               t.Optional(t.uint8_t)),
                           ('StartIndex', t.Optional(t.uint8_t)),
                           ('NWKAddrAssocDevList', t.Optional(t.List(t.NWK)))),
    ZDOCmd.Node_Desc_rsp: (STATUS, NWKI, ('NodeDescriptor',
                                          t.Optional(NodeDescriptor))),
    ZDOCmd.Power_Desc_rsp: (STATUS, NWKI, ('PowerDescriptor',
                                           t.Optional(PowerDescriptor))),
    ZDOCmd.Simple_Desc_rsp: (STATUS, NWKI,
                             ('SimpleDescriptor',
                              t.Optional(SizePrefixedSimpleDescriptor))),
    ZDOCmd.Active_EP_rsp: (STATUS, NWKI, ('ActiveEPList',
                                          t.LVList(t.uint8_t))),
Esempio n. 21
0
class DoorLock(Cluster):
    """The door lock cluster provides an interface to a generic way to secure a door."""
    class LockState(t.enum8):
        Not_fully_locked = 0x00
        Locked = 0x01
        Unlocked = 0x02
        Undefined = 0xFF

    class LockType(t.enum8):
        Dead_bolt = 0x00
        Magnetic = 0x01
        Other = 0x02
        Mortise = 0x03
        Rim = 0x04
        Latch_bolt = 0x05
        Cylindrical_lock = 0x06
        Tubular_lock = 0x07
        Interconnected_lock = 0x08
        Dead_latch = 0x09
        Door_furniture = 0x0A

    class DoorState(t.enum8):
        Open = 0x00
        Closed = 0x01
        Error_jammed = 0x02
        Error_forced_open = 0x03
        Error_unspecified = 0x04
        Undefined = 0xFF

    class OperatingMode(t.enum8):
        Normal = 0x00
        Vacation = 0x01
        Privacy = 0x02
        No_RF_Lock_Unlock = 0x03
        Passage = 0x04

    class SupportedOperatingModes(t.bitmap16):
        Normal = 0x0001
        Vacation = 0x0002
        Privacy = 0x0004
        No_RF = 0x0008
        Passage = 0x0010

    class DefaultConfigurationRegister(t.bitmap16):
        Enable_Local_Programming = 0x0001
        Keypad_Interface_default_access = 0x0002
        RF_Interface_default_access = 0x0004
        Sound_Volume_non_zero = 0x0020
        Auto_Relock_time_non_zero = 0x0040
        Led_settings_non_zero = 0x0080

    class ZigbeeSecurityLevel(t.enum8):
        Network_Security = 0x00
        APS_Security = 0x01

    class AlarmMask(t.bitmap16):
        Deadbolt_Jammed = 0x0001
        Lock_Reset_to_Factory_Defaults = 0x0002
        Reserved = 0x0004
        RF_Module_Power_Cycled = 0x0008
        Tamper_Alarm_wrong_code_entry_limit = 0x0010
        Tamper_Alarm_front_escutcheon_removed = 0x0020
        Forced_Door_Open_under_Door_Lockec_Condition = 0x0040

    class KeypadOperationEventMask(t.bitmap16):
        Manufacturer_specific = 0x0001
        Lock_source_keypad = 0x0002
        Unlock_source_keypad = 0x0004
        Lock_source_keypad_error_invalid_code = 0x0008
        Lock_source_keypad_error_invalid_schedule = 0x0010
        Unlock_source_keypad_error_invalid_code = 0x0020
        Unlock_source_keypad_error_invalid_schedule = 0x0040
        Non_Access_User_Operation = 0x0080

    class RFOperationEventMask(t.bitmap16):
        Manufacturer_specific = 0x0001
        Lock_source_RF = 0x0002
        Unlock_source_RF = 0x0004
        Lock_source_RF_error_invalid_code = 0x0008
        Lock_source_RF_error_invalid_schedule = 0x0010
        Unlock_source_RF_error_invalid_code = 0x0020
        Unlock_source_RF_error_invalid_schedule = 0x0040

    class ManualOperatitonEventMask(t.bitmap16):
        Manufacturer_specific = 0x0001
        Thumbturn_Lock = 0x0002
        Thumbturn_Unlock = 0x0004
        One_touch_lock = 0x0008
        Key_Lock = 0x0010
        Key_Unlock = 0x0020
        Auto_lock = 0x0040
        Schedule_Lock = 0x0080
        Schedule_Unlock = 0x0100
        Manual_Lock_key_or_thumbturn = 0x0200
        Manual_Unlock_key_or_thumbturn = 0x0400

    class RFIDOperationEventMask(t.bitmap16):
        Manufacturer_specific = 0x0001
        Lock_source_RFID = 0x0002
        Unlock_source_RFID = 0x0004
        Lock_source_RFID_error_invalid_RFID_ID = 0x0008
        Lock_source_RFID_error_invalid_schedule = 0x0010
        Unlock_source_RFID_error_invalid_RFID_ID = 0x0020
        Unlock_source_RFID_error_invalid_schedule = 0x0040

    class KeypadProgrammingEventMask(t.bitmap16):
        Manufacturer_Specific = 0x0001
        Master_code_changed = 0x0002
        PIN_added = 0x0004
        PIN_deleted = 0x0008
        PIN_changed = 0x0010

    class RFProgrammingEventMask(t.bitmap16):
        Manufacturer_Specific = 0x0001
        PIN_added = 0x0004
        PIN_deleted = 0x0008
        PIN_changed = 0x0010
        RFID_code_added = 0x0020
        RFID_code_deleted = 0x0040

    class RFIDProgrammingEventMask(t.bitmap16):
        Manufacturer_Specific = 0x0001
        RFID_code_added = 0x0020
        RFID_code_deleted = 0x0040

    class OperationEventSource(t.enum8):
        Keypad = 0x00
        RF = 0x01
        Manual = 0x02
        RFID = 0x03
        Indeterminate = 0xFF

    class OperationEvent(t.enum8):
        UnknownOrMfgSpecific = 0x00
        Lock = 0x01
        Unlock = 0x02
        LockFailureInvalidPINorID = 0x03
        LockFailureInvalidSchedule = 0x04
        UnlockFailureInvalidPINorID = 0x05
        UnlockFailureInvalidSchedule = 0x06
        OnTouchLock = 0x07
        KeyLock = 0x08
        KeyUnlock = 0x09
        AutoLock = 0x0A
        ScheduleLock = 0x0B
        ScheduleUnlock = 0x0C
        Manual_Lock = 0x0D
        Manual_Unlock = 0x0E
        Non_Access_User_Operational_Event = 0x0F

    class ProgrammingEvent(t.enum8):
        UnknownOrMfgSpecific = 0x00
        MasterCodeChanged = 0x01
        PINCodeAdded = 0x02
        PINCodeDeleted = 0x03
        PINCodeChanges = 0x04
        RFIDCodeAdded = 0x05
        RFIDCodeDeleted = 0x06

    class UserStatus(t.enum8):
        Available = 0x00
        Enabled = 0x01
        Disabled = 0x03
        Not_Supported = 0xFF

    class UserType(t.enum8):
        Unrestricted = 0x00
        Year_Day_Schedule_User = 0x01
        Week_Day_Schedule_User = 0x02
        Master_User = 0x03
        Non_Access_User = 0x04
        Not_Supported = 0xFF

    class DayMask(t.bitmap8):
        Sun = 0x01
        Mon = 0x02
        Tue = 0x04
        Wed = 0x08
        Thu = 0x10
        Fri = 0x20
        Sat = 0x40

    class EventType(t.enum8):
        Operation = 0x00
        Programming = 0x01
        Alarm = 0x02

    cluster_id = 0x0101
    name = "Door Lock"
    ep_attribute = "door_lock"
    attributes = {
        0x0000: ("lock_state", LockState),
        0x0001: ("lock_type", LockType),
        0x0002: ("actuator_enabled", t.Bool),
        0x0003: ("door_state", DoorState),
        0x0004: ("door_open_events", t.uint32_t),
        0x0005: ("door_closed_events", t.uint32_t),
        0x0006: ("open_period", t.uint16_t),
        0x0010: ("num_of_lock_records_supported", t.uint16_t),
        0x0011: ("num_of_total_users_supported", t.uint16_t),
        0x0012: ("num_of_pin_users_supported", t.uint16_t),
        0x0013: ("num_of_rfid_users_supported", t.uint16_t),
        0x0014: ("num_of_week_day_schedules_supported_per_user", t.uint8_t),
        0x0015: ("num_of_year_day_schedules_supported_per_user", t.uint8_t),
        0x0016: ("num_of_holiday_scheduleds_supported", t.uint8_t),
        0x0017: ("max_pin_len", t.uint8_t),
        0x0018: ("min_pin_len", t.uint8_t),
        0x0019: ("max_rfid_len", t.uint8_t),
        0x001A: ("min_rfid_len", t.uint8_t),
        0x0020: ("enable_logging", t.Bool),
        0x0021: ("language", t.LimitedCharString(3)),
        0x0022: ("led_settings", t.uint8_t),
        0x0023: ("auto_relock_time", t.uint32_t),
        0x0024: ("sound_volume", t.uint8_t),
        0x0025: ("operating_mode", OperatingMode),
        0x0026: ("supported_operating_modes", SupportedOperatingModes),
        0x0027:
        ("default_configuration_register", DefaultConfigurationRegister),
        0x0028: ("enable_local_programming", t.Bool),
        0x0029: ("enable_one_touch_locking", t.Bool),
        0x002A: ("enable_inside_status_led", t.Bool),
        0x002B: ("enable_privacy_mode_button", t.Bool),
        0x0030: ("wrong_code_entry_limit", t.uint8_t),
        0x0031: ("user_code_temporary_disable_time", t.uint8_t),
        0x0032: ("send_pin_ota", t.Bool),
        0x0033: ("require_pin_for_rf_operation", t.Bool),
        0x0034: ("zigbee_security_level", ZigbeeSecurityLevel),
        0x0040: ("alarm_mask", AlarmMask),
        0x0041: ("keypad_operation_event_mask", KeypadOperationEventMask),
        0x0042: ("rf_operation_event_mask", RFOperationEventMask),
        0x0043: ("manual_operation_event_mask", ManualOperatitonEventMask),
        0x0044: ("rfid_operation_event_mask", RFIDOperationEventMask),
        0x0045: ("keypad_programming_event_mask", KeypadProgrammingEventMask),
        0x0046: ("rf_programming_event_mask", RFProgrammingEventMask),
        0x0047: ("rfid_programming_event_mask", RFIDProgrammingEventMask),
    }
    server_commands = {
        0x0000: ("lock_door", (t.Optional(t.CharacterString), ), False),
        0x0001: ("unlock_door", (t.Optional(t.CharacterString), ), False),
        0x0002: ("toggle_door", (t.Optional(t.CharacterString), ), False),
        0x0003: (
            "unlock_with_timeout",
            (t.uint16_t, t.Optional(t.CharacterString)),
            False,
        ),
        0x0004: ("get_log_record", (t.uint16_t, ), False),
        0x0005: (
            "set_pin_code",
            (t.uint16_t, UserStatus, UserType, t.CharacterString),
            False,
        ),
        0x0006: ("get_pin_code", (t.uint16_t, ), False),
        0x0007: ("clear_pin_code", (t.uint16_t, ), False),
        0x0008: ("clear_all_pin_codes", (), False),
        0x0009: ("set_user_status", (t.uint16_t, UserStatus), False),
        0x000A: ("get_user_status", (t.uint16_t, ), False),
        0x000B: (
            "set_week_day_schedule",
            (
                t.uint8_t,
                t.uint16_t,
                DayMask,
                t.uint8_t,
                t.uint8_t,
                t.uint8_t,
                t.uint8_t,
            ),
            False,
        ),
        0x000C: ("get_week_day_schedule", (t.uint8_t, t.uint16_t), False),
        0x000D: ("clear_week_day_schedule", (t.uint8_t, t.uint16_t), False),
        0x000E: (
            "set_year_day_schedule",
            (t.uint8_t, t.uint16_t, t.LocalTime, t.LocalTime),
            False,
        ),
        0x000F: ("get_year_day_schedule", (t.uint8_t, t.uint16_t), False),
        0x0010: ("clear_year_day_schedule", (t.uint8_t, t.uint16_t), False),
        0x0011: (
            "set_holiday_schedule",
            (t.uint8_t, t.LocalTime, t.LocalTime, OperatingMode),
            False,
        ),
        0x0012: ("get_holiday_schedule", (t.uint8_t, ), False),
        0x0013: ("clear_holiday_schedule", (t.uint8_t, ), False),
        0x0014: ("set_user_type", (t.uint16_t, UserType), False),
        0x0015: ("get_user_type", (t.uint16_t, ), False),
        0x0016: (
            "set_rfid_code",
            (t.uint16_t, UserStatus, UserType, t.CharacterString),
            False,
        ),
        0x0017: ("get_rfid_code", (t.uint16_t, ), False),
        0x0018: ("clear_rfid_code", (t.uint16_t, ), False),
        0x0019: ("clear_all_rfid_codes", (), False),
    }
    client_commands = {
        0x0000: ("lock_door_response", (foundation.Status, ), True),
        0x0001: ("unlock_door_response", (foundation.Status, ), True),
        0x0002: ("toggle_door_response", (foundation.Status, ), True),
        0x0003: ("unlock_with_timeout_response", (foundation.Status, ), True),
        0x0004: (
            "get_log_record_response",
            (
                t.uint16_t,
                t.uint32_t,
                EventType,
                OperationEventSource,
                t.uint8_t,
                t.uint16_t,
                t.Optional(t.CharacterString),
            ),
            True,
        ),
        0x0005: ("set_pin_code_response", (foundation.Status, ), True),
        0x0006: (
            "get_pin_code_response",
            (t.uint16_t, UserStatus, UserType, t.CharacterString),
            True,
        ),
        0x0007: ("clear_pin_code_response", (foundation.Status, ), True),
        0x0008: ("clear_all_pin_codes_response", (foundation.Status, ), True),
        0x0009: ("set_user_status_response", (foundation.Status, ), True),
        0x000A: ("get_user_status_response", (t.uint16_t, UserStatus), True),
        0x000B:
        ("set_week_day_schedule_response", (foundation.Status, ), True),
        0x000C: (
            "get_week_day_schedule_response",
            (
                t.uint8_t,
                t.uint16_t,
                foundation.Status,
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
            ),
            True,
        ),
        0x000D:
        ("clear_week_day_schedule_response", (foundation.Status, ), True),
        0x000E:
        ("set_year_day_schedule_response", (foundation.Status, ), True),
        0x000F: (
            "get_year_day_schedule_response",
            (
                t.uint8_t,
                t.uint16_t,
                foundation.Status,
                t.Optional(t.LocalTime),
                t.Optional(t.LocalTime),
            ),
            True,
        ),
        0x0010:
        ("clear_year_day_schedule_response", (foundation.Status, ), True),
        0x0011: ("set_holiday_schedule_response", (foundation.Status, ), True),
        0x0012: (
            "get_holiday_schedule_response",
            (
                t.uint8_t,
                foundation.Status,
                t.Optional(t.LocalTime),
                t.Optional(t.LocalTime),
                t.Optional(t.uint8_t),
            ),
            True,
        ),
        0x0013: ("clear_holiday_schedule_response", (foundation.Status, ),
                 True),
        0x0014: ("set_user_type_response", (foundation.Status, ), True),
        0x0015: ("get_user_type_response", (t.uint16_t, UserType), True),
        0x0016: ("set_rfid_code_response", (t.uint8_t, ), True),
        0x0017: (
            "get_rfid_code_response",
            (t.uint16_t, UserStatus, UserType, t.CharacterString),
            True,
        ),
        0x0018: ("clear_rfid_code_response", (foundation.Status, ), True),
        0x0019: ("clear_all_rfid_codes_response", (foundation.Status, ), True),
        0x0020: (
            "operation_event_notification",
            (
                OperationEventSource,
                OperationEvent,
                t.uint16_t,
                t.uint8_t,
                t.LocalTime,
                t.CharacterString,
            ),
            False,
        ),
        0x0021: (
            "programming_event_notification",
            (
                OperationEventSource,
                ProgrammingEvent,
                t.uint16_t,
                t.uint8_t,
                UserType,
                UserStatus,
                t.LocalTime,
                t.CharacterString,
            ),
            False,
        ),
    }
Esempio n. 22
0
                                                    MultiAddress)),
    # Network Management Server Services Requests
    # ... TODO optional stuff ...
    ZDOCmd.Mgmt_Lqi_req: (('StartIndex', t.uint8_t), ),
    ZDOCmd.Mgmt_Rtg_req: (('StartIndex', t.uint8_t), ),
    # ... TODO optional stuff ...
    ZDOCmd.Mgmt_Leave_req: (('DeviceAddress', t.EUI64), ('Options',
                                                         t.bitmap8)),
    ZDOCmd.Mgmt_Permit_Joining_req: (('PermitDuration', t.uint8_t),
                                     ('TC_Significant', t.Bool)),
    # ... TODO optional stuff ...

    # Responses
    # Device and Service Discovery Server Responses
    ZDOCmd.NWK_addr_rsp:
    (STATUS, IEEE, NWK, ('NumAssocDev', t.Optional(t.uint8_t)),
     ('StartIndex', t.Optional(t.uint8_t)), ('NWKAddressAssocDevList',
                                             t.Optional(t.List(t.NWK)))),
    ZDOCmd.IEEE_addr_rsp: (STATUS, IEEE, NWK, ('NumAssocDev',
                                               t.Optional(t.uint8_t)),
                           ('StartIndex', t.Optional(t.uint8_t)),
                           ('NWKAddrAssocDevList', t.Optional(t.List(t.NWK)))),
    ZDOCmd.Node_Desc_rsp: (STATUS, NWKI, ('NodeDescriptor',
                                          t.Optional(NodeDescriptor))),
    ZDOCmd.Power_Desc_rsp: (STATUS, NWKI, ('PowerDescriptor',
                                           t.Optional(PowerDescriptor))),
    ZDOCmd.Simple_Desc_rsp: (STATUS, NWKI,
                             ('SimpleDescriptor',
                              t.Optional(SizePrefixedSimpleDescriptor))),
    ZDOCmd.Active_EP_rsp: (STATUS, NWKI, ('ActiveEPList',
                                          t.LVList(t.uint8_t))),
Esempio n. 23
0
class DoorLock(Cluster):
    cluster_id = 0x0101
    name = "Door Lock"
    ep_attribute = "door_lock"
    attributes = {
        0x0000: ("lock_state", t.enum8),
        0x0001: ("lock_type", t.enum8),
        0x0002: ("actuator_enabled", t.Bool),
        0x0003: ("door_state", t.enum8),
        0x0004: ("door_open_events", t.uint32_t),
        0x0005: ("door_closed_events", t.uint32_t),
        0x0006: ("open_period", t.uint16_t),
        0x0010: ("num_of_lock_records_supported", t.uint16_t),
        0x0011: ("num_of_total_users_supported", t.uint16_t),
        0x0012: ("num_of_pin_users_supported", t.uint16_t),
        0x0013: ("num_of_rfid_users_supported", t.uint16_t),
        0x0014: ("num_of_week_day_schedules_supported_per_user", t.uint8_t),
        0x0015: ("num_of_year_day_schedules_supported_per_user", t.uint8_t),
        0x0016: ("num_of_holiday_scheduleds_supported", t.uint8_t),
        0x0017: ("max_pin_len", t.uint8_t),
        0x0018: ("min_pin_len", t.uint8_t),
        0x0019: ("max_rfid_len", t.uint8_t),
        0x001A: ("min_rfid_len", t.uint8_t),
        0x0020: ("enable_logging", t.Bool),
        0x0021: ("language", t.LimitedCharString(3)),
        0x0022: ("led_settings", t.uint8_t),
        0x0023: ("auto_relock_time", t.uint32_t),
        0x0024: ("sound_volume", t.uint8_t),
        0x0025: ("operating_mode", t.enum8),
        0x0026: ("supported_operating_modes", t.bitmap16),
        0x0027: ("default_configuration_register", t.bitmap16),
        0x0028: ("enable_local_programming", t.Bool),
        0x0029: ("enable_one_touch_locking", t.Bool),
        0x002A: ("enable_inside_status_led", t.Bool),
        0x002B: ("enable_privacy_mode_button", t.Bool),
        0x0030: ("wrong_code_entry_limit", t.uint8_t),
        0x0031: ("user_code_temporary_disable_time", t.uint8_t),
        0x0032: ("send_pin_ota", t.Bool),
        0x0033: ("require_pin_for_rf_operation", t.Bool),
        0x0034: ("zigbee_security_level", t.enum8),
        0x0040: ("alarm_mask", t.bitmap16),
        0x0041: ("keypad_operation_event_mask", t.bitmap16),
        0x0042: ("rf_operation_event_mask", t.bitmap16),
        0x0043: ("manual_operation_event_mask", t.bitmap16),
        0x0044: ("rfid_operation_event_mask", t.bitmap16),
        0x0045: ("keypad_programming_event_mask", t.bitmap16),
        0x0046: ("rf_programming_event_mask", t.bitmap16),
        0x0047: ("rfid_programming_event_mask", t.bitmap16),
    }
    server_commands = {
        0x0000: ("lock_door", (t.Optional(t.CharacterString), ), False),
        0x0001: ("unlock_door", (t.Optional(t.CharacterString), ), False),
        0x0002: ("toggle_door", (t.Optional(t.CharacterString), ), False),
        0x0003: (
            "unlock_with_timeout",
            (t.uint16_t, t.Optional(t.CharacterString)),
            False,
        ),
        0x0004: ("get_log_record", (t.uint16_t, ), False),
        0x0005: (
            "set_pin_code",
            (t.uint16_t, t.uint8_t, t.enum8, t.CharacterString),
            False,
        ),
        0x0006: ("get_pin_code", (t.uint16_t, ), False),
        0x0007: ("clear_pin_code", (t.uint16_t, ), False),
        0x0008: ("clear_all_pin_codes", (), False),
        0x0009: ("set_user_status", (t.uint16_t, t.uint8_t), False),
        0x000A: ("get_user_status", (t.uint16_t, ), False),
        0x000B: (
            "set_week_day_schedule",
            (
                t.uint8_t,
                t.uint16_t,
                t.bitmap8,
                t.uint8_t,
                t.uint8_t,
                t.uint8_t,
                t.uint8_t,
            ),
            False,
        ),
        0x000C: ("get_week_day_schedule", (t.uint8_t, t.uint16_t), False),
        0x000D: ("clear_week_day_schedule", (t.uint8_t, t.uint16_t), False),
        0x000E: (
            "set_year_day_schedule",
            (t.uint8_t, t.uint16_t, t.uint32_t, t.uint32_t),
            False,
        ),
        0x000F: ("get_year_day_schedule", (t.uint8_t, t.uint16_t), False),
        0x0010: ("clear_year_day_schedule", (t.uint8_t, t.uint16_t), False),
        0x0011: (
            "set_holiday_schedule",
            (t.uint8_t, t.uint32_t, t.uint32_t, t.enum8),
            False,
        ),
        0x0012: ("get_holiday_schedule", (t.uint8_t, ), False),
        0x0013: ("clear_holiday_schedule", (t.uint8_t, ), False),
        0x0014: ("set_user_type", (t.uint16_t, t.enum8), False),
        0x0015: ("get_user_type", (t.uint16_t, ), False),
        0x0016: (
            "set_rfid_code",
            (t.uint16_t, t.uint8_t, t.enum8, t.CharacterString),
            False,
        ),
        0x0017: ("get_rfid_code", (t.uint16_t, ), False),
        0x0018: ("clear_rfid_code", (t.uint16_t, ), False),
        0x0019: ("clear_all_rfid_codes", (), False),
    }
    client_commands = {
        0x0000: ("lock_door_response", (foundation.Status, ), True),
        0x0001: ("unlock_door_response", (foundation.Status, ), True),
        0x0002: ("toggle_door_response", (foundation.Status, ), True),
        0x0003: ("unlock_with_timeout_response", (foundation.Status, ), True),
        0x0004: (
            "get_log_record_response",
            (
                t.uint16_t,
                t.uint32_t,
                t.enum8,
                t.uint8_t,
                t.uint8_t,
                t.uint16_t,
                t.Optional(t.CharacterString),
            ),
            True,
        ),
        0x0005: ("set_pin_code_response", (foundation.Status, ), True),
        0x0006: (
            "get_pin_code_response",
            (t.uint16_t, t.uint8_t, t.enum8, t.CharacterString),
            True,
        ),
        0x0007: ("clear_pin_code_response", (foundation.Status, ), True),
        0x0008: ("clear_all_pin_codes_response", (foundation.Status, ), True),
        0x0009: ("set_user_status_response", (foundation.Status, ), True),
        0x000A: ("get_user_status_response", (t.uint16_t, t.uint8_t), True),
        0x000B:
        ("set_week_day_schedule_response", (foundation.Status, ), True),
        0x000C: (
            "get_week_day_schedule_response",
            (
                t.uint8_t,
                t.uint16_t,
                foundation.Status,
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
            ),
            True,
        ),
        0x000D:
        ("clear_week_day_schedule_response", (foundation.Status, ), True),
        0x000E:
        ("set_year_day_schedule_response", (foundation.Status, ), True),
        0x000F: (
            "get_year_day_schedule_response",
            (
                t.uint8_t,
                t.uint16_t,
                foundation.Status,
                t.Optional(t.uint32_t),
                t.Optional(t.uint32_t),
            ),
            True,
        ),
        0x0010:
        ("clear_year_day_schedule_response", (foundation.Status, ), True),
        0x0011: ("set_holiday_schedule_response", (foundation.Status, ), True),
        0x0012: (
            "get_holiday_schedule_response",
            (
                t.uint8_t,
                foundation.Status,
                t.Optional(t.uint32_t),
                t.Optional(t.uint32_t),
                t.Optional(t.enum8),
            ),
            True,
        ),
        0x0013: ("clear_holiday_schedule_response", (foundation.Status, ),
                 True),
        0x0014: ("set_user_type_response", (foundation.Status, ), True),
        0x0015: ("get_user_type_response", (t.uint16_t, t.enum8), True),
        0x0016: ("set_rfid_code_response", (t.uint8_t, ), True),
        0x0017: (
            "get_rfid_code_response",
            (t.uint16_t, t.uint8_t, t.enum8, t.CharacterString),
            True,
        ),
        0x0018: ("clear_rfid_code_response", (foundation.Status, ), True),
        0x0019: ("clear_all_rfid_codes_response", (foundation.Status, ), True),
        0x0020: (
            "operation_event_notification",
            (
                t.uint8_t,
                t.uint8_t,
                t.uint16_t,
                t.uint8_t,
                t.uint32_t,
                t.CharacterString,
            ),
            False,
        ),
        0x0021: (
            "programming_event_notification",
            (
                t.uint8_t,
                t.uint8_t,
                t.uint16_t,
                t.uint8_t,
                t.uint8_t,
                t.uint8_t,
                t.uint32_t,
                t.CharacterString,
            ),
            False,
        ),
    }
Esempio n. 24
0
class LightLink(Cluster):
    cluster_id = 0x1000
    ep_attribute = "lightlink"
    attributes = {}
    server_commands = {
        0x0000: ("scan", (t.uint32_t, t.bitmap8, t.bitmap8), False),
        0x0002: ("device_information", (t.uint32_t, t.uint8_t), False),
        0x0006: ("identify", (t.uint32_t, t.uint16_t), False),
        0x0007: ("reset_to_factory_new", (t.uint32_t, ), False),
        0x0010: ("network_start", NET_START, False),
        0x0012: ("network_join_router", NET_JOIN, False),
        0x0014: ("network_join_end_device", NET_JOIN, False),
        0x0016: (
            "network_update",
            (t.uint32_t, t.EUI64, t.uint8_t, t.uint8_t, t.NWK, t.NWK),
            False,
        ),
        0x0041: ("get_group_identifiers", (t.uint8_t, ), False),
        0x0042: ("get_endpoint_list", (t.uint8_t, ), False),
    }
    client_commands = {
        0x0001: (
            "scan_rsp",
            (
                t.uint32_t,
                t.uint8_t,
                t.bitmap8,
                t.bitmap8,
                t.bitmap16,
                t.uint32_t,
                t.EUI64,
                t.uint8_t,
                t.uint8_t,
                t.NWK,
                t.NWK,
                t.uint8_t,
                t.uint8_t,
                t.Optional(t.uint8_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
            ),
            True,
        ),
        0x0003: (
            "device_information_rsp",
            (t.uint32_t, t.uint8_t, t.uint8_t, t.LVList(DeviceInfoRecord)),
            True,
        ),
        0x0011: (
            "network_start_rsp",
            (t.uint32_t, foundation.Status, t.EUI64, t.uint8_t, t.uint8_t,
             t.uint16_t),
            True,
        ),
        0x0013:
        ("network_join_router_rsp", (t.uint32_t, foundation.Status), True),
        0x0015:
        ("network_join_end_device_rsp", (t.uint32_t, foundation.Status), True),
        0x0040: (
            "endpoint_information",
            (t.EUI64, t.NWK, t.uint8_t, t.uint16_t, t.uint16_t, t.uint8_t),
            True,
        ),
        0x0041: (
            "get_group_identifiers_rsp",
            (t.uint8_t, t.uint8_t, t.LVList(GroupInfoRecord)),
            True,
        ),
        0x0042: (
            "get_endpoint_list_rsp",
            (t.uint8_t, t.uint8_t, t.LVList(EndpointInfoRecord)),
            True,
        ),
    }
Esempio n. 25
0
class DoorLock(Cluster):
    cluster_id = 0x0101
    name = 'Door Lock'
    ep_attribute = 'door_lock'
    attributes = {
        0x0000: ('lock_state', t.enum8),
        0x0001: ('lock_type', t.enum8),
        0x0002: ('actuator_enabled', t.Bool),
        0x0003: ('door_state', t.enum8),
        0x0004: ('door_open_events', t.uint32_t),
        0x0005: ('door_closed_events', t.uint32_t),
        0x0006: ('open_period', t.uint16_t),
        0x0010: ('num_of_lock_records_supported', t.uint16_t),
        0x0011: ('num_of_total_users_supported', t.uint16_t),
        0x0012: ('num_of_pin_users_supported', t.uint16_t),
        0x0013: ('num_of_rfid_users_supported', t.uint16_t),
        0x0014: ('num_of_week_day_schedules_supported_per_user', t.uint8_t),
        0x0015: ('num_of_year_day_schedules_supported_per_user', t.uint8_t),
        0x0016: ('num_of_holiday_scheduleds_supported', t.uint8_t),
        0x0017: ('max_pin_len', t.uint8_t),
        0x0018: ('min_pin_len', t.uint8_t),
        0x0019: ('max_rfid_len', t.uint8_t),
        0x001a: ('min_rfid_len', t.uint8_t),
        0x0020: ('enable_logging', t.Bool),
        0x0021: ('language', t.LimitedCharString(3)),
        0x0022: ('led_settings', t.uint8_t),
        0x0023: ('auto_relock_time', t.uint32_t),
        0x0024: ('sound_volume', t.uint8_t),
        0x0025: ('operating_mode', t.enum8),
        0x0026: ('supported_operating_modes', t.bitmap16),
        0x0027: ('default_configuration_register', t.bitmap16),
        0x0028: ('enable_local_programming', t.Bool),
        0x0029: ('enable_one_touch_locking', t.Bool),
        0x002a: ('enable_inside_status_led', t.Bool),
        0x002b: ('enable_privacy_mode_button', t.Bool),
        0x0030: ('wrong_code_entry_limit', t.uint8_t),
        0x0031: ('user_code_temporary_disable_time', t.uint8_t),
        0x0032: ('send_pin_ota', t.Bool),
        0x0033: ('require_pin_for_rf_operation', t.Bool),
        0x0034: ('zigbee_security_level', t.enum8),
        0x0040: ('alarm_mask', t.bitmap16),
        0x0041: ('keypad_operation_event_mask', t.bitmap16),
        0x0042: ('rf_operation_event_mask', t.bitmap16),
        0x0043: ('manual_operation_event_mask', t.bitmap16),
        0x0044: ('rfid_operation_event_mask', t.bitmap16),
        0x0045: ('keypad_programming_event_mask', t.bitmap16),
        0x0046: ('rf_programming_event_mask', t.bitmap16),
        0x0047: ('rfid_programming_event_mask', t.bitmap16),
    }
    server_commands = {
        0x0000: ('lock_door', (t.Optional(t.CharacterString), ), False),
        0x0001: ('unlock_door', (t.Optional(t.CharacterString), ), False),
        0x0002: ('toggle_door', (t.Optional(t.CharacterString), ), False),
        0x0003: ('unlock_with_timeout',
                 (t.uint16_t, t.Optional(t.CharacterString)), False),
        0x0004: ('get_log_record', (t.uint16_t, ), False),
        0x0005: ('set_pin_code', (t.uint16_t, t.uint8_t, t.enum8,
                                  t.CharacterString), False),
        0x0006: ('get_pin_code', (t.uint16_t, ), False),
        0x0007: ('clear_pin_code', (t.uint16_t, ), False),
        0x0008: ('clear_all_pin_codes', (), False),
        0x0009: ('set_user_status', (t.uint16_t, t.uint8_t), False),
        0x000a: ('get_user_status', (t.uint16_t, ), False),
        0x000b:
        ('set_week_day_schedule', (t.uint8_t, t.uint16_t, t.bitmap8, t.uint8_t,
                                   t.uint8_t, t.uint8_t, t.uint8_t), False),
        0x000c: ('get_week_day_schedule', (t.uint8_t, t.uint16_t), False),
        0x000d: ('clear_week_day_schedule', (t.uint8_t, t.uint16_t), False),
        0x000e: ('set_year_day_schedule', (t.uint8_t, t.uint16_t, t.uint32_t,
                                           t.uint32_t), False),
        0x000f: ('get_year_day_schedule', (t.uint8_t, t.uint16_t), False),
        0x0010: ('clear_year_day_schedule', (t.uint8_t, t.uint16_t), False),
        0x0011: ('set_holiday_schedule', (t.uint8_t, t.uint32_t, t.uint32_t,
                                          t.enum8), False),
        0x0012: ('get_holiday_schedule', (t.uint8_t, ), False),
        0x0013: ('clear_holiday_schedule', (t.uint8_t, ), False),
        0x0014: ('set_user_type', (t.uint16_t, t.enum8), False),
        0x0015: ('get_user_type', (t.uint16_t, ), False),
        0x0016: ('set_rfid_code', (t.uint16_t, t.uint8_t, t.enum8,
                                   t.CharacterString), False),
        0x0017: ('get_rfid_code', (t.uint16_t, ), False),
        0x0018: ('clear_rfid_code', (t.uint16_t, ), False),
        0x0019: ('clear_all_rfid_codes', (), False),
    }
    client_commands = {
        0x0000: ('lock_door_response', (foundation.Status, ), True),
        0x0001: ('unlock_door_response', (foundation.Status, ), True),
        0x0002: ('toggle_door_response', (foundation.Status, ), True),
        0x0003: ('unlock_with_timeout_response', (foundation.Status, ), True),
        0x0004: ('get_log_record_response',
                 (t.uint16_t, t.uint32_t, t.enum8, t.uint8_t, t.uint8_t,
                  t.uint16_t, t.Optional(t.CharacterString)), True),
        0x0005: ('set_pin_code_response', (foundation.Status, ), True),
        0x0006: ('get_pin_code_response', (t.uint16_t, t.uint8_t, t.enum8,
                                           t.CharacterString), True),
        0x0007: ('clear_pin_code_response', (foundation.Status, ), True),
        0x0008: ('clear_all_pin_codes_response', (foundation.Status, ), True),
        0x0009: ('set_user_status_response', (foundation.Status, ), True),
        0x000a: ('get_user_status_response', (t.uint16_t, t.uint8_t), True),
        0x000b:
        ('set_week_day_schedule_response', (foundation.Status, ), True),
        0x000c: ('get_week_day_schedule_response',
                 (t.uint8_t, t.uint16_t, foundation.Status,
                  t.Optional(t.uint8_t), t.Optional(t.uint8_t),
                  t.Optional(t.uint8_t), t.Optional(t.uint8_t)), True),
        0x000d:
        ('clear_week_day_schedule_response', (foundation.Status, ), True),
        0x000e:
        ('set_year_day_schedule_response', (foundation.Status, ), True),
        0x000f: ('get_year_day_schedule_response',
                 (t.uint8_t, t.uint16_t, foundation.Status,
                  t.Optional(t.uint32_t), t.Optional(t.uint32_t)), True),
        0x0010:
        ('clear_year_day_schedule_response', (foundation.Status, ), True),
        0x0011: ('set_holiday_schedule_response', (foundation.Status, ), True),
        0x0012: ('get_holiday_schedule_response',
                 (t.uint8_t, foundation.Status, t.Optional(t.uint32_t),
                  t.Optional(t.uint32_t), t.Optional(t.enum8)), True),
        0x0013: ('clear_holiday_schedule_response', (foundation.Status, ),
                 True),
        0x0014: ('set_user_type_response', (foundation.Status, ), True),
        0x0015: ('get_user_type_response', (t.uint16_t, t.enum8), True),
        0x0016: ('set_rfid_code_response', (t.uint8_t, ), True),
        0x0017: ('get_rfid_code_response', (t.uint16_t, t.uint8_t, t.enum8,
                                            t.CharacterString), True),
        0x0018: ('clear_rfid_code_response', (foundation.Status, ), True),
        0x0019: ('clear_all_rfid_codes_response', (foundation.Status, ), True),
        0x0020: ('operation_event_notification',
                 (t.uint8_t, t.uint8_t, t.uint16_t, t.uint8_t, t.uint32_t,
                  t.CharacterString), False),
        0x0021: ('programming_event_notification',
                 (t.uint8_t, t.uint8_t, t.uint16_t, t.uint8_t, t.uint8_t,
                  t.uint8_t, t.uint32_t, t.CharacterString), False),
    }