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', (t.uint8_t, t.int16s, t.uint16_t, t.uint16_t, t.uint8_t, t.uint16_t), True), 0x0001: ('location_data_response', (t.uint8_t, t.uint8_t, t.int16s, t.int16s, t.int16s, t.uint16_t, t.uint8_t, t.uint8_t, 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), }
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.uint16_t), False), }
class Routes(t.Struct): _fields = [ ("Entries", t.uint8_t), ("StartIndex", t.uint8_t), ("RoutingTableList", t.LVList(Route)), ]
0x2b: ('Signed Integer', t.int32s, Analog), 0x2c: ('Signed Integer', t.int40s, Analog), 0x2d: ('Signed Integer', t.int48s, Analog), 0x2e: ('Signed Integer', t.int56s, Analog), 0x2f: ('Signed Integer', t.int64s, Analog), 0x30: ('Enumeration', t.enum8, Discrete), 0x31: ('Enumeration', t.enum16, Discrete), # 0x38: ('Floating point', t.Half, Analog), 0x39: ('Floating point', t.Single, Analog), 0x3a: ('Floating point', t.Double, Analog), 0x41: ('Octet string', t.LVBytes, Discrete), 0x42: ('Character string', t.CharacterString, Discrete), 0x43: ('Long octet string', t.LongOctetString, Discrete), 0x44: ('Long character string', t.LongCharacterString, Discrete), 0x48: ('Array', TypedCollection, Discrete), 0x4c: ('Structure', t.LVList(TypeValue, 2), Discrete), 0x50: ('Set', TypedCollection, Discrete), 0x51: ('Bag', TypedCollection, Discrete), 0xe0: ('Time of day', t.uint32_t, Analog), 0xe1: ('Date', t.uint32_t, Analog), 0xe2: ('UTCTime', t.uint32_t, Analog), 0xe8: ('Cluster ID', t.uint16_t, Discrete), 0xe9: ('Attribute ID', t.uint16_t, Discrete), 0xea: ('BACNet OID', t.uint32_t, Discrete), 0xf0: ('IEEE address', t.EUI64, Discrete), 0xf1: ('128-bit security key', t.fixed_list(16, t.uint16_t), Discrete), 0xff: ('Unknown', None, None), } DATA_TYPE_IDX = { t: tidx
0x2B: ("Signed Integer", t.int32s, Analog), 0x2C: ("Signed Integer", t.int40s, Analog), 0x2D: ("Signed Integer", t.int48s, Analog), 0x2E: ("Signed Integer", t.int56s, Analog), 0x2F: ("Signed Integer", t.int64s, Analog), 0x30: ("Enumeration", t.enum8, Discrete), 0x31: ("Enumeration", t.enum16, Discrete), # 0x38: ('Floating point', t.Half, Analog), 0x39: ("Floating point", t.Single, Analog), 0x3A: ("Floating point", t.Double, Analog), 0x41: ("Octet string", t.LVBytes, Discrete), 0x42: ("Character string", t.CharacterString, Discrete), 0x43: ("Long octet string", t.LongOctetString, Discrete), 0x44: ("Long character string", t.LongCharacterString, Discrete), 0x48: ("Array", TypedCollection, Discrete), 0x4C: ("Structure", t.LVList(TypeValue, 2), Discrete), 0x50: ("Set", TypedCollection, Discrete), 0x51: ("Bag", TypedCollection, Discrete), 0xE0: ("Time of day", t.uint32_t, Analog), 0xE1: ("Date", t.uint32_t, Analog), 0xE2: ("UTCTime", t.uint32_t, Analog), 0xE8: ("Cluster ID", t.uint16_t, Discrete), 0xE9: ("Attribute ID", t.uint16_t, Discrete), 0xEA: ("BACNet OID", t.uint32_t, Discrete), 0xF0: ("IEEE address", t.EUI64, Discrete), 0xF1: ("128-bit security key", t.fixed_list(16, t.uint16_t), Discrete), 0xFF: ("Unknown", None, None), } DATA_TYPE_IDX = { t: tidx
Mgmt_Permit_Joining_rsp = 0x8036 # ... TODO optional stuff ... CLUSTERS = { # Device and Service Discovery Server Requests ZDOCmd.NWK_addr_req: (IEEE, ("RequestType", t.uint8_t), ("StartIndex", t.uint8_t)), ZDOCmd.IEEE_addr_req: (NWKI, ("RequestType", t.uint8_t), ("StartIndex", t.uint8_t)), ZDOCmd.Node_Desc_req: (NWKI,), ZDOCmd.Power_Desc_req: (NWKI,), ZDOCmd.Simple_Desc_req: (NWKI, ("EndPoint", t.uint8_t)), ZDOCmd.Active_EP_req: (NWKI,), ZDOCmd.Match_Desc_req: ( NWKI, ("ProfileID", t.uint16_t), ("InClusterList", t.LVList(t.uint16_t)), ("OutClusterList", t.LVList(t.uint16_t)), ), # ZDO.Complex_Desc_req: (NWKI, ), ZDOCmd.User_Desc_req: (NWKI,), ZDOCmd.Discovery_Cache_req: (NWK, IEEE), ZDOCmd.Device_annce: (NWK, IEEE, ("Capability", t.uint8_t)), ZDOCmd.User_Desc_set: ( NWKI, ("UserDescriptor", t.fixed_list(16, t.uint8_t)), ), # Really a string ZDOCmd.System_Server_Discovery_req: (("ServerMask", t.uint16_t),), ZDOCmd.Discovery_store_req: ( NWK, IEEE, ("NodeDescSize", t.uint8_t),
NWK = ('NWKAddr', t.uint16_t) NWKI = ('NWKAddrOfInterest', t.uint16_t) IEEE = ('IEEEAddr', t.EUI64) STATUS = ('Status', Status) CLUSTERS = { # Device and Service Discovery Server Requests 0x0000: ('NWK_addr_req', (IEEE, ('RequestType', t.uint8_t), ('StartIndex', t.uint8_t))), 0x0001: ('IEEE_addr_req', (NWKI, ('RequestType', t.uint8_t), ('StartIndex', t.uint8_t))), 0x0002: ('Node_Desc_req', (NWKI, )), 0x0003: ('Power_Desc_req', (NWKI, )), 0x0004: ('Simple_Desc_req', (NWKI, ('EndPoint', t.uint8_t))), 0x0005: ('Active_EP_req', (NWKI, )), 0x0006: ('Match_Desc_req', (NWKI, ('ProfileID', t.uint16_t), ('InClusterList', t.LVList(t.uint16_t)), ('OutClusterList', t.LVList(t.uint16_t)))), # 0x0010: ('Complex_Desc_req', (NWKI, )), 0x0011: ('User_Desc_req', (NWKI, )), 0x0012: ('Discovery_Cache_req', (NWK, IEEE)), 0x0013: ('Device_annce', (NWK, IEEE, ('Capability', t.uint8_t))), 0x0014: ('User_Desc_set', (NWKI, ('UserDescriptor', t.fixed_list(16, t.uint8_t)))), # Really a string 0x0015: ('System_Server_Discovery_req', (('ServerMask', t.uint16_t), )), 0x0016: ('Discovery_store_req', (NWK, IEEE, ('NodeDescSize', t.uint8_t), ('PowerDescSize', t.uint8_t), ('ActiveEPSize', t.uint8_t), ('SimpleDescSizeList', t.LVList(t.uint8_t)))), 0x0017: ('Node_Desc_store_req', (NWK, IEEE, ('NodeDescriptor', NodeDescriptor))), 0x0019: ('Active_EP_store_req', (NWK, IEEE, ('ActiveEPList', t.LVList(t.uint8_t)))), 0x001a: ('Simple_Desc_store_req', (NWK, IEEE, ('SimpleDescriptor', SizePrefixedSimpleDescriptor))), 0x001b: ('Remove_node_cache_req', (NWK, IEEE)), 0x001c: ('Find_node_cache_req', (NWK, IEEE)), 0x001d: ('Extended_Simple_Desc_req', (NWKI, ('EndPoint', t.uint8_t), ('StartIndex', t.uint8_t))), 0x001e: ('Extended_Active_EP_req', (NWKI, ('StartIndex', t.uint8_t))), # Bind Management Server Services Responses
NWKI = ('NWKAddrOfInterest', t.uint16_t) IEEE = ('IEEEAddr', t.EUI64) STATUS = ('Status', t.uint8_t) CLUSTERS = { # Device and Service Discovery Server Requests 0x0000: ('NWK_addr_req', (IEEE, ('RequestType', t.uint8_t), ('StartIndex', t.uint8_t))), 0x0001: ('IEEE_addr_req', (NWKI, ('RequestType', t.uint8_t), ('StartIndex', t.uint8_t))), 0x0002: ('Node_Desc_req', (NWKI, )), 0x0003: ('Power_Desc_req', (NWKI, )), 0x0004: ('Simple_Desc_req', (NWKI, ('EndPoint', t.uint8_t))), 0x0005: ('Active_EP_req', (NWKI, )), 0x0006: ('Match_Desc_req', (NWKI, ('ProfileID', t.uint16_t), ('InClusterList', t.LVList(t.uint16_t)), ('OutClusterList', t.LVList(t.uint16_t)))), # 0x0010: ('Complex_Desc_req', (NWKI, )), 0x0011: ('User_Desc_req', (NWKI, )), 0x0012: ('Discovery_Cache_req', (NWK, IEEE)), 0x0013: ('Device_annce', (NWK, IEEE, ('Capability', t.uint8_t))), 0x0014: ('User_Desc_set', (NWKI, ('UserDescriptor', t.fixed_list(16, t.uint8_t)))), # Really a string 0x0015: ('System_Server_Discovery_req', (('ServerMask', t.uint16_t), )), 0x0016: ('Discovery_store_req', (NWK, IEEE, ('NodeDescSize', t.uint8_t), ('PowerDescSize', t.uint8_t), ('ActiveEPSize', t.uint8_t), ('SimpleDescSizeList', t.LVList(t.uint8_t)))), 0x0017:
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), }
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, ), }
def test_lvlist_too_short(): with pytest.raises(ValueError): t.LVList(t.uint8_t).deserialize(b'') with pytest.raises(ValueError): t.LVList(t.uint8_t).deserialize(b'\x04123')
class Neighbors(t.Struct): """Mgmt_Lqi_rsp""" _fields = [('Entries', t.uint8_t), ('StartIndex', t.uint8_t), ('NeighborTableList', t.LVList(Neighbor))]
Mgmt_Permit_Joining_rsp = 0x8036 # ... TODO optional stuff ... CLUSTERS = { # Device and Service Discovery Server Requests ZDOCmd.NWK_addr_req: (IEEE, ('RequestType', t.uint8_t), ('StartIndex', t.uint8_t)), ZDOCmd.IEEE_addr_req: (NWKI, ('RequestType', t.uint8_t), ('StartIndex', t.uint8_t)), ZDOCmd.Node_Desc_req: (NWKI, ), ZDOCmd.Power_Desc_req: (NWKI, ), ZDOCmd.Simple_Desc_req: (NWKI, ('EndPoint', t.uint8_t)), ZDOCmd.Active_EP_req: (NWKI, ), ZDOCmd.Match_Desc_req: (NWKI, ('ProfileID', t.uint16_t), ('InClusterList', t.LVList(t.uint16_t)), ('OutClusterList', t.LVList(t.uint16_t))), # ZDO.Complex_Desc_req: (NWKI, ), ZDOCmd.User_Desc_req: (NWKI, ), ZDOCmd.Discovery_Cache_req: (NWK, IEEE), ZDOCmd.Device_annce: (NWK, IEEE, ('Capability', t.uint8_t)), ZDOCmd.User_Desc_set: (NWKI, ('UserDescriptor', t.fixed_list(16, t.uint8_t))), # Really a string ZDOCmd.System_Server_Discovery_req: (('ServerMask', t.uint16_t), ), ZDOCmd.Discovery_store_req: (NWK, IEEE, ('NodeDescSize', t.uint8_t), ('PowerDescSize', t.uint8_t), ('ActiveEPSize', t.uint8_t), ('SimpleDescSizeList', t.LVList(t.uint8_t))), ZDOCmd.Node_Desc_store_req: (NWK, IEEE, ('NodeDescriptor', NodeDescriptor)), ZDOCmd.Active_EP_store_req: (NWK, IEEE, ('ActiveEPList', t.LVList(t.uint8_t))),
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 Routes(t.Struct): _fields = [ ('Entries', t.uint8_t), ('StartIndex', t.uint8_t), ('RoutingTableList', t.LVList(Route)) ]
def test_lvlist(): d, r = t.LVList(t.uint8_t).deserialize(b'\x0412345') assert r == b'5' assert d == list(map(ord, '1234')) assert t.LVList(t.uint8_t).serialize(d) == b'\x041234'
def test_lvlist(): d, r = t.LVList(t.uint8_t).deserialize(b"\x0412345") assert r == b"5" assert d == list(map(ord, "1234")) assert t.LVList(t.uint8_t).serialize(d) == b"\x041234"