Skip to content

Commit

Permalink
Implement command priority
Browse files Browse the repository at this point in the history
  • Loading branch information
puddly committed Dec 15, 2023
1 parent cc1f018 commit 58695eb
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ license = {text = "GPL-3.0"}
requires-python = ">=3.8"
dependencies = [
"voluptuous",
"zigpy>=0.60.0",
"zigpy>=0.60.2",
'async-timeout; python_version<"3.11"',
]

Expand Down
14 changes: 14 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,3 +993,17 @@ async def test_cb3_device_state_callback_bug(api, mock_command_rsp):
await asyncio.sleep(0.01)

assert api._device_state == device_state


def test_get_command_priority(api):
assert (
api._get_command_priority(
deconz_api.Command(command_id=deconz_api.CommandId.write_parameter)
)
> api._get_command_priority(
deconz_api.Command(command_id=deconz_api.CommandId.update_neighbor)
)
> api._get_command_priority(
deconz_api.Command(command_id=deconz_api.CommandId.aps_data_request)
)
)
15 changes: 13 additions & 2 deletions zigpy_deconz/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from asyncio import timeout as asyncio_timeout # pragma: no cover

from zigpy.config import CONF_DEVICE_PATH
from zigpy.datastructures import PriorityLock
from zigpy.types import (
APSStatus,
Bool,
Expand Down Expand Up @@ -416,7 +417,7 @@ def __init__(self, app: Callable, device_config: dict[str, Any]):
"""Init instance."""
self._app = app
self._awaiting = {}
self._command_lock = asyncio.Lock()
self._command_lock = PriorityLock()
self._config = device_config
self._device_state = DeviceState(
network_state=NetworkState2.OFFLINE,
Expand Down Expand Up @@ -486,6 +487,16 @@ def close(self):
self._uart.close()
self._uart = None

def _get_command_priority(self, command: Command) -> int:
return {
# The watchdog is fed using `write_parameter` and `get_device_state` so they
# must take priority
CommandId.write_parameter: 999,
CommandId.device_state: 999,
# APS data requests are retried and can be deprioritized
CommandId.aps_data_request: -1,
}.get(command.command_id, 0)

async def _command(self, cmd, **kwargs):
payload = []
tx_schema, _ = COMMAND_SCHEMAS[cmd]
Expand Down Expand Up @@ -547,7 +558,7 @@ async def _command(self, cmd, **kwargs):
# connection was lost
raise CommandError(Status.ERROR, "API is not running")

async with self._command_lock:
async with self._command_lock(priority=self._get_command_priority(command)):
seq = self._seq

LOGGER.debug("Sending %s%s (seq=%s)", cmd, kwargs, seq)
Expand Down
4 changes: 2 additions & 2 deletions zigpy_deconz/zigbee/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class ControllerApplication(zigpy.application.ControllerApplication):
{zigpy.config.CONF_DEVICE_BAUDRATE: 115200},
]

_watchdog_period = 600 * 0.75
_watchdog_period = 30

def __init__(self, config: dict[str, Any]):
"""Initialize instance."""
Expand All @@ -85,7 +85,7 @@ async def _watchdog_feed(self):
and self._api.firmware_version <= 0x26450900
):
await self._api.write_parameter(
NetworkParameter.watchdog_ttl, int(self._watchdog_period / 0.75)
NetworkParameter.watchdog_ttl, int(2 * self._watchdog_period)
)
else:
await self._api.get_device_state()
Expand Down

0 comments on commit 58695eb

Please sign in to comment.