|
16 | 16 | import zigpy.zdo.types as zdo_t
|
17 | 17 | import zigpy.exceptions
|
18 | 18 | from zigpy.exceptions import NetworkNotFormed
|
| 19 | +from zigpy.datastructures import PriorityLock |
19 | 20 |
|
20 | 21 | import zigpy_znp.const as const
|
21 | 22 | import zigpy_znp.types as t
|
@@ -58,7 +59,7 @@ def __init__(self, config: conf.ConfigType):
|
58 | 59 | self._config = config
|
59 | 60 |
|
60 | 61 | self._listeners = defaultdict(list)
|
61 |
| - self._sync_request_lock = asyncio.Lock() |
| 62 | + self._sync_request_lock = PriorityLock() |
62 | 63 |
|
63 | 64 | self.capabilities = None # type: int
|
64 | 65 | self.version = None # type: float
|
@@ -963,6 +964,27 @@ def wait_for_response(self, response: t.CommandBase) -> asyncio.Future:
|
963 | 964 |
|
964 | 965 | return self.wait_for_responses([response])
|
965 | 966 |
|
| 967 | + def get_request_priority(self, request: t.CommandBase) -> int: |
| 968 | + """ |
| 969 | + Returns the priority of a request. |
| 970 | + """ |
| 971 | + |
| 972 | + return { |
| 973 | + # Reset requests always take priority |
| 974 | + c.SYS.ResetReq.Req: 9999, |
| 975 | + # Watchdog pings are a close second |
| 976 | + c.SYS.Ping.Req: 9998, |
| 977 | + # Network requests are deprioritized |
| 978 | + c.ZDO.ExtRouteChk.Req: -1, |
| 979 | + c.ZDO.ExtRouteDisc.Req: -1, |
| 980 | + c.UTIL.AssocGetWithAddress.Req: -1, |
| 981 | + c.UTIL.AssocRemove.Req: -1, |
| 982 | + c.UTIL.AssocAdd.Req: -1, |
| 983 | + c.AF.DataRequestExt.Req: -1, |
| 984 | + c.AF.DataRequestSrcRtg.Req: -1, |
| 985 | + c.ZDO.MgmtPermitJoinReq.Req: -1, |
| 986 | + }.get(type(request), 0) |
| 987 | + |
966 | 988 | async def request(
|
967 | 989 | self, request: t.CommandBase, timeout: int | None = None, **response_params
|
968 | 990 | ) -> t.CommandBase | None:
|
@@ -1004,7 +1026,7 @@ async def request(
|
1004 | 1026 | ctx = (
|
1005 | 1027 | contextlib.AsyncExitStack()
|
1006 | 1028 | if isinstance(request, c.SYS.ResetReq.Req)
|
1007 |
| - else self._sync_request_lock |
| 1029 | + else self._sync_request_lock(priority=self.get_request_priority(request)) |
1008 | 1030 | )
|
1009 | 1031 |
|
1010 | 1032 | # We should only be sending one SREQ at a time, according to the spec
|
|
0 commit comments