indigo-matter · Field Notes № 3 — The bridge github / simons-plugins / indigo-matter

Matter out — the bridge

The same plugin, run backwards. Indigo devices you choose — Z-Wave, Insteon, Zigbee, MQTT, anything with a device record — published as one Matter bridge accessory, locally, with no cloud relay and no separate bridge app per ecosystem.

Apple Home · validated Multi-admin · validated Read the honest position: § 05 — where this has been proven
§ 01

The other direction

Everything in № 2 is Indigo as a Matter controller: other people’s devices becoming Indigo devices. The plugin runs the arrangement backwards too. The very same plugin that joins your ecosystems as a second admin can just as easily be the one that gets joined — so Apple Home sees and controls a set of Indigo devices like any other Matter accessory.

If you’ve run Homebridge, this is the same idea over Matter’s protocol instead of HomeKit’s — one implementation reaching every ecosystem that speaks it, rather than one bridge per ecosystem.The share model, inverted

Exporting is opt-in, per device, and starts from nothing: a fresh install exports zero devices, pairs nothing, and runs no bridge process at all.

§ 02

Architecture in brief

Three facts explain most of the design.

  • The bridge is a separate process. A small Node service, installed and supervised by the plugin, is the only place matter.js is imported — the Python plugin never links a Matter stack, and the two halves talk over a loopback WebSocket with a versioned protocol that fails closed on skew.
  • The allow-list is empty by default. Nothing is exported until you say so, and the bridge process only exists while the list is non-empty. Emptying the list stops the process again.
  • Roles are declared by you, not guessed. Indigo doesn’t record what a device is — a relay could be a lamp, a plug or a lock — so you pick, and the dialog defaults to the safest reading.

You build the list in Plugins ▸ Matter ▸ Manage Matter Exports…. The picker marks anything already exported with a , and shows devices that can’t be exported too, with the reason, rather than leaving you to wonder where they went.

What your device can become — the outbound mapping, v1
Your Indigo deviceRoles offered (default first)Appears in ecosystems as
Relay Plug · Light · Lock On/Off Plug-in Unit · On/Off Light · Door Lock
Dimmer Dimmable light · Window covering Dimmable Light · Window Covering
Dimmer, colour-temperature capable Colour-temperature light · Dimmable light · Window covering Color Temperature Light · Dimmable Light · Window Covering
Dimmer, full colour Full-colour light · Dimmable light · Colour-temperature light · Window covering Extended Color Light · Dimmable Light · Color Temperature Light · Window Covering
Sensor, on/off Occupancy · Contact Occupancy Sensor · Contact Sensor
Sensor, numeric Temperature · Humidity · Light (lux) · Pressure · Flow — the default is guessed from the device’s units, and you can correct it the matching Matter sensor type
Thermostat Thermostat Thermostat — setpoints and modes; no fan in v1

Window covering appears under every dimmer because Indigo represents blinds as dimmers. An exported position always means 100 % = fully open in your ecosystem app (the bridge handles Matter’s own inverted attribute for you), and a per-export tick-box flips it if your hardware runs the other way. Locks pass commands to Indigo and confirm nothing optimistically — what the ecosystem shows moves only when the bolt actually moves. What can’t be exported — valves and garage doors as roles (the relay itself stays exportable as a plug), fans, sprinklers — is listed with the reason for each in MATTER.html; the one thing filtered out of the picker entirely is this plugin’s own Matter devices, so a Matter device is never re-exported over Matter.

Installing the Node half is one menu item — Install/update the Matter bridge — after which the plugin writes a launchd job that starts, stops and restarts the process for you. You never start it by hand.

§ 03

Pairing the bridge into an ecosystem

Pairing happens once per ecosystem, not once per device — export something new later and it appears in every ecosystem you’ve already paired, with no further action.

  1. Export at least one device first. The bridge process only exists while the export list is non-empty — there’s nothing to pair against an empty list.
  2. Open a pairing window. Plugins ▸ Matter ▸ Pair Matter Bridge…. Indigo’s own dialogs can’t display a value their own button just computed, so the code doesn’t appear in the dialog — it goes to the Event Log, alongside a link to a page, served over Indigo’s own web server, that shows the same code large enough to read across a room, plus a QR payload.
  3. Add the accessory in Apple Home, entering the code by hand. It’s found as Indigo Matter Bridge — and immediately flagged as an uncertified accessory.
  4. Choose Add Anyway. See below for why that’s the right call, every time.
