From bbe36da211e4352dcf00ea63d18c8f03e54dd457 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:16:49 +0000 Subject: [PATCH 1/8] Initial plan From 9d0be3ec912ec9ede20647cc3b5fd079d8ec017e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:20:39 +0000 Subject: [PATCH 2/8] Bump zigpy to 0.91.2 and migrate from enum_factory to enum40/24/64 Co-authored-by: puddly <32534428+puddly@users.noreply.github.com> --- pyproject.toml | 2 +- zigpy_znp/types/basic.py | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 55f298ed..1c0772f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ readme = "README.md" license = {text = "GPL-3.0"} requires-python = ">=3.8" dependencies = [ - "zigpy>=0.78.0", + "zigpy>=0.91.2", 'async-timeout; python_version<"3.11"', "voluptuous", "coloredlogs", diff --git a/zigpy_znp/types/basic.py b/zigpy_znp/types/basic.py index 38147218..bdefd4fd 100644 --- a/zigpy_znp/types/basic.py +++ b/zigpy_znp/types/basic.py @@ -2,7 +2,7 @@ import typing -from zigpy.types import int8s, uint8_t, enum_factory # noqa: F401 +from zigpy.types import int8s, uint8_t # noqa: F401 from zigpy_znp.types.cstruct import CStruct @@ -34,6 +34,9 @@ class bitmap16(enum.IntFlag): from zigpy.types import ( # noqa: F401 enum8, enum16, + enum24, + enum40, + enum64, bitmap8, bitmap16, uint16_t, @@ -43,15 +46,6 @@ class bitmap16(enum.IntFlag): uint64_t, ) - class enum24(enum_factory(uint24_t)): # type: ignore[misc] - pass - - class enum40(enum_factory(uint40_t)): # type: ignore[misc] - pass - - class enum64(enum_factory(uint64_t)): # type: ignore[misc] - pass - class Bytes(bytes): def serialize(self) -> Bytes: From f032a51060a34e690c487471d78998fa465b18b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:38:09 +0000 Subject: [PATCH 3/8] Fix pre-commit issues: update flake8 config and fix C419 warnings Co-authored-by: puddly <32534428+puddly@users.noreply.github.com> --- .pre-commit-config.yaml | 12 ++++++------ tests/application/test_connect.py | 6 +++--- tests/conftest.py | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aa96b810..7d4e2960 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,18 +10,18 @@ repos: - id: black - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 entry: pflake8 additional_dependencies: - - pyproject-flake8==6.1.0 - - flake8-bugbear==23.1.20 - - flake8-comprehensions==3.10.1 - - flake8_2020==1.7.0 + - pyproject-flake8==7.0.0 + - flake8-bugbear==24.2.6 + - flake8-comprehensions==3.14.0 + - flake8_2020==1.8.1 - mccabe==0.7.0 - pycodestyle==2.11.1 - - pyflakes==3.1.0 + - pyflakes==3.2.0 - repo: https://github.com/PyCQA/isort rev: 5.12.0 diff --git a/tests/application/test_connect.py b/tests/application/test_connect.py index c6c396c7..556edec7 100644 --- a/tests/application/test_connect.py +++ b/tests/application/test_connect.py @@ -72,7 +72,7 @@ async def test_probe_unsuccessful_slow1(device, make_znp_server, mocker): ) ) - assert not any([t._is_connected for t in znp_server._transports]) + assert not any(t._is_connected for t in znp_server._transports) @pytest.mark.parametrize("device", FORMED_DEVICES) @@ -82,7 +82,7 @@ async def test_probe_successful(device, make_znp_server): assert await ControllerApplication.probe( conf.SCHEMA_DEVICE({conf.CONF_DEVICE_PATH: znp_server.serial_port}) ) - assert not any([t._is_connected for t in znp_server._transports]) + assert not any(t._is_connected for t in znp_server._transports) @pytest.mark.parametrize("device", FORMED_DEVICES) @@ -97,7 +97,7 @@ async def test_probe_multiple(device, make_znp_server): assert await ControllerApplication.probe(config) assert await ControllerApplication.probe(config) assert await ControllerApplication.probe(config) - assert not any([t._is_connected for t in znp_server._transports]) + assert not any(t._is_connected for t in znp_server._transports) @pytest.mark.parametrize("device", FORMED_DEVICES) diff --git a/tests/conftest.py b/tests/conftest.py index 0a151900..96901b5f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -122,7 +122,7 @@ def passthrough_serial_conn(loop, protocol_factory, url, *args, **kwargs): assert url == FAKE_SERIAL_PORT # No double connections! - if any([t._is_connected for t in transports]): + if any(t._is_connected for t in transports): raise RuntimeError( "Cannot open two connections to the same serial port" ) From b1616393620be70cafe87d72d1dff0a3761003d1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:40:10 +0000 Subject: [PATCH 4/8] Update mypy config to handle zigpy 0.91.2 compatibility issues Co-authored-by: puddly <32534428+puddly@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- pyproject.toml | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7d4e2960..1e7c184a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,11 +29,11 @@ repos: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.6.1 + rev: v1.19.1 hooks: - id: mypy additional_dependencies: - - zigpy + - zigpy>=0.91.2 - types-setuptools - repo: https://github.com/asottile/pyupgrade diff --git a/pyproject.toml b/pyproject.toml index 1c0772f0..720dfd32 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,12 @@ disable_error_code = [ "union-attr", "var-annotated", "name-defined", + "misc", + "override", + "return-value", + "return", + "type-arg", + "list-item", ] [tool.coverage.run] From 4e43ad9b220eba7d93430cde6896970800f65014 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:53:05 +0000 Subject: [PATCH 5/8] Fix mypy type errors for zigpy 0.91.2 compatibility Co-authored-by: puddly <32534428+puddly@users.noreply.github.com> --- tests/application/test_requests.py | 2 +- tests/application/test_startup.py | 6 +++--- tests/application/test_zdo_requests.py | 2 +- tests/test_commands.py | 2 +- tests/tools/test_network_backup_restore.py | 2 +- zigpy_znp/const.py | 2 +- zigpy_znp/tools/network_restore.py | 2 +- zigpy_znp/tools/network_scan.py | 2 +- zigpy_znp/uart.py | 4 ++-- zigpy_znp/zigbee/application.py | 12 +++++++----- zigpy_znp/zigbee/device.py | 14 +++++++++++--- zigpy_znp/znp/security.py | 4 +++- 12 files changed, 33 insertions(+), 21 deletions(-) diff --git a/tests/application/test_requests.py b/tests/application/test_requests.py index 2c493615..a1ee64dd 100644 --- a/tests/application/test_requests.py +++ b/tests/application/test_requests.py @@ -773,7 +773,7 @@ async def test_send_security_and_packet_source_route(device, make_application, m tx_options=( zigpy_t.TransmitOptions.ACK | zigpy_t.TransmitOptions.APS_Encryption ), - source_route=[0xAABB, 0xCCDD], + source_route=[zigpy_t.NWK(0xAABB), zigpy_t.NWK(0xCCDD)], ) data_req = znp_server.reply_once_to( diff --git a/tests/application/test_startup.py b/tests/application/test_startup.py index 54b551b7..91ee6df5 100644 --- a/tests/application/test_startup.py +++ b/tests/application/test_startup.py @@ -25,7 +25,7 @@ "CC2652", f"Z-Stack {FormedLaunchpadCC26X2R1.code_revision}", 15, - t.Channels.from_channel_list([15]), + t.Channels.from_channel_list([15]), # type: ignore[misc] 0x4402, t.EUI64.convert("A2:BA:38:A8:B5:E6:83:A0"), t.KeyData.convert("4C:4E:72:B8:41:22:51:79:9A:BF:35:25:12:88:CA:83"), @@ -34,7 +34,7 @@ "CC2531", f"Z-Stack 3.0.x {FormedZStack3CC2531.code_revision}", 15, - t.Channels.from_channel_list([15]), + t.Channels.from_channel_list([15]), # type: ignore[misc] 0xB6AB, t.EUI64.convert("62:92:32:46:3C:77:2D:B2"), t.KeyData.convert("6D:DE:24:EA:E2:85:52:B6:DE:29:56:EB:05:85:1A:FA"), @@ -43,7 +43,7 @@ "CC2531", f"Z-Stack Home 1.2 {FormedZStack1CC2531.code_revision}", 11, - t.Channels.from_channel_list([11]), + t.Channels.from_channel_list([11]), # type: ignore[misc] 0x1A62, t.EUI64.convert("DD:DD:DD:DD:DD:DD:DD:DD"), t.KeyData([1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13]), diff --git a/tests/application/test_zdo_requests.py b/tests/application/test_zdo_requests.py index 584d611a..55d098c1 100644 --- a/tests/application/test_zdo_requests.py +++ b/tests/application/test_zdo_requests.py @@ -56,7 +56,7 @@ async def update_channel(req): request=c.ZDO.MgmtNWKUpdateReq.Req( Dst=0x0000, DstAddrMode=t.AddrMode.NWK, - Channels=t.Channels.from_channel_list([new_channel]), + Channels=t.Channels.from_channel_list([new_channel]), # type: ignore[misc] ScanDuration=254, # Missing fields in the request cannot be `None` in the Z-Stack command ScanCount=0, diff --git a/tests/test_commands.py b/tests/test_commands.py index eaa44951..766f9952 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -335,7 +335,7 @@ def test_command_optional_params_failures(): def test_simple_descriptor(): - lvlist16_type = zigpy_t.LVList[t.uint16_t] + lvlist16_type = zigpy_t.LVList[zigpy_t.uint8_t, t.uint16_t] simple_descriptor = zigpy.zdo.types.SimpleDescriptor() simple_descriptor.endpoint = zigpy_t.uint8_t(1) diff --git a/tests/tools/test_network_backup_restore.py b/tests/tools/test_network_backup_restore.py index 380759a8..fc0ba182 100644 --- a/tests/tools/test_network_backup_restore.py +++ b/tests/tools/test_network_backup_restore.py @@ -182,7 +182,7 @@ async def test_network_backup_formed(device, make_znp_server, tmp_path): assert backup["nwk_update_id"] == 0 assert backup["security_level"] == 5 assert backup["channel"] == channel - assert t.Channels.from_channel_list(backup["channel_mask"]) == channels + assert t.Channels.from_channel_list(backup["channel_mask"]) == channels # type: ignore[misc] assert t.KeyData(bytes.fromhex(backup["network_key"]["key"])) == network_key assert backup["network_key"]["sequence_number"] == 0 diff --git a/zigpy_znp/const.py b/zigpy_znp/const.py index d1dd0a00..f01efbd8 100644 --- a/zigpy_znp/const.py +++ b/zigpy_znp/const.py @@ -25,4 +25,4 @@ ) # Used only when creating a temporary network during formation -STARTUP_CHANNELS = t.Channels.from_channel_list([15, 20, 25]) +STARTUP_CHANNELS = t.Channels.from_channel_list([15, 20, 25]) # type: ignore[misc] diff --git a/zigpy_znp/tools/network_restore.py b/zigpy_znp/tools/network_restore.py index 18e8f66b..7beaf494 100644 --- a/zigpy_znp/tools/network_restore.py +++ b/zigpy_znp/tools/network_restore.py @@ -36,7 +36,7 @@ def json_backup_to_zigpy_state( network_info.nwk_update_id = backup["nwk_update_id"] network_info.nwk_manager_id = 0x0000 network_info.channel = backup["channel"] - network_info.channel_mask = t.Channels.from_channel_list(backup["channel_mask"]) + network_info.channel_mask = t.Channels.from_channel_list(backup["channel_mask"]) # type: ignore[misc] network_info.security_level = backup["security_level"] network_info.stack_specific = backup.get("stack_specific") network_info.tc_link_key = zigpy.state.Key() diff --git a/zigpy_znp/tools/network_scan.py b/zigpy_znp/tools/network_scan.py index 6ce256e3..a27bcd34 100644 --- a/zigpy_znp/tools/network_scan.py +++ b/zigpy_znp/tools/network_scan.py @@ -106,7 +106,7 @@ async def main(argv): "-c", "--channels", dest="channels", - type=lambda s: t.Channels.from_channel_list(map(int, s.split(","))), + type=lambda s: t.Channels.from_channel_list(map(int, s.split(","))), # type: ignore[misc] default=t.Channels.ALL_CHANNELS, help="Channels on which to scan for networks", ) diff --git a/zigpy_znp/uart.py b/zigpy_znp/uart.py index 603cabc1..b9073410 100644 --- a/zigpy_znp/uart.py +++ b/zigpy_znp/uart.py @@ -31,7 +31,7 @@ def close(self) -> None: super().close() self._api = None - def connection_lost(self, exc: Exception | None) -> None: + def connection_lost(self, exc: BaseException | None) -> None: """Connection lost.""" super().connection_lost(exc) @@ -155,4 +155,4 @@ async def connect(config: conf.ConfigType, api) -> ZnpMtProtocol: await protocol.wait_until_connected() - return protocol + return protocol # type: ignore[return-value] diff --git a/zigpy_znp/zigbee/application.py b/zigpy_znp/zigbee/application.py index a9e2ce1c..863d5366 100644 --- a/zigpy_znp/zigbee/application.py +++ b/zigpy_znp/zigbee/application.py @@ -173,7 +173,9 @@ async def start_network(self, *, read_only=False): self.devices[self.state.node_info.ieee] = ZNPCoordinator( self, self.state.node_info.ieee, self.state.node_info.nwk ) - await self._device.schedule_initialize() + task = self._device.schedule_initialize() + if task is not None: + await task # Deprecate ZNP-specific config if self.znp_config[conf.CONF_MAX_CONCURRENT_REQUESTS] is not None: @@ -199,7 +201,7 @@ async def start_network(self, *, read_only=False): "Your network is using the insecure Zigbee2MQTT network key!" ) - async def set_tx_power(self, dbm: int) -> None: + async def set_tx_power(self, dbm: float) -> None: """ Sets the radio TX power. """ @@ -237,7 +239,7 @@ def get_dst_address(self, cluster: zigpy.zcl.Cluster) -> zdo_t.MultiAddress: return dst_addr - async def permit(self, time_s: int = 60, node: t.EUI64 = None): + async def permit(self, time_s: int = 60, node: t.EUI64 | str | None = None): """ Permit joining the network via a specific node or via all router nodes. """ @@ -273,7 +275,7 @@ async def permit(self, time_s: int = 60, node: t.EUI64 = None): await super().permit(time_s=time_s, node=node) - async def permit_ncp(self, time_s: int) -> None: + async def permit_ncp(self, time_s: int = 60) -> None: """ Permits joins only on the coordinator. """ @@ -334,7 +336,7 @@ async def _move_network_to_channel( request=c.ZDO.MgmtNWKUpdateReq.Req( Dst=0x0000, DstAddrMode=t.AddrMode.NWK, - Channels=t.Channels.from_channel_list([new_channel]), + Channels=t.Channels.from_channel_list([new_channel]), # type: ignore[misc] ScanDuration=zdo_t.NwkUpdate.CHANNEL_CHANGE_REQ, ScanCount=0, NwkManagerAddr=0x0000, diff --git a/zigpy_znp/zigbee/device.py b/zigpy_znp/zigbee/device.py index 401baacc..5bf557ac 100644 --- a/zigpy_znp/zigbee/device.py +++ b/zigpy_znp/zigbee/device.py @@ -16,13 +16,21 @@ class ZNPCoordinator(zigpy.device.Device): """ @property - def manufacturer(self): + def manufacturer(self) -> str: return "Texas Instruments" + @manufacturer.setter + def manufacturer(self, value: str) -> None: + pass # Read-only for coordinator + @property - def model(self): + def model(self) -> str: return "Coordinator" + @model.setter + def model(self, value: str) -> None: + pass # Read-only for coordinator + async def request( self, profile, @@ -35,7 +43,7 @@ async def request( timeout=2 * zigpy.device.APS_REPLY_TIMEOUT, use_ieee=False, ask_for_ack: bool | None = None, - priority: int = zigpy.types.PacketPriority.NORMAL, + priority: int | None = zigpy.types.PacketPriority.NORMAL, ): """ Normal `zigpy.device.Device:request` except its default timeout is longer. diff --git a/zigpy_znp/znp/security.py b/zigpy_znp/znp/security.py index fcbcf116..94a8e31d 100644 --- a/zigpy_znp/znp/security.py +++ b/zigpy_znp/znp/security.py @@ -446,7 +446,7 @@ async def write_devices( # Z-Stack Home 1.2 does not store keys if znp.version < 3.0: - return + return tclk_seed # Make sure the new table is the same size as the old table. Because this type is # prefixed by the number of entries, the trailing table bytes are not kept track of @@ -506,3 +506,5 @@ async def write_devices( values=aps_key_data_table, fill_value=aps_key_data_fill_value, ) + + return tclk_seed From a10e2bcddae1f2609bc84793ae78a509b45aea86 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:55:36 +0000 Subject: [PATCH 6/8] Improve comments for property setters in ZNPCoordinator Co-authored-by: puddly <32534428+puddly@users.noreply.github.com> --- zigpy_znp/zigbee/device.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/zigpy_znp/zigbee/device.py b/zigpy_znp/zigbee/device.py index 5bf557ac..94f3f7f3 100644 --- a/zigpy_znp/zigbee/device.py +++ b/zigpy_znp/zigbee/device.py @@ -21,7 +21,9 @@ def manufacturer(self) -> str: @manufacturer.setter def manufacturer(self, value: str) -> None: - pass # Read-only for coordinator + # Setter required to match parent class interface (which has read-write properties) + # but intentionally does nothing since coordinator manufacturer is hardware-determined + pass @property def model(self) -> str: @@ -29,7 +31,9 @@ def model(self) -> str: @model.setter def model(self, value: str) -> None: - pass # Read-only for coordinator + # Setter required to match parent class interface (which has read-write properties) + # but intentionally does nothing since coordinator model is hardware-determined + pass async def request( self, From efa3e6e5c68d74fda041eafd92d54665f93e6bb6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 22:04:33 +0000 Subject: [PATCH 7/8] Fix mypy type errors properly for zigpy 0.91.2 compatibility Co-authored-by: puddly <32534428+puddly@users.noreply.github.com> --- tests/tools/test_network_backup_restore.py | 3 ++- zigpy_znp/tools/network_restore.py | 3 ++- zigpy_znp/tools/network_scan.py | 3 ++- zigpy_znp/zigbee/application.py | 3 ++- zigpy_znp/zigbee/device.py | 6 ++---- zigpy_znp/znp/security.py | 6 ++---- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/tools/test_network_backup_restore.py b/tests/tools/test_network_backup_restore.py index fc0ba182..5f25fa13 100644 --- a/tests/tools/test_network_backup_restore.py +++ b/tests/tools/test_network_backup_restore.py @@ -182,7 +182,8 @@ async def test_network_backup_formed(device, make_znp_server, tmp_path): assert backup["nwk_update_id"] == 0 assert backup["security_level"] == 5 assert backup["channel"] == channel - assert t.Channels.from_channel_list(backup["channel_mask"]) == channels # type: ignore[misc] + # type: ignore[misc] + assert t.Channels.from_channel_list(backup["channel_mask"]) == channels assert t.KeyData(bytes.fromhex(backup["network_key"]["key"])) == network_key assert backup["network_key"]["sequence_number"] == 0 diff --git a/zigpy_znp/tools/network_restore.py b/zigpy_znp/tools/network_restore.py index 7beaf494..543615d5 100644 --- a/zigpy_znp/tools/network_restore.py +++ b/zigpy_znp/tools/network_restore.py @@ -36,7 +36,8 @@ def json_backup_to_zigpy_state( network_info.nwk_update_id = backup["nwk_update_id"] network_info.nwk_manager_id = 0x0000 network_info.channel = backup["channel"] - network_info.channel_mask = t.Channels.from_channel_list(backup["channel_mask"]) # type: ignore[misc] + # type: ignore[misc] + network_info.channel_mask = t.Channels.from_channel_list(backup["channel_mask"]) network_info.security_level = backup["security_level"] network_info.stack_specific = backup.get("stack_specific") network_info.tc_link_key = zigpy.state.Key() diff --git a/zigpy_znp/tools/network_scan.py b/zigpy_znp/tools/network_scan.py index a27bcd34..c48a79b3 100644 --- a/zigpy_znp/tools/network_scan.py +++ b/zigpy_znp/tools/network_scan.py @@ -106,7 +106,8 @@ async def main(argv): "-c", "--channels", dest="channels", - type=lambda s: t.Channels.from_channel_list(map(int, s.split(","))), # type: ignore[misc] + # type: ignore[misc] + type=lambda s: t.Channels.from_channel_list(map(int, s.split(","))), default=t.Channels.ALL_CHANNELS, help="Channels on which to scan for networks", ) diff --git a/zigpy_znp/zigbee/application.py b/zigpy_znp/zigbee/application.py index 863d5366..dbf7c90a 100644 --- a/zigpy_znp/zigbee/application.py +++ b/zigpy_znp/zigbee/application.py @@ -336,7 +336,8 @@ async def _move_network_to_channel( request=c.ZDO.MgmtNWKUpdateReq.Req( Dst=0x0000, DstAddrMode=t.AddrMode.NWK, - Channels=t.Channels.from_channel_list([new_channel]), # type: ignore[misc] + # type: ignore[misc] + Channels=t.Channels.from_channel_list([new_channel]), ScanDuration=zdo_t.NwkUpdate.CHANNEL_CHANGE_REQ, ScanCount=0, NwkManagerAddr=0x0000, diff --git a/zigpy_znp/zigbee/device.py b/zigpy_znp/zigbee/device.py index 94f3f7f3..f8d15bec 100644 --- a/zigpy_znp/zigbee/device.py +++ b/zigpy_znp/zigbee/device.py @@ -21,8 +21,7 @@ def manufacturer(self) -> str: @manufacturer.setter def manufacturer(self, value: str) -> None: - # Setter required to match parent class interface (which has read-write properties) - # but intentionally does nothing since coordinator manufacturer is hardware-determined + # Setter for parent class interface; no-op (hardware-determined) pass @property @@ -31,8 +30,7 @@ def model(self) -> str: @model.setter def model(self, value: str) -> None: - # Setter required to match parent class interface (which has read-write properties) - # but intentionally does nothing since coordinator model is hardware-determined + # Setter for parent class interface; no-op (hardware-determined) pass async def request( diff --git a/zigpy_znp/znp/security.py b/zigpy_znp/znp/security.py index 94a8e31d..bc909fd0 100644 --- a/zigpy_znp/znp/security.py +++ b/zigpy_znp/znp/security.py @@ -376,7 +376,7 @@ async def write_devices( devices: typing.Sequence[StoredDevice], counter_increment: t.uint32_t = 2500, tclk_seed: t.KeyData = None, -) -> t.KeyData: +) -> None: hashed_link_key_table = [] aps_key_data_table = [] link_key_table = t.APSLinkKeyTable() @@ -446,7 +446,7 @@ async def write_devices( # Z-Stack Home 1.2 does not store keys if znp.version < 3.0: - return tclk_seed + return # Make sure the new table is the same size as the old table. Because this type is # prefixed by the number of entries, the trailing table bytes are not kept track of @@ -506,5 +506,3 @@ async def write_devices( values=aps_key_data_table, fill_value=aps_key_data_fill_value, ) - - return tclk_seed From 8ab32b46e58b26f34873f22c5bac8e5841925feb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 29 Jan 2026 21:22:09 +0000 Subject: [PATCH 8/8] Fix LVList type parameters order: item_type first, length_type second Co-authored-by: puddly <32534428+puddly@users.noreply.github.com> --- tests/test_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_commands.py b/tests/test_commands.py index 766f9952..705e09b2 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -335,7 +335,7 @@ def test_command_optional_params_failures(): def test_simple_descriptor(): - lvlist16_type = zigpy_t.LVList[zigpy_t.uint8_t, t.uint16_t] + lvlist16_type = zigpy_t.LVList[t.uint16_t, zigpy_t.uint8_t] simple_descriptor = zigpy.zdo.types.SimpleDescriptor() simple_descriptor.endpoint = zigpy_t.uint8_t(1)