v1.0.1 - Bug fixes
Unsolicited frames on the command connection no longer cause UNAVAILABLE state
The panel pushes real-time alarm event frames (@alA, !lmX) on the persistent
command TCP connection between command responses. Previously _receive() consumed
these frames as if they were command replies, which caused DevStatus to be None
and the client to return UNAVAILABLE on every poll that raced with a push event.
_receive() now detects non-@ieM frames, parses them, and reads the next frame
until a real command response arrives (up to 5 consecutive unsolicited frames).
Stale response fallback in command dispatcher
In rare cases the panel sends a valid @ieM frame whose content belongs to a
different command (e.g. a zone list arriving while a status request is in flight).
The command dispatcher (_) now retries reading one more frame when the expected
XPath is missing from the response.
New features
Push events forwarded via on_event callback
Unsolicited frames received on the command connection are fully parsed and forwarded
to the new IAlarmMkClient.on_event callback instead of being silently skipped.
The callback is invoked from a worker thread; use asyncio.run_coroutine_threadsafe
to bridge back to an async event loop.
def handle(event: dict):
print("push event:", event)
client.on_event = handleThis means callers that keep a persistent command connection open (e.g. Home
Assistant) receive real-time panel events without needing a separate
IAlarmMkPushClient connection.
XPath constants extracted to _internal/paths.py
All Meian protocol XPath strings are now defined as named constants in
open_ialarm_mk_local_api._internal.paths and reused across both client modules.
Full Changelog: v1.0.0...v1.0.1