-
Notifications
You must be signed in to change notification settings - Fork 2
feat(export): E6+E7 — pairing UX, fabric management, bridge LaunchAgent [no-release] #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| # indigo-matter-bridge | ||
|
|
||
| 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. | ||
|
|
||
| > **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: | ||
| > the plugin decides *what* to export and the node makes it a Matter accessory. | ||
| > Install the Indigo plugin; it installs and manages this package for you, via | ||
| > its own **Plugins ▸ Matter ▸ Install/update the Matter export bridge** menu | ||
| > item and a launchd LaunchAgent it writes. | ||
|
|
||
| ## Why it is a separate process | ||
|
|
||
| matter.js is imported **here and nowhere else**. Indigo plugins are Python, and | ||
| the alternative — a Node shim inside the plugin, or a second Matter stack — buys | ||
| two versions of the specification and a second place for accessory identity to | ||
| drift. The plugin talks to this node over a loopback WebSocket with a versioned | ||
| JSON protocol, and refuses to attach on a version mismatch rather than guessing. | ||
|
|
||
| The contract is | ||
| [`docs/BRIDGE_PROTOCOL.md`](https://github.com/simons-plugins/indigo-matter/blob/main/docs/BRIDGE_PROTOCOL.md) | ||
| in the plugin repository. It is a real contract: both sides' test suites assert | ||
| against one shared file of golden frames, so a frame that changes on one side | ||
| fails the other side's tests. | ||
|
|
||
| ## Running it by hand | ||
|
|
||
| Normally the plugin's LaunchAgent does this. For development: | ||
|
|
||
| ```sh | ||
| node dist/main.js \ | ||
| --storage-path ~/Library/Application\ Support/com.simons-plugins.indigo-matter/bridge-node \ | ||
| --ws-port 5581 \ | ||
| --matter-port 5540 \ | ||
| [--mdns-interface en0] | ||
| ``` | ||
|
|
||
| Every flag is validated and the node **refuses to start** on a value it cannot | ||
| parse, rather than silently running somewhere unexpected — including a flag given | ||
| with no value. | ||
|
|
||
| | Flag | Meaning | | ||
| |---|---| | ||
| | `--storage-path` | Where identity, fabrics and the endpoint-number map live. **Sacred**: losing it un-pairs every ecosystem and duplicates every accessory. | | ||
| | `--ws-port` | The loopback protocol port the plugin dials (default 5581). | | ||
| | `--matter-port` | The Matter UDP port to advertise on (default 5540). | | ||
| | `--mdns-interface` | Pin mDNS to one interface. Omit to let matter.js choose; on a Mac with VPN/utun interfaces, pinning is usually necessary. | | ||
|
|
||
| The node writes its own log to stdout/stderr. Under the plugin's LaunchAgent that | ||
| is `~/Library/Logs/indigo-matter/bridge-node.log` and `bridge-node.err.log`. | ||
|
|
||
| ## Storage | ||
|
|
||
| Two files in `--storage-path`, alongside matter.js's own store: | ||
|
|
||
| * **`identity.json`** — install id, commissioning passcode and discriminator, | ||
| plus a witness recording that the bridge has been commissioned at least once. | ||
| An unreadable one is moved aside and a replacement minted **in memory only**: | ||
| the `SerialNumber`/`UniqueID` every paired ecosystem knows are never | ||
| overwritten. | ||
| * **`endpoint-map.json`** — the persisted `UniqueID → endpoint number` map. It | ||
| allocates nothing (matter.js owns the numbers); it is an independent *witness*, | ||
| so a lost or reset matter.js store becomes a log line instead of silently | ||
| duplicating every accessory in every ecosystem. Drift is reported and never | ||
| repaired automatically — repairing it would call the same fault clean on the | ||
| next pass. | ||
|
|
||
| Back both up. The plugin's **Export fabric backup…** menu item covers them. | ||
|
|
||
| ## Uncertified by design | ||
|
|
||
| The bridge advertises with the specification's **test vendor id** (`0xFFF1`), so | ||
| every ecosystem shows an "uncertified accessory" warning when you add it. That is | ||
| normal and expected — Homebridge and Home Assistant produce the same warning — | ||
| and choosing "Add Anyway" is the intended path. Matter certification is a paid, | ||
| per-product process that a self-hosted bridge cannot meaningfully complete. | ||
|
|
||
| ## Development | ||
|
|
||
| ```sh | ||
| npm install | ||
| npm run build # tsc | ||
| npm test # builds, copies the shared golden frames, runs node --test | ||
| ``` | ||
|
|
||
| The test suite includes an integration file that stands up a **real** | ||
| `ServerNode` on a real Matter stack behind a real WebSocket server, because the | ||
| faults worth catching here (a role factory that builds but writes the wrong | ||
| attribute; a bridged child publishing the wrong manufacturer) cannot fail against | ||
| a stub. | ||
|
|
||
| ## Licence | ||
|
|
||
| MIT. Not affiliated with Perceptive Automation, the Connectivity Standards | ||
| Alliance, Apple, Amazon, Google or Samsung. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Describe the lifecycle trigger as the allow-list transition.
ExportBridgecan receive the transition from Indigo callbacks, not only from the configuration dialog. The plugin context describes_start_bridge_agentas running on whichever Indigo thread changed the allow-list. Replace “the dialog’s empty↔non-empty transitions” with “the allow-list’s empty↔non-empty transitions” so the documentation covers non-dialog changes.🤖 Prompt for AI Agents