Expected behaviour Why every ecosystem calls the bridge “uncertified”. Matter attestation runs one way — the commissioner checks the device’s certificate — and out here the bridge is the device. It advertises with the specification’s test vendor ID, the same posture Homebridge, matterbridge and Home Assistant’s own bridge all ship with. A real CSA vendor ID needs paid membership and per-product certification, which isn’t proportionate for a free plugin — so the warning is permanent, not a bug to chase.

To add a second ecosystem, open another pairing window: each admin needs its own freshly derived code. To remove one, Unpair an Ecosystem… lists the fabrics the bridge currently serves and drops the one you pick, leaving the rest alone.

§ 04

Accessory identity, and why restarts don’t duplicate anything

Every exported device gets a stable identity tied to its Indigo device ID, and a Matter endpoint number allocated once against that identity — never from its position in a list. Ecosystems remember both: the name you gave the accessory, the room you put it in, the scenes and automations you built on it are all keyed to the identity, not the name.

The endpoint numbers are matter.js’s. The bridge’s own record is a witness, not an allocator — it notices when something’s wrong; it never repairs it, and it never hands out numbers of its own.Why restarts are safe

That witness record is also what makes a restart harmless. Reboots, plugin upgrades and crash recoveries used to leave the bridge briefly showing ecosystems an empty accessory list, and Apple would treat whatever came back as brand new, stuck in the bridge’s own room. The bridge now rebuilds its accessory list from disk before it ever goes back online, so a restart shows ecosystems accessories that were briefly unavailable, not accessories that vanished — and even a full pairing reset, which used to trip a false drift alarm on the witness record, now just quietly adopts the fresh numbers matter.js hands out.

When something does go wrong there are two recovery actions rather than a reinstall: Rebuild Matter Endpoint Map… reconstructs the witness record from matter.js’s own numbers, and Reset Matter Bridge Pairings… factory-resets the bridge so every ecosystem must pair again. Fabric backups cover the bridge node’s identity too, so a restore brings back the accessory identities along with the controller fabric.

§ 05

Where this has actually been proven

The export half is newer than the controller half, and the claims here are deliberately narrow. What follows is the whole of it, as of 6 August 2026.

Bridge validation record
WhatPosition
Pairing from the plugin’s own menu Pair Matter Bridge… → code in the Event Log → added in Apple Home, uncertified prompt accepted, exported devices controllable. validated
A second controller alongside Apple Home Alexa commissioned as a third fabric on the live bridge, concurrently with Apple Home. This is the multi-admin proof ADR-0007 sets as the bar for the export half, and the bar is met. validated
Alexa, in day-to-day use Pairing and control both work — with one known caveat, below. validated, with a caveat
Google Home & SmartThings Never tested here, and therefore not claimed — neither supported nor unsupported. The first user report settles it.
The one-click managed install The whole chain, unattended: npm install → LaunchAgent plist → launchd → node online → attach → reconcile. validated
Accessory identity across a reboot The identity machinery of § 04 has not yet been exercised across a full reboot of the Indigo Mac. That leg is outstanding — treat it as untested until it is done.
The Alexa caveat — issue #143 A device exported after Alexa was already paired can show as stale or unresponsive in the Alexa app for some minutes before it converges. Apple Home picks the same change up promptly; Alexa gets there in the end. If a newly exported accessory looks dead in Alexa, give it a few minutes before assuming anything is broken — issue #143 tracks it.

So, plainly: Apple Home is validated end to end. Alexa is validated for pairing and control, with the convergence caveat above. Google Home and SmartThings are untested and unclaimed. Nothing on this page should be read as a promise about an ecosystem that isn’t named in that sentence — and a report of any ecosystem working, or refusing, is genuinely useful: file it here.

Underneath the field record, the bridge node carries its own automated suite — 405 tests, including integration tests against a real matter.js ServerNode — and shares a golden set of protocol frames with the plugin’s Python suite so the two halves can’t drift apart silently. That story is № 4 — The Proving Ground.

§ 06

Where to go next

This page is the shape of it. The plugin itself installs from the Indigo Plugin Store; everything after that — installing the bridge package, exporting your first device, opening a pairing window, the recovery actions, the troubleshooting tables — is in INSTALL.md. For the full prose on what can and can’t be exported and why, and the fabric mechanics, see MATTER.md. The loopback wire contract between the two halves is documented in BRIDGE_PROTOCOL.md.