Skip to content
Closed
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
94 changes: 83 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
# indigo-matter

Matter device support for the [Indigo](https://www.indigodomo.com) home automation server.

Add Matter devices from the **Domio** iOS app or the plugin's own menu; control them as
first-class Indigo devices (triggers, schedules, action groups, control pages, API). The
plugin manages a [`matter-server`](https://github.com/matter-js/matterjs-server) instance,
holds the Indigo-owned Matter fabric, translates Matter clusters ↔ Indigo device types,
and owns runtime control for each device's lifetime.
Matter device support for the [Indigo](https://www.indigodomo.com) home automation server —
**in both directions**.

**Matter in (the controller).** Add Matter devices from the **Domio** iOS app or the
plugin's own menu; control them as first-class Indigo devices (triggers, schedules, action
groups, control pages, API). The plugin manages a
[`matter-server`](https://github.com/matter-js/matterjs-server) instance, holds the
Indigo-owned Matter fabric, translates Matter clusters ↔ Indigo device types, and owns
runtime control for each device's lifetime.

**Matter out (the bridge).** Publish selected *Indigo* devices — Z-Wave, Insteon, Zigbee,
MQTT, anything with a device record — outward as Matter accessories, so Apple Home can see
and control them locally. Opt-in per device, nothing exported by default, from a second
managed process. Apple Home is the ecosystem this is built and documented for; Alexa,
Google Home and SmartThings are untested and unclaimed. See
[Exporting Indigo devices](#exporting-indigo-devices-matter-out).

> **This is an independent, uncertified implementation.** It is not certified by the
> Connectivity Standards Alliance (CSA), and is not affiliated with or endorsed by them.
Expand All @@ -17,7 +26,9 @@ and owns runtime control for each device's lifetime.
```text
Domio (iOS) ─┐
├── setup code ──▶ indigo-matter ──WebSocket──▶ matter-server ──IP──▶ Wi-Fi + Thread devices
plugin menu ─┘
plugin menu ─┘ │
└──WebSocket──▶ bridge node ──Matter──▶ Apple Home
(export, opt-in)
```

## Adding devices
Expand All @@ -34,9 +45,39 @@ device reaches one of them:
- **Already on your network, never commissioned** — its printed code works directly, from
either entry point.

## Exporting Indigo devices (Matter out)

The plugin can also wear the Matter **device** role: a set of Indigo devices you choose is
published as accessories on a Matter bridge that Apple Home commissions like any other
accessory. One bridge, one pairing, however many devices.

- **Opt-in per device, default empty.** A fresh install exports nothing, pairs nothing and
runs no bridge process. Exporting is publishing — the device becomes operable from every
ecosystem the bridge is paired with — so it is always a deliberate act.
- **You declare what each device is.** Indigo cannot tell a plug from a lamp from a lock,
so the export dialog asks, and defaults to the safest reading. Relays, dimmers, colour
and colour-temperature lights, window coverings, locks, the seven sensor types and
thermostats are supported; valves, fans, garage doors, sprinklers and MultiIO are not,
and appear in the picker **with the reason**.
- **Expect an "uncertified accessory" prompt** and choose *Add Anyway*. The bridge presents
a development attestation certificate — as Homebridge, matterbridge and Home Assistant's
bridge all do — and outbound attestation is the commissioning ecosystem's policy, not
something this plugin can change.
- **Apple Home only, as a claim.** Alexa, Google Home and SmartThings are untested and
unclaimed; nothing here says they will or won't work.
- **A second npm package** (`indigo-matter-bridge`), installed from its own menu item.
Note it is **not on the npm registry yet**, so export cannot be brought up until it is.

Setup, pairing, recovery and troubleshooting:
[full install guide](https://simons-plugins.github.io/indigo-matter/INSTALL.html). How it
works and what it can represent:
[MATTER.md → Indigo as a Matter bridge](docs/MATTER.md#indigo-as-a-matter-bridge--the-other-direction).
(The typeset [Field Notes № 1](https://simons-plugins.github.io/indigo-matter/matter.html)
page predates the export half and does not cover it yet.)

## Status

**Built and live-validated, including with real hardware.** The full device-class
**Matter in — built and live-validated, including with real hardware.** The full device-class
catalogue is shipped — lighting (on/off/dimmer/colour), sensors, thermostats, fans,
window coverings, locks, valves, buttons, smoke/CO, air quality, energy metering,
battery levels, and bridges — plus failure hardening, fabric backup/restore, and a
Expand All @@ -52,6 +93,22 @@ during the Domio flow); the plugin then joins over IP via that ecosystem's borde
fit; validation specifics live in
[Handover](https://simons-plugins.github.io/indigo-matter/HANDOVER.html).

**Matter out — built, unit-tested on both sides, partly validated live.** The allow-list,
the role mapping, endpoint persistence, pairing and fabric management, and the managed
LaunchAgent are all in place, and the bridge node's own suite stands up a real Matter stack.
On live hardware the bridge **has** been commissioned into Apple Home (uncertified prompt
and all), an on/off light and a dimmer **have** been controlled in both directions, and
accessory identity **has** survived an upgrade without duplicating (2026-08-04 / 05, on
the reference server). Still outstanding: pairing through the plugin's own menu rather
than the node's console, a second controller alongside Apple Home, the reboot leg of the
identity check, and the managed LaunchAgent end to end — that last one needs the package
installed, which until `indigo-matter-bridge` is published means the local-install
workaround rather than the shipped install menu. Treat the export half as new. See
[MATTER.md](docs/MATTER.md#indigo-as-a-matter-bridge--the-other-direction) for how it
works, and
[Handover](https://simons-plugins.github.io/indigo-matter/HANDOVER.html) for the
validation specifics.

## Setup

The plugin doesn't speak Matter directly — it drives **matter-server**, a separate
Expand Down Expand Up @@ -86,12 +143,19 @@ reconciled N Matter node(s)
manual mode, fabric backups, upgrading and uninstalling, is covered in the
[full install guide](https://simons-plugins.github.io/indigo-matter/INSTALL.html).

To **export** Indigo devices as well, add a fourth step — **Plugins ▸ Matter ▸
Install/update the Matter export bridge** — and then pick your devices in *Manage Matter
Exports…*. The bridge starts itself once something is exported. Full walkthrough in the
install guide.

## Requirements

- Indigo 2025.2+ on macOS.
- **Node.js ≥ 22.13.0** (Homebrew is the paved road; nvm works too) and the `matter-server`
npm package — Beta, **exact-pinned to 1.2.2** (`DEFAULT_INSTALL_SPEC`; the Install action
uses this).
- For export only: a second npm package, `indigo-matter-bridge`, exact-pinned and installed
by its own menu item. Not yet on the npm registry.
- Python dep: `websockets` (see `Contents/Server Plugin/requirements.txt`).
- The **Domio** iOS app for adding devices — optional: the plugin menu's *Commission
device by setup code…* does the same job from Indigo.
Expand Down Expand Up @@ -122,7 +186,10 @@ Developer reference, in the repo — not intended as user documentation:

- [`docs/IMPLEMENTATION.md`](https://github.com/simons-plugins/indigo-matter/blob/main/docs/IMPLEMENTATION.md) — protocols, scaffold, cluster handlers.
- [`docs/API.md`](https://github.com/simons-plugins/indigo-matter/blob/main/docs/API.md) — the Domio ↔ plugin HTTP contract (v1.3).
- [`docs/PRD-indigo-matter-plugin.md`](https://github.com/simons-plugins/indigo-matter/blob/main/docs/PRD-indigo-matter-plugin.md) — product requirements and milestones.
- [`docs/BRIDGE_PROTOCOL.md`](https://github.com/simons-plugins/indigo-matter/blob/main/docs/BRIDGE_PROTOCOL.md) — the plugin ⇄ bridge-node local protocol (export side).
- [`docs/PRD-indigo-matter-plugin.md`](https://github.com/simons-plugins/indigo-matter/blob/main/docs/PRD-indigo-matter-plugin.md) — product requirements and milestones (inbound).
- [`docs/PRD-indigo-matter-export.md`](https://github.com/simons-plugins/indigo-matter/blob/main/docs/PRD-indigo-matter-export.md) — the same for the export bridge.
- [`bridge-node/`](https://github.com/simons-plugins/indigo-matter/tree/main/bridge-node) — the bridge node itself (TypeScript; the only place matter.js is imported). `npm run build && npm test`.
- [`CLAUDE.md`](https://github.com/simons-plugins/indigo-matter/blob/main/CLAUDE.md) — architecture and workspace conventions.

## Trademarks and certification
Expand Down Expand Up @@ -150,6 +217,12 @@ What that means in practice:
attestation so uncertified devices (development boards, Homebridge/Matterbridge
bridges) can be commissioned. It is off by default, warns on every start, and should
be turned off once the device is paired.
- **The export bridge is uncertified in the other direction, and visibly so.** It
advertises with the specification's test vendor ID, so every ecosystem shows an
"uncertified accessory" warning when you add it and you choose *Add Anyway*. That is the
normal state for this class of software — Homebridge, matterbridge and Home Assistant's
bridge all ship the same way — and it is not something the plugin can change: outbound,
the trust policy belongs to the ecosystem doing the commissioning.

The icon bundles the Matter symbol from
[Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Logo_of_Matter_connectivity_standard.svg),
Expand All @@ -159,4 +232,3 @@ which is public domain for copyright purposes. See
## License

MIT — see [LICENSE](https://github.com/simons-plugins/indigo-matter/blob/main/LICENSE).
</content>
5 changes: 3 additions & 2 deletions bridge-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ The Matter **bridge node** for the
[indigo-matter](https://github.com/simons-plugins/indigo-matter) Indigo plugin.

It exports selected [Indigo](https://www.indigodomo.com) devices as Matter
accessories, so Apple Home, Alexa, Google Home and SmartThings see them as
ordinary Matter devices on a bridge.
accessories, so an ecosystem sees them as ordinary Matter devices on a bridge.
**Apple Home** is the ecosystem this is built and documented for; Alexa, Google
Home and SmartThings are untested and unclaimed.

> **This package is not useful on its own.** It has no configuration of its own,
> no discovery, and no idea what an Indigo device is. It is one half of a pair:
Expand Down
81 changes: 68 additions & 13 deletions docs/HANDOVER.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# indigo-matter — Build Handover

**Last updated:** 2026-08-05 23:21 UTC
**Active work:** `feat/e6-e7-pairing-and-agent` — E6 + E7, the last functional
export milestones (E8 is docs only). See the section immediately below; the
`main` summary in this header describes the last merge, not that branch.
**Last updated:** 2026-08-05 23:58 UTC
**Active work:** `docs/e8-export-documentation` (PR #129, stacked on
`feat/e6-e7-pairing-and-agent` / PR #128) — E8, docs only. See the E6+E7 section
immediately below; the `main` summary in this header describes the last merge,
not those branches.
**Branch:** `main` — PRs #106, #107, #108 all merged.
**Version:** `2026.7.13`
**Tests:** 1005 passing (`cd indigo-matter && /Library/Frameworks/Python.framework/Versions/Current/bin/python3 -m pytest -q`)
**Deployed:** jarvis is **unchanged** — still running the #103 code (v2026.7.10 era). **Nothing from #106/#107/#108 has been deployed**, so the #104 supervision fixes are NOT yet live on jarvis.
**Status:** **Wi-Fi AND Thread validated with real hardware.** #104's three server-supervision faults are fixed and merged (#107). #105's diagnostic is merged (#108) but **#105 stays open** — the bridged-endpoint path still has no real-bridge validation. `domio-code` #236 is fixed and closed (domio-code PR #237). Known-open: #105, plus the older #43, #46, #21–#24.
**Deployed:** jarvis is running the #103-era plugin (v2026.7.10) plus **E5's export half, deployed 2026-08-05 with 3 accessories live in Apple Home**. **Nothing from #106/#107/#108, and no part of E6 or E7, has been deployed** so the #104 supervision fixes are NOT yet live on jarvis.
**Status:** **Wi-Fi AND Thread validated with real hardware**, and the **export half's E0 pairing gate PASSED on 2026-08-04** with live two-way control on 2026-08-05 (see *Live validation on jarvis*). #104's three server-supervision faults are fixed and merged (#107). #105's diagnostic is merged (#108) but **#105 stays open** — the bridged-endpoint path still has no real-bridge validation. `domio-code` #236 is fixed and closed (domio-code PR #237). Known-open: #105, plus the older #43, #46, #21–#24.

---

Expand Down Expand Up @@ -396,10 +397,55 @@ exactly where `LaunchAgent._server_entry()` looks for it. `npm link` works too.
Do this and everything in E7 runs unchanged; just remember the plugin's install
menu will still try the registry spec.

**So the managed LaunchAgent is not, strictly, blocked on `npm publish`.** It is
blocked on the package being *installed*, and the local-install recipe above
installs it. What the publish unblocks is the shipped route — the
"Install/update the Matter export bridge" menu item — which is what a user would
use and is therefore what "end to end" means. Do not restate the blocker as
"npm" when the distinction matters.

### Live validation on jarvis — what has actually happened

Recorded here because README, MATTER.md and INSTALL.md all point at this file
for the specifics. Dates are the observation dates, not the write-up dates.

**E0's gate: PASSED (2026-08-04).** An uncertified bridge was commissioned into
a real Apple Home and the uncertified-accessory prompt was accepted. This is the
question that could have killed the feature outright — *will any ecosystem pair
an uncertified test-VID bridge?* — and the answer is yes. Note the pairing was
driven from the **bridge node's own console**, before the plugin's pairing menu
existed; see the outstanding list below.

**E3's live E2E: PASSED (2026-08-05).** An on/off light and a dimmer, exported
through the **Manage Matter Exports…** dialog, controlled from Apple Home and
from Indigo, each direction showing up on the other side. That is XAC4 in both
directions and XAC3's Apple Home control.

**E5 deployed to jarvis (2026-08-05), and the upgrade migration observed.**
Three exported accessories kept endpoint numbers **3, 5 and 4** across a plugin
and bridge-node upgrade — their pre-upgrade values, and deliberately *not* in
creation order, which is what makes the observation worth anything. No duplicates
appeared in Apple Home. That is XAC5's upgrade leg.

**Still outstanding, and it must stay marked so:**

- **Pairing through the plugin's own menu.** E0's pairing was driven from the
node's console. *Pair Matter Bridge…* → the IWS code page → Apple Home has not
been walked end to end.
- **The second-admin / multi-fabric proof** — XAC3's second half. No second
controller has been added alongside Apple Home.
- **XAC5's reboot leg.** A plugin reload and a bridge-node restart have both been
survived; a full Mac reboot has not.
- **E6 and E7 end to end**, which need the install menu and therefore the npm
publish (or the local-install recipe above for a dry run).

### Deferred / not done

- **XAC3's live pairing is unverified.** Every code path is unit-tested, but
nothing here has met a real ecosystem. That is the jarvis script below.
- **XAC3 is PART-verified — do not read this list as "nothing has been
validated".** The pairing gate and live two-way control have both been done on
jarvis (see the section immediately above); what is unverified is pairing
driven from the *plugin's own menu*, and the second-admin half. The jarvis
script below is still the route for those.
- **A locally-opened commissioning window still does not update the
`AdministratorCommissioning` cluster's `windowStatus`/`adminFabricIndex`.**
Unchanged from E5: matter.js 0.17.8's cluster command asserts a remote
Expand All @@ -413,13 +459,21 @@ menu will still try the registry spec.
gives the stop/start seam the E5 note said was missing) but is **not wired**:
`fabric_backup.restore_backup` still reports and skips the `bridge-node/`
members. Wiring it is a small, self-contained follow-up.
- **The published Field Notes site does not know export exists.**
`docs/matter.html` is a hand-built page generated from an earlier `MATTER.md`
and carries **zero** export content, and `docs/index.html`'s standfirst still
offers "two long reads" with no route to the export material or to
`INSTALL.md`. E8 therefore points README's export lede at `docs/MATTER.md`
directly rather than at `matter.html`. **Regenerating both pages is
outstanding**, and until it is done the GitHub Pages site under-sells the
feature to anyone who starts there.
- **Still open from earlier:** #105, #83, #84, #62 follow-up, #43, #46, #21–#24.

### Open, unexplained, and Apple-side: room changes in Apple Home

Observed on jarvis with E5 deployed and 3 accessories live: on/off control works,
but Apple Home refuses to change an accessory's **room** ("can't change
settings"). Simon had changed those same accessories' rooms successfully before,
Observed on jarvis with E5 deployed and 3 accessories live (2026-08-05): on/off
control works, but Apple Home refuses to change an accessory's **room** ("can't
change settings"). Simon had changed those same accessories' rooms successfully before,
so this is a change in Apple-side state, not in bridge behaviour.

**No bridge-side change can address this, and the reasoning matters.** Room
Expand All @@ -435,8 +489,9 @@ presented as a remedy for it.

### Deploying E6 + E7 to jarvis

Nothing in E5, E6 or E7 has been deployed. In order, because each step gates
the next:
**E5 is deployed** (2026-08-05, with three accessories live — see *Live
validation on jarvis* above). **E6 and E7 are not.** In order, because each step
gates the next:

1. **Publish `indigo-matter-bridge@0.5.0`** (above). Without it step 4 fails.
For a dry run, use the local-install workaround instead.
Expand Down
Loading