Skip to content

feat: custom node labels with HA name sync#413

Closed
markvp wants to merge 19 commits intomatter-js:mainfrom
markvp:feat/custom-node-labels
Closed

feat: custom node labels with HA name sync#413
markvp wants to merge 19 commits intomatter-js:mainfrom
markvp:feat/custom-node-labels

Conversation

@markvp
Copy link
Copy Markdown
Contributor

@markvp markvp commented Mar 23, 2026

Summary

Implements custom node labels for matterjs-server (#409), allowing users to assign friendly names to nodes directly in the dashboard — addressing the difficulty of identifying multiple identical devices (e.g. a dozen "GRILLPLATS plug").

  • Server-side custom labels stored in persistent storage, separate from Matter's NodeLabel attribute
  • Home Assistant name sync — pull device names from HA, push label changes back to HA
  • Dashboard UI — pencil edit button on nodes, settings menu with HA integration dialog

Changes

Commit 1: Custom node labels (server-side naming)

  • New set_custom_node_label WS command with persistent storage
  • custom_label field on MatterNode, customLabel getter on ws-client
  • Dashboard: pencil edit icon on node details, labels in node list and network views
  • New input-dialog-box component for text input dialogs
  • getDeviceName() priority: customLabel > nodeLabel > productName
  • 6 ws-client unit tests + 3 integration tests

Commit 2: Server-side Home Assistant name sync

  • HomeAssistantClient — stateless HTTP client for HA REST API
  • Auto-detects HA add-on via SUPERVISOR_TOKEN env var
  • New WS commands: set_ha_credentials, sync_ha_names, push_node_label_to_ha
  • Device matching via HA identifier format deviceid_<fabric>-<node>-<endpoint>
  • ha_url_set field on ServerInfoMessage
  • 7 unit tests for device matching + 3 ws-client command tests

Commit 3: Dashboard UI for HA integration

  • Settings gear now opens a menu (Log Level + Home Assistant)
  • HA integration dialog: URL + token config, "Sync Names from HA" button
  • After editing a label, prompts "Also update in Home Assistant?" if HA configured
  • Server details shows HA integration status

Test plan

  • npm run format && npm run lint && npm run build — all pass
  • ws-client unit tests: 52/52 pass (9 new)
  • HomeAssistantClient unit tests: 7/7 pass
  • Manual: start server, open dashboard, edit a node label via pencil icon
  • Manual: verify label persists across page reload
  • Manual: verify label appears in node list and network views
  • Manual: settings gear opens menu with Log Level and Home Assistant options
  • Manual: HA dialog accepts URL + token, sync button pulls names

Closes #409

🤖 Generated with Claude Code

markvp and others added 3 commits March 24, 2026 04:43
Add ability for users to assign custom labels to nodes, stored
server-side in persistent storage. This addresses the difficulty
of identifying multiple identical devices (e.g. dozen "GRILLPLATS plug")
in the dashboard.

- New `set_custom_node_label` WebSocket command
- Labels stored in ConfigStorage `node-labels` context, persisted across restarts
- Dashboard: pencil edit button on node details, labels shown in node list and network views
- `getDeviceName()` priority: customLabel > nodeLabel > productName
- ws-client: `MatterNode.customLabel` getter and `setCustomNodeLabel()` method
- Unit tests (ws-client) and integration tests for the new command

Closes matter-js#409

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add server-side plumbing for syncing device names between matterjs-server
and Home Assistant. Auto-detects HA add-on environment via SUPERVISOR_TOKEN,
with manual URL+token config for standalone installs.

New WS commands:
- set_ha_credentials: store HA URL + long-lived access token
- sync_ha_names: pull device names from HA device registry → custom labels
- push_node_label_to_ha: push a node's custom label to HA device registry

Also adds:
- HomeAssistantClient: stateless HTTP client for HA REST API
- Device matching via HA identifier format (deviceid_<fabric>-<node>-<endpoint>)
- ha_url_set field on ServerInfoMessage for dashboard awareness
- Unit tests for device matching (7) and WS commands (3)

Dashboard UI for triggering sync will be a separate commit.

Refs matter-js#409

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Settings gear now opens a menu with "Log Level" and "Home Assistant" options
- HA integration dialog: configure URL + token, sync names from HA
- After editing a node label, prompts "Also update in Home Assistant?" if HA is configured
- Server details shows HA integration status

New files:
- ha-integration-dialog.ts: credentials form + sync button
- settings-menu-dialog.ts: replaces direct log-level launch with menu
- show-ha-integration-dialog.ts, show-settings-menu-dialog.ts: show functions

Refs matter-js#409

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 23, 2026 21:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds server-backed custom node labels and Home Assistant name synchronization, with dashboard UI to edit labels and manage HA integration.

Changes:

  • Introduces custom_label support across ws-controller/ws-client, plus a WS command to persistently set/clear labels.
  • Adds a HomeAssistantClient and WS commands to configure HA credentials, sync names from HA, and push label updates back to HA.
  • Updates dashboard UI to edit node labels inline and configure HA integration via a new settings menu/dialogs.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/ws-controller/src/types/WebSocketMessageTypes.ts Extends WS types with custom_label, HA commands, and ha_url_set server info flag
packages/ws-controller/src/server/WebSocketControllerHandler.ts Implements new WS commands, persistence hookup, HA sync/push logic, and node detail augmentation
packages/ws-controller/src/server/HomeAssistantClient.ts Adds HA REST client and device-registry matching utility
packages/ws-controller/src/server/ConfigStorage.ts Persists HA credentials and custom node labels (new storage context)
packages/ws-controller/src/index.ts Exports HomeAssistantClient from ws-controller package
packages/ws-client/test/WsClientTest.ts Adds ws-client tests for new commands and custom_label model behavior
packages/ws-client/src/models/node.ts Adds custom_label field and customLabel getter
packages/ws-client/src/models/model.ts Adds new APICommands and ha_url_set to ws-client types
packages/ws-client/src/client.ts Adds ws-client methods for label set/clear + HA credentials/sync/push commands
packages/matter-server/test/IntegrationTest.ts Adds integration coverage for label set/clear and propagation in events/responses
packages/matter-server/test/HomeAssistantClientTest.ts Adds unit coverage for HA device→node matching logic
packages/dashboard/src/pages/network/network-utils.ts Uses custom label as highest priority name in UI
packages/dashboard/src/pages/matter-server-view.ts Displays customLabel alongside nodeLabel/vendor/product in list
packages/dashboard/src/pages/components/server-details.ts Shows HA integration configured status
packages/dashboard/src/pages/components/node-details.ts Adds label edit UX and optional push-to-HA prompt
packages/dashboard/src/pages/components/header.ts Routes settings gear to new settings menu
packages/dashboard/src/components/dialogs/settings/show-settings-menu-dialog.ts Lazy-loads and mounts settings menu dialog
packages/dashboard/src/components/dialogs/settings/show-ha-integration-dialog.ts Lazy-loads and mounts HA integration dialog
packages/dashboard/src/components/dialogs/settings/settings-menu-dialog.ts New settings menu dialog offering Log Level + Home Assistant
packages/dashboard/src/components/dialogs/settings/ha-integration-dialog.ts New HA credentials/sync dialog
packages/dashboard/src/components/dialog-box/show-dialog-box.ts Adds showInputDialog helper and params type
packages/dashboard/src/components/dialog-box/input-dialog-box.ts New generic text input dialog component

markvp and others added 6 commits March 24, 2026 05:40
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Addresses PR feedback: HA requests had no timeout, so a hung HA endpoint
could block WS command handling indefinitely. Now uses AbortController
with a 30-second default timeout and surfaces a clear error message.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 23, 2026 21:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 6 comments.

- Rename ha_url_set to ha_credentials_set across all packages
- Use Headers object in HomeAssistantClient to prevent Authorization override
- Store endpoint number on HaNodeMatch to simplify preference logic
- Downgrade node label logging from info to debug, omit label value
- Use stable element IDs in ha-integration-dialog instead of label queries

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 23, 2026 23:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.

- Replace setTimeout with deterministic nodes_changed listener in test
- Append settings/HA dialogs to document.body instead of renderRoot
- Change HA status label from "Connected" to "Configured"
- Use fromConfig instead of create when user sets HA credentials, so
  user-provided credentials take effect even under Supervisor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 23, 2026 23:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

- Allow settings menu dialog to close via Escape/scrim click
- Validate nodeId and endpoint are strictly decimal digits before parsing
  to prevent partial numeric matches (e.g. "1abc" → 1)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 24, 2026 00:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.

- Validate node exists before pushing label to HA
- Trim whitespace from custom labels server-side, treat whitespace-only
  as empty (clear)
- Prevent double-submission in input dialog by guarding with resolved
  flag and stopping Enter key propagation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 24, 2026 01:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.

- Fall back to Supervisor client when stored HA credentials are
  cleared/invalid, keeping ha_credentials_set and actual capability
  in sync
- Resolve input dialog promise in _handleClosed to prevent dangling
  awaits when dialog is closed externally

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 24, 2026 02:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.

- Extract #applyCustomLabel helper to centralize custom_label injection
- Fix log wording: "invalid" → "missing" for absent credentials
- Add Clear button to HA integration dialog to allow clearing stored
  credentials

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 24, 2026 02:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 6 comments.

- Replace parentNode!.removeChild with this.remove() in all dialogs
- Add error type guards (instanceof Error) in node-details catch blocks
- Make #applyCustomLabel non-mutating (shallow clone)
- Add URL validation (http/https only) in set_ha_credentials handler
- Remove @cancel=${preventDefault} from ha-integration and input dialogs
- Update HA status labels: "Credentials saved" / "Stored credentials cleared"
- Remove stray console.log in ws-client event handler
- Replace setTimeout with deterministic event listeners in tests
- Downgrade HA URL log from info to debug

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 24, 2026 03:52
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.

- Fix stale comment about Supervisor credential precedence
- Enforce both-or-neither for HA URL/token, trim whitespace
- Batch sync_ha_names: persist all labels first, then broadcast updates
- Add aria-label fallback on input dialog text field for screen readers
- Downgrade push-label log to debug, omit label value from message
- Fix remaining "invalid" → "missing" in comment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markvp markvp requested a review from Copilot March 24, 2026 04:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.

markvp and others added 2 commits March 24, 2026 12:29
- Flip create() to prefer stored config over Supervisor token,
  consistent with set_ha_credentials behavior
- Use String(nodeId) instead of String(node_id) in push handler
  for consistent config key format
- Treat empty/whitespace name_by_user as unset in HA device matching

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@Apollon77 Apollon77 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry but we will not connect the matterjs server with HomeAssistant because the server is also planned to be used as a standalone component. As already discussed in the issue this is not the way to go!

The way to go is to have a way to store node specific meta data in the matterjs-server (maximum short term solution) or better in matter,js when we add more to the controller layer anyway.

I mark the PR now as "request changes", and sure you can gibve it anpther try but I would more love to build the real solution into matter.js because any such special solution just increases the migration efforts

@Apollon77
Copy link
Copy Markdown
Collaborator

if you really have time constrains for this please join the Matter Community sync to discuss these

@Apollon77 Apollon77 closed this Apr 9, 2026
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.

[Feature Request] Custom node labels (Name/Location/Notes)

3 participants