Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ loop→Indigo writes go straight through `device_sync.apply_states` (thread-safe

| Module | Role |
|---|---|
| `plugin.py` | Lifecycle glue, action bridge, IWS HTTP handlers. Since E6 also the pairing surface: **Pair Matter Bridge…** (§3.8, codes to the event log because Indigo dialogs have no dynamic labels), **Unpair an Ecosystem…** (§3.9, two confirm gates + a dynamic fabric picker), the `pairing` IWS page, and `getPrefsConfigUiValues`, which seeds PRD §5.5's read-only export readout from state the plugin already holds (no I/O on a dialog open) |
| `plugin.py` | Lifecycle glue and the device/action bridge — `startup`/`shutdown`/`runConcurrentThread`, the device-subscription/export-id watchdog, `deviceUpdated`/`deviceDeleted`, `actionControl*`, and `getPrefsConfigUiValues`'s PRD §5.5 export readout. Composes the four mixins below into `Plugin`; Indigo resolves every `<CallbackMethod>`/list-method by name as an attribute on the `Plugin` class, which is why the split (issue #146) is mixins rather than free-standing modules — none of them may define `__init__`/`deviceUpdated`/etc., or the `super()` chain to `indigo.PluginBase` breaks |
| `plugin_constants.py` | Constants (timeouts, menu/option labels) and the two pure prefs helpers, `server_location`/`sanitize_host`, shared across `plugin.py` and the four mixins — split out because several groups are consumed by two different mixins each, and a mixin importing from `plugin.py` would be a back-import (issue #146) |
| `pairing_page.py` | The pairing IWS page's HTML template (PRD §6) — pure rendering, no `indigo` import, no plugin state. Only caller is `HttpApiMixin._pairing_page` |
| `http_api_mixin.py` | The Domio HTTP API (`docs/API.md` v1.1) — `http_status`/`http_commission`/`http_decommission`/`http_diagnostics`/`http_pairing`. The five IWS `<Action uiPath="hidden">` handlers share the `_parse_request`/`_reply` helpers, which is why the pairing page's IWS glue lives here rather than in `PairingMenuMixin` |
| `export_dialog_mixin.py` | The **Manage Matter Exports…** dialog (PRD-indigo-matter-export §5.1 UI-D) — candidate/role pickers, add/update/remove, and the reconcile/save machinery `startup` calls into. `_truthy` is a de facto shared helper used by call sites across three mixins; it lives here only because `Plugin` always composes all four |
| `pairing_menu_mixin.py` | **Pair Matter Bridge…** (§3.8, codes to the event log because Indigo dialogs have no dynamic labels), **Unpair an Ecosystem…** (§3.9, two confirm gates + a dynamic fabric picker), and fabric backup/restore (issues #26, #136) |
| `server_menu_mixin.py` | matter-server install/restart menus, manual commission/decommission-device menus (+ folder and node pickers), export-bridge recovery (rebuild endpoint map, reset pairings), and the bridge node's LaunchAgent start/stop/diagnose seams — originally separate bands kept in one mixin because they share one construction rule (`ServerProcess` only ever from `Plugin._server_prefs()`) and one install thread |
| `async_runtime.py` | The event loop + thread + bridge primitives |
| `protocol.py` | **Rename firewall** — the only place that knows matter-server wire field names |
| `ws_json_client.py` | Shared transport core for both WS clients: run loop, `min(2**attempt, 30)` reconnect backoff, `message_id`→future correlation, disconnect/diagnostic handling. Handshake + frame vocabulary are subclass hooks; unmatched **error** responses are logged (BRIDGE_PROTOCOL §3.4) |
Expand Down
2 changes: 1 addition & 1 deletion indigo-matter.indigoPlugin/Contents/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<key>IwsApiVersion</key>
<string>1.0.0</string>
<key>PluginVersion</key>
<string>2026.9.1</string>
<string>2026.9.2</string>
<key>ServerApiVersion</key>
<string>3.6</string>
</dict>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def list_nodes(self) -> list:

Every node matter-server has reported is listed, INCLUDING one that
produced no Indigo devices — its entry carries an empty name list, which
``getMatterNodes`` in ``plugin.py`` renders as "(no Indigo devices)".
``ServerMenuMixin.getMatterNodes`` renders as "(no Indigo devices)".
See ``_known_nodes`` for why ``_index`` alone could not do this.

Sorted by node id; device names resolved outside the lock so a slow
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""The outbound export engine — Indigo device changes ⇄ the bridge node.

``plugin.py`` stays lifecycle glue: it owns the Indigo callbacks and nothing
else. Everything those callbacks *mean* for export lives here — when the
``plugin.py`` and its mixins stay UI/lifecycle glue: they own the Indigo
callbacks and nothing else. Everything those callbacks *mean* for export lives here — when the
:class:`bridge_client.BridgeClient` exists at all, what the desired endpoint set
is, how a device change becomes a ``set_state``, and how an ecosystem command
becomes an ``indigo.*`` call. A bare ``§N`` below is ``docs/BRIDGE_PROTOCOL.md``.
Expand Down
Loading
Loading