Skip to content

Releases: VoidElle/open-ialarm-mk-local-api

v1.0.2 - Bug fixes

10 Jun 13:12

Choose a tag to compare

Bug Fixes

  • ZoneModel.is_open now correctly reports open zones - the previous implementation required both the IN_USE and FAULT status bits to be set. Because the MK7 panel does not set IN_USE for zones in their normal state, is_open always returned False even when a zone was physically open. The check now only requires the FAULT bit, which is the bit the panel sets when a zone is open/faulted.

Documentation

  • Added a note to ZoneModel docs clarifying that is_open only reflects the physical state when "Check magnets" (zone monitoring) is enabled for the zone in the iAlarm app. When disabled, the panel does not report fault status and is_open will always return False.

Full Changelog: v1.0.1...v1.0.2

v1.0.1 - Bug fixes

09 Jun 18:46

Choose a tag to compare

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 = handle

This 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

v1.0.0 - First release

07 Jun 09:35

Choose a tag to compare

Features

  • Async Python client for iAlarm-MK alarm panels via the local Meian TCP protocol
  • Arm Away, Arm Stay, Arm Partial, Disarm, Cancel Alarm
  • Read alarm status, zone list, and network info
  • Framed two-phase socket read: large MK7 responses (>1024 bytes) always received in full
  • TCP keep-alive (SO_KEEPALIVE) to prevent idle connection drops at the OS level
  • Application-level keepalive: background task polls status every 30 s to prevent panel idle timeouts
  • Auto-reconnect: each command retries once on connection drop before raising
  • Concurrent-safe: internal asyncio.Lock serializes all commands (Home Assistant coordinator safe)
  • Async context manager support (async with)
  • Type-safe dataclasses: AlarmStatusModel, ZoneModel, NetworkInfoModel
  • Structured exceptions: IAlarmMkConnectionError, IAlarmMkLoginError, IAlarmMkAlarmError
  • Comprehensive debug logging at every protocol step

Supported panels

Model Default TCP port
iAlarm MK7 8000
iAlarm MK2 18034

Full Changelog: https://github.com/VoidElle/open-ialarm-mk-local-api/commits/v1.0.0