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()
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()
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), }
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'
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"
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
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, ) }
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, )
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), }
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()
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"", )
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), }
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))
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, ), }
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)
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), }
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
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)),
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), }
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))),
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, ), }
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, ), }
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, ), }
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), }