diff --git a/.gitignore b/.gitignore index ddd8f0e..edb452b 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,5 @@ ENV/ # Visual Studio Code .vscode + +.DS_Store diff --git a/setup.py b/setup.py index 650908c..f35e125 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,6 @@ author_email="schmidt.d@aon.at", license="GPL-3.0", packages=find_packages(exclude=["tests"]), - install_requires=["pyserial-asyncio", "zigpy>=0.37.0"], + install_requires=["pyserial-asyncio", "zigpy>=0.40.0"], tests_require=["pytest", "pytest-asyncio", "asynctest"], ) diff --git a/tests/test_application.py b/tests/test_application.py index db3bd3c..1b36dd6 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -7,7 +7,7 @@ import zigpy.config import zigpy.device import zigpy.neighbor -from zigpy.types import EUI64 +from zigpy.types import EUI64, Channels import zigpy.zdo.types as zdo_t from zigpy_deconz import types as t @@ -253,10 +253,34 @@ async def _version(): app._api._proto_ver = protocol_ver return [version] + params = { + deconz_api.NetworkParameter.aps_designed_coordinator: [designed_coord], + deconz_api.NetworkParameter.nwk_address: [designed_coord], + deconz_api.NetworkParameter.protocol_version: [protocol_ver], + deconz_api.NetworkParameter.mac_address: [EUI64([0x01] * 8)], + deconz_api.NetworkParameter.nwk_address: [0x0000], + deconz_api.NetworkParameter.nwk_panid: [0x1234], + deconz_api.NetworkParameter.nwk_extended_panid: [EUI64([0x02] * 8)], + deconz_api.NetworkParameter.channel_mask: [Channels.CHANNEL_25], + deconz_api.NetworkParameter.aps_extended_panid: [EUI64([0x02] * 8)], + deconz_api.NetworkParameter.network_key: [0, t.Key([0x03] * 16)], + deconz_api.NetworkParameter.trust_center_address: [EUI64([0x04] * 8)], + deconz_api.NetworkParameter.link_key: [ + EUI64([0x04] * 8), + t.Key(b"ZigBeeAlliance09"), + ], + deconz_api.NetworkParameter.security_mode: [3], + deconz_api.NetworkParameter.current_channel: [25], + deconz_api.NetworkParameter.nwk_update_id: [0], + } + async def _read_param(param, *args): - if param == deconz_api.NetworkParameter.mac_address: - return (t.EUI64([0x01] * 8),) - return (designed_coord,) + try: + return params[param] + except KeyError: + raise zigpy_deconz.exception.CommandError( + deconz_api.Status.UNSUPPORTED, "Unsupported" + ) app._reset_watchdog = AsyncMock() app.form_network = AsyncMock() diff --git a/zigpy_deconz/__init__.py b/zigpy_deconz/__init__.py index ca97709..057bce1 100644 --- a/zigpy_deconz/__init__.py +++ b/zigpy_deconz/__init__.py @@ -2,7 +2,7 @@ # coding: utf-8 MAJOR_VERSION = 0 -MINOR_VERSION = 13 +MINOR_VERSION = 14 PATCH_VERSION = "0" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" diff --git a/zigpy_deconz/api.py b/zigpy_deconz/api.py index 71c846a..756f4bf 100644 --- a/zigpy_deconz/api.py +++ b/zigpy_deconz/api.py @@ -10,7 +10,7 @@ import serial from zigpy.config import CONF_DEVICE_PATH import zigpy.exceptions -from zigpy.types import APSStatus, Channels +from zigpy.types import APSStatus, Bool, Channels from zigpy_deconz.exception import APIException, CommandError import zigpy_deconz.types as t @@ -179,12 +179,16 @@ class NetworkParameter(t.uint8_t, enum.Enum): aps_extended_panid = 0x0B trust_center_address = 0x0E security_mode = 0x10 + use_predefined_nwk_panid = 0x15 network_key = 0x18 + link_key = 0x19 current_channel = 0x1C permit_join = 0x21 protocol_version = 0x22 nwk_update_id = 0x24 watchdog_ttl = 0x26 + nwk_frame_counter = 0x27 + app_zdp_response_handling = 0x28 NETWORK_PARAMETER_SCHEMA = { @@ -197,12 +201,16 @@ class NetworkParameter(t.uint8_t, enum.Enum): NetworkParameter.aps_extended_panid: (t.ExtendedPanId,), NetworkParameter.trust_center_address: (t.EUI64,), NetworkParameter.security_mode: (t.uint8_t,), + NetworkParameter.use_predefined_nwk_panid: (Bool,), NetworkParameter.network_key: (t.uint8_t, t.Key), + NetworkParameter.link_key: (t.EUI64, t.Key), NetworkParameter.current_channel: (t.uint8_t,), NetworkParameter.permit_join: (t.uint8_t,), NetworkParameter.protocol_version: (t.uint16_t,), NetworkParameter.nwk_update_id: (t.uint8_t,), NetworkParameter.watchdog_ttl: (t.uint32_t,), + NetworkParameter.nwk_frame_counter: (t.uint32_t,), + NetworkParameter.app_zdp_response_handling: (t.uint16_t,), } diff --git a/zigpy_deconz/zigbee/application.py b/zigpy_deconz/zigbee/application.py index 2ab0e49..2502f50 100644 --- a/zigpy_deconz/zigbee/application.py +++ b/zigpy_deconz/zigbee/application.py @@ -93,11 +93,40 @@ async def startup(self, auto_form=False): NetworkParameter.channel_mask ] await self._api[NetworkParameter.aps_extended_panid] + + if self.state.network_information.network_key is None: + self.state.network_information.network_key = zigpy.state.Key() + + ( + _, + self.state.network_information.network_key.key, + ) = await self._api.read_parameter(NetworkParameter.network_key, 0) + self.state.network_information.network_key.seq = 0 + self.state.network_information.network_key.rx_counter = None + self.state.network_information.network_key.partner_ieee = None + + try: + (self.state.network_information.network_key.tx_counter,) = await self._api[ + NetworkParameter.nwk_frame_counter + ] + except zigpy_deconz.exception.CommandError as ex: + assert ex.status == Status.UNSUPPORTED + self.state.network_information.network_key.tx_counter = None + if self.state.network_information.tc_link_key is None: self.state.network_information.tc_link_key = zigpy.state.Key() + (self.state.network_information.tc_link_key.partner_ieee,) = await self._api[ NetworkParameter.trust_center_address ] + ( + _, + self.state.network_information.tc_link_key.key, + ) = await self._api.read_parameter( + NetworkParameter.link_key, + self.state.network_information.tc_link_key.partner_ieee, + ) + (self.state.network_information.security_level,) = await self._api[ NetworkParameter.security_mode ] @@ -288,8 +317,9 @@ async def broadcast( binascii.hexlify(data), ) dst_addr_ep = t.DeconzAddressEndpoint() - dst_addr_ep.address_mode = t.uint8_t(t.ADDRESS_MODE.GROUP.value) + dst_addr_ep.address_mode = t.uint8_t(t.ADDRESS_MODE.NWK.value) dst_addr_ep.address = t.uint16_t(broadcast_address) + dst_addr_ep.endpoint = dst_ep with self._pending.new(req_id) as req: try: