def network_info(node_info): return app_state.NetworkInfo( extended_pan_id=t.ExtendedPanId.convert("0D:49:91:99:AE:CD:3C:35"), pan_id=t.PanId(0x9BB0), nwk_update_id=0x12, nwk_manager_id=t.NWK(0x0000), channel=t.uint8_t(15), channel_mask=t.Channels.from_channel_list([15, 20, 25]), security_level=t.uint8_t(5), network_key=app_state.Key( key=t.KeyData.convert( "9A:79:D6:9A:DA:EC:45:C6:F2:EF:EB:AF:DA:A3:07:B6"), seq=108, tx_counter=39009277, ), tc_link_key=app_state.Key( key=t.KeyData(b"ZigBeeAlliance09"), partner_ieee=node_info.ieee, tx_counter=8712428, ), key_table=[], children=[], nwk_addresses={}, stack_specific={}, source=f"zigpy-deconz@{zigpy_deconz.__version__}", metadata={"deconz": { "version": 0, }}, )
class NetworkInformation: """Network information.""" extended_pan_id: t.ExtendedPanId | None = None pan_id: t.PanId | None = 0xFFFE nwk_update_id: t.uint8_t | None = 0x00 nwk_manager_id: t.NWK | None = t.NWK(0xFFFE) channel: t.uint8_t | None = None channel_mask: t.Channels | None = None security_level: t.uint8_t | None = None network_key: Key | None = None tc_link_key: Key | None = None key_table: list[Key] | None = None children: list[NodeInfo] | None = None # If exposed by the stack, NWK addresses of other connected devices on the network nwk_addresses: dict[t.EUI64, t.NWK] | None = None # Dict to keep track of stack-specific network stuff. # Z-Stack, for example, has a TCLK_SEED that should be backed up. stack_specific: dict[int | str, Any] | None = None def __post_init__(self) -> None: """Initialize instance.""" if self.extended_pan_id is None: self.extended_pan_id = t.EUI64.convert("ff:ff:ff:ff:ff:ff:ff:ff") if self.key_table is None: self.key_table = [] if self.stack_specific is None: self.stack_specific = {} if self.children is None: self.children = [] if self.nwk_addresses is None: self.nwk_addresses = {}
class NodeInfo: """Controller Application network Node information.""" nwk: t.NWK = t.NWK(0xFFFE) ieee: t.EUI64 | None = None logical_type: zdo_t.LogicalType | None = None def __post_init__(self) -> None: """Initialize instance.""" if self.ieee is None: self.ieee = t.EUI64.convert("ff:ff:ff:ff:ff:ff:ff:ff") if self.logical_type is None: self.logical_type = zdo_t.LogicalType.Coordinator
def test_addressing_nwk(): """Test addressing mode nwk.""" data = b"\x02\x07\x08\x2A" extra = b"extra data" r, rest = t.Addressing.deserialize(data + extra) assert rest == extra assert r.addr_mode == t.AddrMode.NWK assert r.addr == t.NWK(0x0807) assert r.serialize() == data dst = t.Addressing.nwk(0x0807, 42) assert dst.serialize() == data
def app_mock(): """ConntrollerApplication Mock.""" config = App.SCHEMA({ CONF_DATABASE: None, CONF_DEVICE: { CONF_DEVICE_PATH: "/dev/null" } }) app_mock = MagicMock(spec_set=App(config)) app_mock.state.node_information = app_state.NodeInfo( t.NWK(0x0000), ieee=NCP_IEEE, logical_type=zdo_t.LogicalType.Coordinator) return app_mock
def test_ember_network_params_to_network_info(): """Coverage for Ember Network param to zigpy network information converter.""" network_params = t.EmberNetworkParameters( t.ExtendedPanId.convert("ff:7b:aa:bb:cc:dd:ee:ff"), panId=0xD539, radioTxPower=8, radioChannel=20, joinMethod=t.EmberJoinMethod.USE_MAC_ASSOCIATION, nwkManagerId=0x1234, nwkUpdateId=22, channels=t.Channels.ALL_CHANNELS, ) network_info = network_params.zigpy_network_information assert network_info.extended_pan_id == t.ExtendedPanId.convert( "ff:7b:aa:bb:cc:dd:ee:ff") assert network_info.pan_id == zt.PanId(0xD539) assert network_info.nwk_update_id == 22 assert network_info.nwk_manager_id == zt.NWK(0x1234) assert network_info.channel == 20
def app(): class App(zigpy.application.ControllerApplication): async def shutdown(self): pass async def startup(self, auto_form=False): self._ieee = t.EUI64.convert("aa:de:de:be:ef:11:22:11") self._nwk = t.NWK(0x0000) async def request( self, device, profile, cluster, src_ep, dst_ep, sequence, data, expect_reply=True, use_ieee=False, ): pass async def permit_ncp(self, time_s=60): pass async def probe(self, config): return True config = App.SCHEMA({ CONF_DATABASE: None, CONF_DEVICE: { CONF_DEVICE_PATH: "/dev/null" } }) app = App(config) app.state.node_information = app_state.NodeInfo( t.NWK(0x0000), ieee=NCP_IEEE, logical_type=zdo_t.LogicalType.Coordinator) return app
async def test_database(tmpdir): db = os.path.join(str(tmpdir), "test.db") app = await make_app(db) ieee = make_ieee() relays_1 = [t.NWK(0x1234), t.NWK(0x2345)] relays_2 = [t.NWK(0x3456), t.NWK(0x4567)] app.handle_join(99, ieee, 0) app.handle_join(99, ieee, 0) dev = app.get_device(ieee) ep = dev.add_endpoint(1) ep.status = zigpy.endpoint.Status.ZDO_INIT ep.profile_id = 260 ep.device_type = profiles.zha.DeviceType.PUMP ep = dev.add_endpoint(2) ep.status = zigpy.endpoint.Status.ZDO_INIT ep.profile_id = 260 ep.device_type = 0xFFFD # Invalid clus = ep.add_input_cluster(0) ep.add_output_cluster(1) ep = dev.add_endpoint(3) ep.status = zigpy.endpoint.Status.ZDO_INIT ep.profile_id = 49246 ep.device_type = profiles.zll.DeviceType.COLOR_LIGHT app.device_initialized(dev) clus._update_attribute(0, 99) clus._update_attribute(4, bytes("Custom", "ascii")) clus._update_attribute(5, bytes("Model", "ascii")) clus.listener_event("cluster_command", 0) clus.listener_event("general_command") dev.relays = relays_1 signature = dev.get_signature() assert ep.endpoint_id in signature[SIG_ENDPOINTS] assert SIG_MANUFACTURER not in signature assert SIG_MODEL not in signature dev.manufacturer = "Custom" dev.model = "Model" assert dev.get_signature()[SIG_MANUFACTURER] == "Custom" assert dev.get_signature()[SIG_MODEL] == "Model" # Test a CustomDevice custom_ieee = make_ieee(1) app.handle_join(199, custom_ieee, 0) dev = app.get_device(custom_ieee) app.device_initialized(dev) ep = dev.add_endpoint(1) ep.status = zigpy.endpoint.Status.ZDO_INIT ep.device_type = profiles.zll.DeviceType.COLOR_LIGHT ep.profile_id = 65535 with patch("zigpy.quirks.get_device", fake_get_device): app.device_initialized(dev) assert isinstance(app.get_device(custom_ieee), FakeCustomDevice) assert isinstance(app.get_device(custom_ieee), CustomDevice) dev = app.get_device(custom_ieee) app.device_initialized(dev) dev.relays = relays_2 dev.endpoints[1].level._update_attribute(0x0011, 17) dev.endpoints[99].level._update_attribute(0x0011, 17) assert dev.endpoints[1].in_clusters[0x0008]._attr_cache[0x0011] == 17 assert dev.endpoints[99].in_clusters[0x0008]._attr_cache[0x0011] == 17 await app.pre_shutdown() # Everything should've been saved - check that it re-loads with patch("zigpy.quirks.get_device", fake_get_device): app2 = await make_app(db) dev = app2.get_device(ieee) assert dev.endpoints[1].device_type == profiles.zha.DeviceType.PUMP assert dev.endpoints[2].device_type == 0xFFFD assert dev.endpoints[2].in_clusters[0]._attr_cache[0] == 99 assert dev.endpoints[2].in_clusters[0]._attr_cache[4] == bytes("Custom", "ascii") assert dev.endpoints[2].in_clusters[0]._attr_cache[5] == bytes("Model", "ascii") assert dev.endpoints[2].manufacturer == "Custom" assert dev.endpoints[2].model == "Model" assert dev.endpoints[2].out_clusters[1].cluster_id == 1 assert dev.endpoints[3].device_type == profiles.zll.DeviceType.COLOR_LIGHT assert dev.relays == relays_1 dev = app2.get_device(custom_ieee) # This virtual attribute is added by the quirk, there is no corresponding cluster # stored in the database, nor is there a corresponding endpoint 99 assert dev.endpoints[1].in_clusters[0x0008]._attr_cache[0x0011] == 17 assert dev.endpoints[99].in_clusters[0x0008]._attr_cache[0x0011] == 17 assert dev.relays == relays_2 dev.relays = None app.handle_leave(99, ieee) await app2.pre_shutdown() app3 = await make_app(db) assert ieee in app3.devices async def mockleave(*args, **kwargs): return [0] app3.devices[ieee].zdo.leave = mockleave await app3.remove(ieee) for i in range(1, 20): await asyncio.sleep(0) assert ieee not in app3.devices await app3.pre_shutdown() app4 = await make_app(db) assert ieee not in app4.devices dev = app4.get_device(custom_ieee) assert dev.relays is None await app4.pre_shutdown() os.unlink(db)
def nwk(): """NWK fixture.""" return t.NWK(0xBEEF)
async def test_database(tmpdir, monkeypatch): monkeypatch.setattr(Device, "_initialize", _initialize) db = os.path.join(str(tmpdir), "test.db") app = make_app(db) # TODO: Leaks a task on dev.initialize, I think? ieee = make_ieee() relays_1 = [t.NWK(0x1234), t.NWK(0x2345)] relays_2 = [t.NWK(0x3456), t.NWK(0x4567)] app.handle_join(99, ieee, 0) app.handle_join(99, ieee, 0) dev = app.get_device(ieee) dev.node_desc, _ = zdo_t.NodeDescriptor.deserialize(b"1234567890123") ep = dev.add_endpoint(1) ep.profile_id = 260 ep.device_type = profiles.zha.DeviceType.PUMP ep = dev.add_endpoint(2) ep.profile_id = 260 ep.device_type = 0xFFFD # Invalid clus = ep.add_input_cluster(0) ep.add_output_cluster(1) ep = dev.add_endpoint(3) ep.profile_id = 49246 ep.device_type = profiles.zll.DeviceType.COLOR_LIGHT app.device_initialized(dev) clus._update_attribute(0, 99) clus._update_attribute(4, bytes("Custom", "ascii")) clus._update_attribute(5, bytes("Model", "ascii")) clus.listener_event("cluster_command", 0) clus.listener_event("general_command") dev.relays = relays_1 # Test a CustomDevice custom_ieee = make_ieee(1) app.handle_join(199, custom_ieee, 0) dev = app.get_device(custom_ieee) app.device_initialized(dev) ep = dev.add_endpoint(1) ep.profile_id = 65535 with mock.patch("zigpy.quirks.get_device", fake_get_device): app.device_initialized(dev) assert isinstance(app.get_device(custom_ieee), FakeCustomDevice) assert isinstance(app.get_device(custom_ieee), CustomDevice) assert ep.endpoint_id in dev.get_signature() app.device_initialized(app.get_device(custom_ieee)) dev.relays = relays_2 # Everything should've been saved - check that it re-loads with mock.patch("zigpy.quirks.get_device", fake_get_device): app2 = make_app(db) dev = app2.get_device(ieee) assert dev.endpoints[1].device_type == profiles.zha.DeviceType.PUMP assert dev.endpoints[2].device_type == 0xFFFD assert dev.endpoints[2].in_clusters[0]._attr_cache[0] == 99 assert dev.endpoints[2].in_clusters[0]._attr_cache[4] == bytes("Custom", "ascii") assert dev.endpoints[2].in_clusters[0]._attr_cache[5] == bytes("Model", "ascii") assert dev.endpoints[2].manufacturer == "Custom" assert dev.endpoints[2].model == "Model" assert dev.endpoints[2].out_clusters[1].cluster_id == 1 assert dev.endpoints[3].device_type == profiles.zll.DeviceType.COLOR_LIGHT assert dev.relays == relays_1 dev = app2.get_device(custom_ieee) assert dev.relays == relays_2 dev.relays = None app.handle_leave(99, ieee) app2 = make_app(db) assert ieee in app2.devices async def mockleave(*args, **kwargs): return [0] app2.devices[ieee].zdo.leave = mockleave await app2.remove(ieee) assert ieee not in app2.devices app3 = make_app(db) assert ieee not in app3.devices dev = app2.get_device(custom_ieee) assert dev.relays is None os.unlink(db)
def node_info(): return app_state.NodeInfo( nwk=t.NWK(0x0000), ieee=t.EUI64.convert("93:2C:A9:34:D9:D0:5D:12"), logical_type=zdo_t.LogicalType.Coordinator, )
async def startup(self, auto_form=False): self._ieee = t.EUI64.convert("aa:de:de:be:ef:11:22:11") self._nwk = t.NWK(0x0000)