Skip to content

Add Matter (matter.js) support: 8 commissionable device types#5

Draft
HuggeK wants to merge 8 commits into
srcfl:mainfrom
HuggeK:feat/matter-support
Draft

Add Matter (matter.js) support: 8 commissionable device types#5
HuggeK wants to merge 8 commits into
srcfl:mainfrom
HuggeK:feat/matter-support

Conversation

@HuggeK

@HuggeK HuggeK commented Jun 25, 2026

Copy link
Copy Markdown

Draft — functionally complete and tested locally, but needs more testing/validation (Docker, real-ecosystem commissioning, UI polish) before it's ready to merge.

Refs #4.

Summary

Adds Matter (smart-home standard) support so the simulator can emulate commissionable Matter devices and pair them into real ecosystems (Home Assistant, Apple Home, Google). Built on matter.js (@matter/main v0.16.11, Matter 1.4.2).

matter.js is Node.js/TypeScript while this app is pure-Go single-binary, so the core is a Go↔Node bridge: the Go side spawns and supervises a Node child process (NDJSON-over-stdio RPC) that hosts the matter.js ServerNodes. The Go side owns all device physics; the bridge is a thin Matter shim. Conforms to the existing DeviceServer/Automatable abstraction.

Device types (all commissionable, with pairing code + QR)

Temperature sensor, light sensor, smart plug (power + energy), EVSE charger, thermostat, heat pump, dishwasher, washing machine.

Key decisions

  • Node.js is host-provided (v18+, v20+ recommended). Detected at runtime; if absent, Matter is disabled gracefully (GET /api/matter/status) — never a crash. No Node bundled into the binary/Docker image.
  • The bridge + its node_modules are vendored as node_modules.tgz, go:embed-ed and extracted to a cache dir at first run. matter.js logs are pinned to stderr so stdout stays a clean control channel.
  • Devices use the CSA test Vendor ID 0xFFF1 → to pair into Home Assistant you must enable its test/Test-Net DCL (allow uncertified devices). Documented in /docs + CLAUDE.md.

Testing done

  • go test ./... is green with no Node on PATH (CI stays Node-free); real-Node tests are gated behind -tags matter_integration (make test-matter).
  • Integration test (real Node): all 8 device types commission with unique pairing codes; smart-plug energy accrues.
  • Live smoke test of the server-mode Windows binary: created plug/thermostat/temp sensor → unique pairing codes + MT: QR over HTTP; toggled plug + ran automation → power/energy accumulated. (Two HTTP-API gaps found and fixed during this.)

Not yet validated (before un-drafting)

  • Docker image build/run (daemon wasn't available in the test env).
  • Real commissioning into Home Assistant / Apple Home end-to-end.
  • Per-device-card UI rendering of pairing code/QR (data is exposed via the API; create flow + availability gating are wired).
  • Native Wails desktop build (needs a C compiler; CI builds it via MSVC).

Notable files

internal/matter/ (bridge supervisor, RPC, device adapter, physics, detection, embed), internal/matter/bridge/ (Node program + vendored deps), wiring in cmd/simulator/{main,app}.go, ports/settings/state, and docs sync (openapi.json, MCP, /docs, CLAUDE.md).

🤖 Generated with Claude Code

HuggeK and others added 8 commits June 25, 2026 11:48
… support

Introduces the foundational pieces for commissionable Matter device emulation
via matter.js v0.16.11, driven by a supervised Node.js child process.

- internal/matter/bridge: Node bridge (NDJSON-over-stdio RPC) hosting matter.js
  ServerNodes for all 8 device types (temperature/light sensor, smart plug,
  EVSE, thermostat, heat pump, dishwasher, laundry washer). All 8 verified to
  boot cleanly with real pairing codes + QR. Deps vendored as node_modules.tgz.
- matter.js logs pinned to stderr so stdout stays a clean control channel.
- internal/matter Go: types, node detection, NDJSON rpc transport, storage
  paths, and go:embed extraction of the bridge to a cache dir.
- device.ProtocolMatter + CategoryMatter; ports allocator gains matter base.

Refs srcfl#4

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- internal/matter manager.go (process supervision, crash-restart + replay),
  server.go (DeviceServer/Automatable adapter), devicetypes.go (physics +
  cluster mapping for all 8 types), plus unit + tag-gated integration tests.
- Wire matter protocol into createSimulator/restoreSimulator/start/stop/
  generateValues, the Simulator struct, ports allocator, settings, and
  persisted state (matter_type).
- app.go GetSimulators/GetSimulator expose pairing code/QR/commissioned;
  add MatterStatus(); GET /api/matter/status; bridge shutdown on exit.

Integration test (real Node): all 8 device types commission with unique
pairing codes; smart-plug energy accumulates. Default go test ./... stays
Node-free and green.

Refs srcfl#4

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Frontend: 'Matter Devices' category, create-modal buttons for all 8 types
  (gated on /api/matter/status availability), status fetch, protocol badge.
- Docs sync (per CLAUDE.md): openapi.json gains matter_* create types + 400
  and GET /api/matter/status; MCP create tool lists matter types + matter.status
  tool; /docs page gets a Matter section.
- Document the CSA test Vendor ID (0xFFF1) / DCL test-net requirement: to pair
  into Home Assistant you must enable its test/Test-Net DCL (allow uncertified
  devices); Apple/Google warn about uncertified accessories.
- Makefile: vendor-matter (repackage node_modules.tgz) and test-matter
  (-tags matter_integration) targets. settings/state gain matter base port +
  matter_type persistence.

Refs srcfl#4

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The HTTP handlers (server mode) built their own responses and only handled
mqtt/ocpp. Add the matter case to the simulator list + detail endpoints
(pairing_code, qr, commissioned, bridge_up, device state) and to the /state
endpoint so Matter devices can be controlled (toggle plug, setpoints, start
cycle) over HTTP, matching the Wails bindings. Found via live testing of the
server-mode binary.

Refs srcfl#4

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Server mode now logs 'Open the web UI: http://localhost:<port>' (plus the LAN
URL) so the dashboard is one click away from the terminal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant