@matter-server/dashboard 1.2.7 → 1.2.8-alpha.0-20260718-c874702

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/esm/components/webrtc-stream-view.d.ts +1 -0
  2. package/dist/esm/components/webrtc-stream-view.d.ts.map +1 -1
  3. package/dist/esm/components/webrtc-stream-view.js +11 -1
  4. package/dist/esm/components/webrtc-stream-view.js.map +1 -1
  5. package/dist/esm/pages/camera-overlay.d.ts +1 -0
  6. package/dist/esm/pages/camera-overlay.d.ts.map +1 -1
  7. package/dist/esm/pages/camera-overlay.js +13 -2
  8. package/dist/esm/pages/camera-overlay.js.map +1 -1
  9. package/dist/esm/pages/components/node-details.d.ts.map +1 -1
  10. package/dist/esm/pages/components/node-details.js +9 -10
  11. package/dist/esm/pages/components/node-details.js.map +1 -1
  12. package/dist/esm/pages/network/update-connections-dialog.d.ts.map +1 -1
  13. package/dist/esm/pages/network/update-connections-dialog.js +1 -1
  14. package/dist/esm/pages/network/update-connections-dialog.js.map +1 -1
  15. package/dist/esm/util/device-icons.d.ts +2 -0
  16. package/dist/esm/util/device-icons.d.ts.map +1 -1
  17. package/dist/esm/util/device-icons.js +6 -0
  18. package/dist/esm/util/device-icons.js.map +1 -1
  19. package/dist/web/js/{attribute-write-dialog-CtEW9qD_.js → attribute-write-dialog-CB7oucjt.js} +1 -1
  20. package/dist/web/js/{command-invoke-dialog-D7KF-xwE.js → command-invoke-dialog-C9rdQjTo.js} +1 -1
  21. package/dist/web/js/{commission-node-dialog-Co9T2m1_.js → commission-node-dialog-BwkiZy8i.js} +5 -5
  22. package/dist/web/js/{commission-node-existing-Vcsia5Qz.js → commission-node-existing-BWTlMlwi.js} +1 -1
  23. package/dist/web/js/{commission-node-thread-CCb6UUm_.js → commission-node-thread-WDo3_tCy.js} +1 -1
  24. package/dist/web/js/{commission-node-wifi-7CGfcbm9.js → commission-node-wifi-Drj7Z0rY.js} +1 -1
  25. package/dist/web/js/{dialog-box-CN_Qk_4S.js → dialog-box-Dq6fTPQH.js} +1 -1
  26. package/dist/web/js/{fabric-label-dialog-Bh6yCaOl.js → fabric-label-dialog-FE4tGieS.js} +1 -1
  27. package/dist/web/js/main.js +4 -3
  28. package/dist/web/js/{matter-dashboard-app-DLe-yfrV.js → matter-dashboard-app-Ditf9BYC.js} +410 -386
  29. package/dist/web/js/{node-acl-add-dialog-IyD1EoTu.js → node-acl-add-dialog-BA3u0qYj.js} +1 -1
  30. package/dist/web/js/{node-binding-dialog-CahBxL34.js → node-binding-dialog-BV_fMc0a.js} +1 -1
  31. package/dist/web/js/{node-label-dialog-Xu8QQuQX.js → node-label-dialog-DG5CqG1e.js} +1 -1
  32. package/dist/web/js/{settings-dialog-BU2nn7IQ.js → settings-dialog-VafGbl7R.js} +1 -1
  33. package/package.json +3 -3
  34. package/src/components/webrtc-stream-view.ts +10 -1
  35. package/src/pages/camera-overlay.ts +14 -2
  36. package/src/pages/components/node-details.ts +9 -10
  37. package/src/pages/network/update-connections-dialog.ts +4 -3
  38. package/src/util/device-icons.ts +7 -0
@@ -1,4 +1,4 @@
1
- import { i, c, a as clientContext, n, r, b as i$1, P as Privilege, v as nodeIdKey, x as aclCapacity, s as showAlertDialog, y as targetServerClusters, z as clusters, B as AuthMode, C as addAclEntry, E as PRIVILEGE_NAMES, d as b, F as mdiClose, G as getDeviceName, h as handleAsync, g as t } from './matter-dashboard-app-DLe-yfrV.js';
1
+ import { i, c, a as clientContext, n, r, b as i$1, P as Privilege, v as nodeIdKey, x as aclCapacity, s as showAlertDialog, y as targetServerClusters, z as clusters, B as AuthMode, C as addAclEntry, E as PRIVILEGE_NAMES, d as b, F as mdiClose, G as getDeviceName, h as handleAsync, g as t } from './matter-dashboard-app-Ditf9BYC.js';
2
2
  import { p as preventDefault } from './prevent_default-D-ohDGsN.js';
3
3
  import './main.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { i, c, a as clientContext, n, r, b as i$1, v as nodeIdKey, z as clusters, s as showAlertDialog, H as targetAclCapacityForBinding, I as addBinding, J as bindableClusters, A, d as b, G as getDeviceName, K as getEndpointDeviceTypes, h as handleAsync, g as t } from './matter-dashboard-app-DLe-yfrV.js';
1
+ import { i, c, a as clientContext, n, r, b as i$1, v as nodeIdKey, z as clusters, s as showAlertDialog, H as targetAclCapacityForBinding, I as addBinding, J as bindableClusters, A, d as b, G as getDeviceName, K as getEndpointDeviceTypes, h as handleAsync, g as t } from './matter-dashboard-app-Ditf9BYC.js';
2
2
  import { p as preventDefault } from './prevent_default-D-ohDGsN.js';
3
3
  import './main.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { r, n, g as t, b as i, M as MAX_NODE_LABEL_LENGTH, d as b, w as writeNodeLabel, s as showAlertDialog } from './matter-dashboard-app-DLe-yfrV.js';
1
+ import { r, n, g as t, b as i, M as MAX_NODE_LABEL_LENGTH, d as b, w as writeNodeLabel, s as showAlertDialog } from './matter-dashboard-app-Ditf9BYC.js';
2
2
  import { p as preventDefault } from './prevent_default-D-ohDGsN.js';
3
3
  import './main.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { i, c, a as clientContext, t as tickContext, r, e, b as i$1, f as fireAndForget, s as showAlertDialog, d as b, A, h as handleAsync, g as t, n, D as DevModeService, m as mdiWifi, j as mdiPlus, k as mdiPencil, l as mdiDelete, o as mdiEyeOff, p as mdiEye, q as mdiAccessPoint } from './matter-dashboard-app-DLe-yfrV.js';
1
+ import { i, c, a as clientContext, t as tickContext, r, e, b as i$1, f as fireAndForget, s as showAlertDialog, d as b, A, h as handleAsync, g as t, n, D as DevModeService, m as mdiWifi, j as mdiPlus, k as mdiPencil, l as mdiDelete, o as mdiEyeOff, p as mdiEye, q as mdiAccessPoint } from './matter-dashboard-app-Ditf9BYC.js';
2
2
  import { p as preventDefault } from './prevent_default-D-ohDGsN.js';
3
3
  import './main.js';
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matter-server/dashboard",
3
- "version": "1.2.7",
3
+ "version": "1.2.8-alpha.0-20260718-c874702",
4
4
  "description": "Dashboard for OHF Matter Server",
5
5
  "homepage": "https://github.com/matter-js/matterjs-server",
6
6
  "bugs": {
@@ -34,8 +34,8 @@
34
34
  "dependencies": {
35
35
  "@lit/context": "^1.1.6",
36
36
  "@material/web": "^2.4.1",
37
- "@matter-server/custom-clusters": "1.2.7",
38
- "@matter-server/ws-client": "1.2.7",
37
+ "@matter-server/custom-clusters": "1.2.8-alpha.0-20260718-c874702",
38
+ "@matter-server/ws-client": "1.2.8-alpha.0-20260718-c874702",
39
39
  "@mdi/js": "^7.4.47",
40
40
  "lit": "^3.3.3",
41
41
  "qrcode-generator": "^2.0.4",
@@ -188,6 +188,7 @@ export class WebRtcStreamView extends LitElement {
188
188
 
189
189
  @property({ attribute: false }) nodeId!: number | bigint;
190
190
  @property({ type: Number }) endpointId!: number;
191
+ @property({ type: Boolean }) liveViewSupported = true;
191
192
  @property({ type: Object }) resolution: { width: number; height: number } | null = null;
192
193
 
193
194
  @property({ type: Boolean }) watermarkEnabled = false;
@@ -253,7 +254,11 @@ export class WebRtcStreamView extends LitElement {
253
254
  ${this._state === "idle"
254
255
  ? html`<div class="placeholder">
255
256
  <ha-svg-icon class="placeholder-icon" .path=${mdiVideoOutline}></ha-svg-icon>
256
- <div class="placeholder-text">Click <b>Start</b> to begin streaming</div>
257
+ <div class="placeholder-text">
258
+ ${this.liveViewSupported
259
+ ? html`Click <b>Start</b> to begin streaming`
260
+ : "Live view not supported — use Snapshot"}
261
+ </div>
257
262
  </div>`
258
263
  : null}
259
264
  ${this._state === "connecting"
@@ -272,6 +277,10 @@ export class WebRtcStreamView extends LitElement {
272
277
  }
273
278
 
274
279
  async start(): Promise<void> {
280
+ if (!this.liveViewSupported) {
281
+ this._fireStateChange("error", "Live view is not supported on this device");
282
+ return;
283
+ }
275
284
  if (!this.client) throw new Error("Matter client not available");
276
285
  if (this._state === "connecting" || this._state === "streaming") return;
277
286
 
@@ -28,6 +28,8 @@ import "../components/webrtc-stream-view.js";
28
28
  import type { WebRtcStreamView } from "../components/webrtc-stream-view.js";
29
29
  import { asObject, pickNumber } from "../util/attribute-shapes.js";
30
30
  import { hasAvsumOnEndpoint } from "../util/avsum.js";
31
+ import { LIVE_VIEW_DEVICE_TYPE_IDS } from "../util/device-icons.js";
32
+ import { getEndpointDeviceTypes } from "../util/endpoints.js";
31
33
 
32
34
  type StreamState = "idle" | "connecting" | "streaming" | "error";
33
35
 
@@ -73,6 +75,13 @@ export class CameraOverlay extends LitElement {
73
75
  @state() private _snapshotResolutions: Resolution[] = [];
74
76
  @state() private _selectedSnapshotResolution: Resolution | null = null;
75
77
 
78
+ private get _liveViewSupported(): boolean {
79
+ const node = this.client?.nodes[String(this.nodeId)];
80
+ if (!node) return false;
81
+ const deviceTypeIds = getEndpointDeviceTypes(node, this.endpointId).map(d => d.id);
82
+ return LIVE_VIEW_DEVICE_TYPE_IDS.some(id => deviceTypeIds.includes(id));
83
+ }
84
+
76
85
  private get _snapshotSupported(): boolean {
77
86
  const node = this.client?.nodes[String(this.nodeId)];
78
87
  // CaptureSnapshot (cmd 12) must appear in AcceptedCommandList (attr 0xfff9 = 65529).
@@ -276,7 +285,9 @@ export class CameraOverlay extends LitElement {
276
285
  }
277
286
 
278
287
  override render() {
279
- const canStart = this._state === "idle" || this._state === "error";
288
+ const liveViewSupported = this._liveViewSupported;
289
+ const idleOrError = this._state === "idle" || this._state === "error";
290
+ const canStart = liveViewSupported && idleOrError;
280
291
 
281
292
  return html`
282
293
  <div class="backdrop" @click=${this._closing ? undefined : this._close}></div>
@@ -301,6 +312,7 @@ export class CameraOverlay extends LitElement {
301
312
  ${ref(this._streamViewRef)}
302
313
  .nodeId=${this.nodeId}
303
314
  .endpointId=${this.endpointId}
315
+ .liveViewSupported=${liveViewSupported}
304
316
  .resolution=${this._selectedResolution}
305
317
  .watermarkEnabled=${this._watermarkEnabled}
306
318
  .osdEnabled=${this._osdEnabled}
@@ -359,7 +371,7 @@ export class CameraOverlay extends LitElement {
359
371
  </md-outlined-select>
360
372
  `
361
373
  : nothing}
362
- ${canStart && this._snapshotSupported && this._snapshotResolutions.length > 0
374
+ ${idleOrError && this._snapshotSupported && this._snapshotResolutions.length > 0
363
375
  ? html`
364
376
  <md-outlined-select
365
377
  label="Snapshot"
@@ -13,7 +13,7 @@ import "@material/web/list/list";
13
13
  import "@material/web/list/list-item";
14
14
  import { consume } from "@lit/context";
15
15
  import { MatterClient, MatterNode, UpdateSource } from "@matter-server/ws-client";
16
- import { mdiChatProcessing, mdiPencil, mdiShareVariant, mdiTrashCan, mdiUpdate, mdiVideo } from "@mdi/js";
16
+ import { mdiCamera, mdiChatProcessing, mdiPencil, mdiShareVariant, mdiTrashCan, mdiUpdate, mdiVideo } from "@mdi/js";
17
17
  import { LitElement, css, html, nothing } from "lit";
18
18
  import { customElement, property, state } from "lit/decorators.js";
19
19
  import { clientContext, tickContext } from "../../client/client-context.js";
@@ -23,18 +23,13 @@ import { showNodeLabelDialog } from "../../components/dialogs/node-label-dialog/
23
23
  import { handleAsync } from "../../util/async-handler.js";
24
24
  import "../../components/ha-svg-icon";
25
25
  import "../camera-overlay.js";
26
- import { DeviceTypes, getDeviceIcon } from "../../util/device-icons.js";
26
+ import { DeviceTypes, LIVE_VIEW_DEVICE_TYPE_IDS, getDeviceIcon } from "../../util/device-icons.js";
27
27
  import { getEndpointDeviceTypes } from "../../util/endpoints.js";
28
28
  import { ICD_CLUSTER_ID, icdBadge } from "../../util/icd.js";
29
29
  import { formatManualPairingCode, renderPairingQrCodeDataUri } from "../../util/pairing-code.js";
30
30
  import { bindingContext } from "./context.js";
31
31
 
32
- const CAMERA_DEVICE_TYPE_IDS: number[] = [
33
- DeviceTypes.CAMERA,
34
- DeviceTypes.VIDEO_DOORBELL,
35
- DeviceTypes.FLOODLIGHT_CAMERA,
36
- DeviceTypes.SNAPSHOT_CAMERA,
37
- ];
32
+ const CAMERA_DEVICE_TYPE_IDS: number[] = [...LIVE_VIEW_DEVICE_TYPE_IDS, DeviceTypes.SNAPSHOT_CAMERA];
38
33
 
39
34
  /** Map updateState values to user-friendly labels */
40
35
  const UPDATE_STATE_LABELS: Record<number, string> = {
@@ -89,6 +84,7 @@ export class NodeDetails extends LitElement {
89
84
 
90
85
  const deviceTypeIds = getEndpointDeviceTypes(this.node, this.endpoint).map(d => d.id);
91
86
  const isCamera = CAMERA_DEVICE_TYPE_IDS.some(id => deviceTypeIds.includes(id));
87
+ const isLiveViewCamera = LIVE_VIEW_DEVICE_TYPE_IDS.some(id => deviceTypeIds.includes(id));
92
88
  const badge = icdBadge(this.node.attributes, this.node.available);
93
89
 
94
90
  return html`
@@ -170,8 +166,11 @@ export class NodeDetails extends LitElement {
170
166
  @click=${() => this._openCameraOverlay()}
171
167
  ?disabled=${!this.node.available}
172
168
  >
173
- Live View
174
- <ha-svg-icon slot="icon" .path=${mdiVideo}></ha-svg-icon>
169
+ ${isLiveViewCamera ? "Live View" : "Snapshot"}
170
+ <ha-svg-icon
171
+ slot="icon"
172
+ .path=${isLiveViewCamera ? mdiVideo : mdiCamera}
173
+ ></ha-svg-icon>
175
174
  </md-outlined-button>
176
175
  `
177
176
  : nothing}
@@ -146,11 +146,12 @@ export class UpdateConnectionsDialog extends LitElement {
146
146
  const paths = this._getAttributePathsForNode(nodeIdStr);
147
147
  if (paths.length === 0) return;
148
148
 
149
- // Use the actual node_id from the node object (number | bigint)
150
- await this.client.readAttribute(node.node_id, paths);
149
+ // fabric_filtered must match the node subscription's filter (true), else matter.js
150
+ // discards the read and no attribute_updated fires, leaving the store stale.
151
+ await this.client.readAttribute(node.node_id, paths, undefined, true);
151
152
  });
152
153
 
153
- // Wait for all to complete (results come via events, we just need completion)
154
+ // Return values are discarded; refreshed data arrives via attribute_updated events.
154
155
  await Promise.all(updatePromises);
155
156
 
156
157
  // Close dialog on success
@@ -189,6 +189,13 @@ export const DeviceTypes = {
189
189
  INTERCOM: 0x0140,
190
190
  };
191
191
 
192
+ /** Device types whose mandatory clusters include WebRTCTransportProvider (0x553), i.e. support live streaming. */
193
+ export const LIVE_VIEW_DEVICE_TYPE_IDS: readonly number[] = Object.freeze([
194
+ DeviceTypes.CAMERA,
195
+ DeviceTypes.VIDEO_DOORBELL,
196
+ DeviceTypes.FLOODLIGHT_CAMERA,
197
+ ]);
198
+
192
199
  /**
193
200
  * Maps device type IDs to MDI icon paths.
194
201
  */