@matterbridge/core 3.10.10-dev-20260912-2c1c047 → 3.10.10-dev-20260914-784e019

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 (36) hide show
  1. package/dist/behaviors/cameraAvSettingsUserLevelManagementServer.d.ts +1 -0
  2. package/dist/behaviors/cameraAvSettingsUserLevelManagementServer.js +2 -3
  3. package/dist/behaviors/cameraAvStreamManagementServer.d.ts +1 -0
  4. package/dist/behaviors/cameraAvStreamManagementServer.js +11 -12
  5. package/dist/behaviors/chimeServer.d.ts +2 -1
  6. package/dist/behaviors/chimeServer.js +2 -2
  7. package/dist/behaviors/colorControlServer.d.ts +2 -0
  8. package/dist/behaviors/colorControlServer.js +18 -0
  9. package/dist/behaviors/levelControlServer.d.ts +3 -1
  10. package/dist/behaviors/levelControlServer.js +9 -0
  11. package/dist/behaviors/onOffServer.d.ts +2 -0
  12. package/dist/behaviors/onOffServer.js +6 -0
  13. package/dist/behaviors/webRtcTransportProviderServer.d.ts +2 -1
  14. package/dist/behaviors/webRtcTransportProviderServer.js +8 -8
  15. package/dist/behaviors/webRtcTransportRequestorServer.d.ts +2 -1
  16. package/dist/behaviors/webRtcTransportRequestorServer.js +5 -5
  17. package/dist/behaviors/weriftSession.d.ts +2 -0
  18. package/dist/behaviors/weriftSession.js +25 -1
  19. package/dist/demoDevices.js +64 -0
  20. package/dist/devices/camera/export.d.ts +9 -0
  21. package/dist/devices/camera/export.js +9 -0
  22. package/dist/devices/cameraController.d.ts +8 -0
  23. package/dist/devices/cameraController.js +35 -0
  24. package/dist/devices/floodlightCamera.d.ts +4 -2
  25. package/dist/devices/floodlightCamera.js +7 -6
  26. package/dist/devices/videoDoorbell.d.ts +4 -2
  27. package/dist/devices/videoDoorbell.js +7 -6
  28. package/dist/helpers.d.ts +1 -0
  29. package/dist/helpers.js +26 -0
  30. package/dist/matterbridge.js +9 -20
  31. package/dist/matterbridgeEndpoint.d.ts +5 -1
  32. package/dist/matterbridgeEndpoint.js +9 -4
  33. package/dist/matterbridgeEndpointHelpers.d.ts +1 -1
  34. package/dist/matterbridgeEndpointHelpers.js +0 -5
  35. package/dist/matterbridgePlatform.js +1 -1
  36. package/package.json +9 -5
@@ -9,6 +9,7 @@ declare const MatterbridgeCameraAvSettingsUserLevelManagementServer_base: import
9
9
  mechanicalZoom: true;
10
10
  }>, import("@matter/types").ClusterType.Concrete, new () => {}, "cameraAvSettingsUserLevelManagement">;
11
11
  export declare class MatterbridgeCameraAvSettingsUserLevelManagementServer extends MatterbridgeCameraAvSettingsUserLevelManagementServer_base {
12
+ readonly endpoint: MatterbridgeEndpoint;
12
13
  mptzSetPosition(request: CameraAvSettingsUserLevelManagement.MptzSetPositionRequest): void;
13
14
  mptzRelativeMove(request: CameraAvSettingsUserLevelManagement.MptzRelativeMoveRequest): void;
14
15
  }
@@ -1,7 +1,6 @@
1
1
  import { CameraAvSettingsUserLevelManagementServer } from '@matter/node/behaviors/camera-av-settings-user-level-management';
2
2
  import { Status, StatusResponseError } from '@matter/types';
3
3
  import { CameraAvSettingsUserLevelManagement } from '@matter/types/clusters/camera-av-settings-user-level-management';
4
- import { emitCommand } from '../matterbridgeEndpointHelpers.js';
5
4
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
5
  function clamp(value, min, max) {
7
6
  return Math.min(Math.max(value, min), max);
@@ -28,7 +27,7 @@ export class MatterbridgeCameraAvSettingsUserLevelManagementServer extends Camer
28
27
  zoom: zoom ?? this.state.mptzPosition.zoom,
29
28
  };
30
29
  device.log.info(`MatterbridgeCameraAvSettingsUserLevelManagementServer: set mechanical PTZ position to pan ${this.state.mptzPosition.pan}°, tilt ${this.state.mptzPosition.tilt}°, zoom ${this.state.mptzPosition.zoom} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
31
- emitCommand(this.endpoint, CameraAvSettingsUserLevelManagementServer.id, 'mptzSetPosition', request, this.context);
30
+ this.endpoint.emitCommand(CameraAvSettingsUserLevelManagement, 'mptzSetPosition', request, this.context);
32
31
  }
33
32
  mptzRelativeMove(request) {
34
33
  const device = this.endpoint.stateOf(MatterbridgeServer);
@@ -41,7 +40,7 @@ export class MatterbridgeCameraAvSettingsUserLevelManagementServer extends Camer
41
40
  const zoom = request.zoomDelta === undefined ? current.zoom : clamp((current.zoom ?? 1) + request.zoomDelta, 1, this.state.zoomMax);
42
41
  this.state.mptzPosition = { pan, tilt, zoom };
43
42
  device.log.info(`MatterbridgeCameraAvSettingsUserLevelManagementServer: moved mechanical PTZ position by pan ${request.panDelta ?? 0}°, tilt ${request.tiltDelta ?? 0}°, zoom ${request.zoomDelta ?? 0} to pan ${pan}°, tilt ${tilt}°, zoom ${zoom} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
44
- emitCommand(this.endpoint, CameraAvSettingsUserLevelManagementServer.id, 'mptzRelativeMove', request, this.context);
43
+ this.endpoint.emitCommand(CameraAvSettingsUserLevelManagement, 'mptzRelativeMove', request, this.context);
45
44
  }
46
45
  }
47
46
  export function createDefaultCameraAvSettingsUserLevelManagementClusterServer(endpoint, options) {
@@ -23,6 +23,7 @@ declare const MatterbridgeCameraAvStreamManagementServer_base: import("@matter/n
23
23
  }>, import("@matter/types").ClusterType.Concrete, new () => {}, "cameraAvStreamManagement">;
24
24
  export declare class MatterbridgeCameraAvStreamManagementServer extends MatterbridgeCameraAvStreamManagementServer_base {
25
25
  #private;
26
+ readonly endpoint: MatterbridgeEndpoint;
26
27
  initialize(): void;
27
28
  setStreamPriorities(request: CameraAvStreamManagement.SetStreamPrioritiesRequest): void;
28
29
  videoStreamAllocate(request: CameraAvStreamManagement.VideoStreamAllocateRequest): CameraAvStreamManagement.VideoStreamAllocateResponse;
@@ -2,7 +2,6 @@ import { readFileSync } from 'node:fs';
2
2
  import { CameraAvStreamManagementServer } from '@matter/node/behaviors/camera-av-stream-management';
3
3
  import { Status, StatusResponseError, StreamUsage, ThreeLevelAuto } from '@matter/types';
4
4
  import { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
5
- import { emitCommand } from '../matterbridgeEndpointHelpers.js';
6
5
  import { MatterbridgeServer } from './matterbridgeServer.js';
7
6
  const DEFAULT_CAMERA_COLOR_TEST_RESOLUTION = '640x480';
8
7
  const AUDIO_STREAM_BIT_DEPTHS = [8, 16, 24, 32];
@@ -112,7 +111,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
112
111
  }
113
112
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: setting stream priorities to [${request.streamPriorities.join(', ')}] (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
114
113
  this.state.streamUsagePriorities = request.streamPriorities;
115
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'setStreamPriorities', request, this.context);
114
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'setStreamPriorities', request, this.context);
116
115
  }
117
116
  videoStreamAllocate(request) {
118
117
  const device = this.endpoint.stateOf(MatterbridgeServer);
@@ -153,7 +152,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
153
152
  stream.keyFrameInterval === request.keyFrameInterval);
154
153
  if (existingStream) {
155
154
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: reused video stream ${existingStream.videoStreamId} for usage ${request.streamUsage} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
156
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'videoStreamAllocate', request, this.context);
155
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'videoStreamAllocate', request, this.context);
157
156
  return { videoStreamId: existingStream.videoStreamId };
158
157
  }
159
158
  if (this.state.allocatedVideoStreams.length >= this.state.maxConcurrentEncoders) {
@@ -182,7 +181,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
182
181
  },
183
182
  ];
184
183
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: allocated video stream ${videoStreamId} for usage ${request.streamUsage} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
185
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'videoStreamAllocate', request, this.context);
184
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'videoStreamAllocate', request, this.context);
186
185
  return { videoStreamId };
187
186
  }
188
187
  videoStreamDeallocate(request) {
@@ -192,7 +191,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
192
191
  }
193
192
  this.state.allocatedVideoStreams = this.state.allocatedVideoStreams.filter((stream) => stream.videoStreamId !== request.videoStreamId);
194
193
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: deallocated video stream ${request.videoStreamId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
195
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'videoStreamDeallocate', request, this.context);
194
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'videoStreamDeallocate', request, this.context);
196
195
  }
197
196
  audioStreamAllocate(request) {
198
197
  const device = this.endpoint.stateOf(MatterbridgeServer);
@@ -224,7 +223,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
224
223
  stream.bitDepth === request.bitDepth);
225
224
  if (existingStream) {
226
225
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: reused audio stream ${existingStream.audioStreamId} for usage ${request.streamUsage} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
227
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'audioStreamAllocate', request, this.context);
226
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'audioStreamAllocate', request, this.context);
228
227
  return { audioStreamId: existingStream.audioStreamId };
229
228
  }
230
229
  let audioStreamId = 0;
@@ -245,7 +244,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
245
244
  },
246
245
  ];
247
246
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: allocated audio stream ${audioStreamId} for usage ${request.streamUsage} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
248
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'audioStreamAllocate', request, this.context);
247
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'audioStreamAllocate', request, this.context);
249
248
  return { audioStreamId };
250
249
  }
251
250
  audioStreamDeallocate(request) {
@@ -255,7 +254,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
255
254
  }
256
255
  this.state.allocatedAudioStreams = this.state.allocatedAudioStreams.filter((stream) => stream.audioStreamId !== request.audioStreamId);
257
256
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: deallocated audio stream ${request.audioStreamId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
258
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'audioStreamDeallocate', request, this.context);
257
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'audioStreamDeallocate', request, this.context);
259
258
  }
260
259
  async snapshotStreamAllocate(request) {
261
260
  const device = this.endpoint.stateOf(MatterbridgeServer);
@@ -293,7 +292,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
293
292
  }
294
293
  : stream);
295
294
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: reused snapshot stream ${existingStream.snapshotStreamId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
296
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'snapshotStreamAllocate', request, this.context);
295
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'snapshotStreamAllocate', request, this.context);
297
296
  return { snapshotStreamId: existingStream.snapshotStreamId };
298
297
  }
299
298
  let snapshotStreamId = 0;
@@ -317,7 +316,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
317
316
  },
318
317
  ];
319
318
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: allocated snapshot stream ${snapshotStreamId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
320
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'snapshotStreamAllocate', request, this.context);
319
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'snapshotStreamAllocate', request, this.context);
321
320
  return { snapshotStreamId };
322
321
  }
323
322
  async snapshotStreamDeallocate(request) {
@@ -327,7 +326,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
327
326
  }
328
327
  this.state.allocatedSnapshotStreams = this.state.allocatedSnapshotStreams.filter((stream) => stream.snapshotStreamId !== request.snapshotStreamId);
329
328
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: deallocated snapshot stream ${request.snapshotStreamId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
330
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'snapshotStreamDeallocate', request, this.context);
329
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'snapshotStreamDeallocate', request, this.context);
331
330
  }
332
331
  captureSnapshot(request) {
333
332
  const device = this.endpoint.stateOf(MatterbridgeServer);
@@ -339,7 +338,7 @@ export class MatterbridgeCameraAvStreamManagementServer extends CameraAvStreamMa
339
338
  device.log.info(`MatterbridgeCameraAvStreamManagementServer: capturing snapshot ${snapshotStreamId ?? 'auto'} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
340
339
  device.log.debug(`MatterbridgeCameraAvStreamManagementServer: captureSnapshot called with snapshotStreamId ${request.snapshotStreamId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
341
340
  const { data, resolution } = cameraColorTestJpegForResolution(request.requestedResolution);
342
- emitCommand(this.endpoint, CameraAvStreamManagementServer.id, 'captureSnapshot', request, this.context);
341
+ this.endpoint.emitCommand(CameraAvStreamManagement, 'captureSnapshot', request, this.context);
343
342
  return {
344
343
  data,
345
344
  imageCodec: CameraAvStreamManagement.ImageCodec.Jpeg,
@@ -1,10 +1,11 @@
1
1
  import { ChimeServer } from '@matter/node/behaviors/chime';
2
- import type { Chime } from '@matter/types/clusters/chime';
2
+ import { Chime } from '@matter/types/clusters/chime';
3
3
  import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
4
4
  export type ChimeId = number;
5
5
  declare const ChimeServerBase: import("@matter/node").ClusterBehavior.Type<typeof ChimeServer, import("@matter/types").ClusterType.WithEnabledAttributes<import("@matter/types").ClusterType.WithEnabledEvents<Chime, "chimeStartedPlaying">, never>, import("@matter/types").ClusterType.Concrete, new () => {}, "chime">;
6
6
  export declare class MatterbridgeChimeServer extends ChimeServerBase {
7
7
  #private;
8
+ readonly endpoint: MatterbridgeEndpoint;
8
9
  initialize(): void;
9
10
  playChimeSound(request: Chime.PlayChimeSoundRequest): Promise<void>;
10
11
  }
@@ -1,6 +1,6 @@
1
1
  import { ChimeServer } from '@matter/node/behaviors/chime';
2
2
  import { Status, StatusResponseError } from '@matter/types';
3
- import { emitCommand } from '../matterbridgeEndpointHelpers.js';
3
+ import { Chime } from '@matter/types/clusters/chime';
4
4
  import { MatterbridgeServer } from './matterbridgeServer.js';
5
5
  const ChimeServerBase = ChimeServer.enable({ events: { chimeStartedPlaying: true } });
6
6
  export class MatterbridgeChimeServer extends ChimeServerBase {
@@ -24,7 +24,7 @@ export class MatterbridgeChimeServer extends ChimeServerBase {
24
24
  }
25
25
  device.log.info(`MatterbridgeChimeServer: playing chime sound with chimeId ${chimeId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
26
26
  this.events.chimeStartedPlaying.emit({ chimeId }, this.context);
27
- emitCommand(this.endpoint, ChimeServer.id, 'playChimeSound', request, this.context);
27
+ this.endpoint.emitCommand(Chime, 'playChimeSound', request, this.context);
28
28
  }
29
29
  }
30
30
  export function createDefaultChimeClusterServer(endpoint, installedChimeSounds, selectedChime, enabled = true) {
@@ -1,6 +1,7 @@
1
1
  import type { MaybePromise } from '@matter/general';
2
2
  import { ColorControlServer } from '@matter/node/behaviors/color-control';
3
3
  import { ColorControl } from '@matter/types/clusters/color-control';
4
+ import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
4
5
  declare const MatterbridgeColorControlServer_base: import("@matter/node").ClusterBehavior.Type<typeof ColorControlServer, import("@matter/types").ClusterType.WithSupportedFeatures<ColorControl, {
5
6
  colorLoop: false;
6
7
  colorTemperature: true;
@@ -9,6 +10,7 @@ declare const MatterbridgeColorControlServer_base: import("@matter/node").Cluste
9
10
  xy: true;
10
11
  }>, import("@matter/types").ClusterType.Concrete, typeof import("@matter/node/behaviors/color-control").ColorControlBaseServer.Internal, "colorControl">;
11
12
  export declare class MatterbridgeColorControlServer extends MatterbridgeColorControlServer_base {
13
+ readonly endpoint: MatterbridgeEndpoint;
12
14
  initialize(): MaybePromise;
13
15
  moveToHue(request: ColorControl.MoveToHueRequest): Promise<void>;
14
16
  moveHue(request: ColorControl.MoveHueRequest): Promise<void>;
@@ -24,6 +24,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
24
24
  });
25
25
  device.log.debug(`MatterbridgeColorControlServer: moveToHue called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
26
26
  await super.moveToHue(request);
27
+ this.endpoint.emitCommand(ColorControl, 'moveToHue', request, this.context);
27
28
  }
28
29
  async moveHue(request) {
29
30
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -42,6 +43,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
42
43
  });
43
44
  device.log.debug(`MatterbridgeColorControlServer: moveHue called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
44
45
  await super.moveHue(request);
46
+ this.endpoint.emitCommand(ColorControl, 'moveHue', request, this.context);
45
47
  }
46
48
  async stepHue(request) {
47
49
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -60,6 +62,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
60
62
  });
61
63
  device.log.debug(`MatterbridgeColorControlServer: stepHue called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
62
64
  await super.stepHue(request);
65
+ this.endpoint.emitCommand(ColorControl, 'stepHue', request, this.context);
63
66
  }
64
67
  async enhancedMoveToHue(request) {
65
68
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -78,6 +81,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
78
81
  });
79
82
  device.log.debug(`MatterbridgeColorControlServer: enhancedMoveToHue called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
80
83
  await super.enhancedMoveToHue(request);
84
+ this.endpoint.emitCommand(ColorControl, 'enhancedMoveToHue', request, this.context);
81
85
  }
82
86
  async enhancedMoveHue(request) {
83
87
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -96,6 +100,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
96
100
  });
97
101
  device.log.debug(`MatterbridgeColorControlServer: enhancedMoveHue called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
98
102
  await super.enhancedMoveHue(request);
103
+ this.endpoint.emitCommand(ColorControl, 'enhancedMoveHue', request, this.context);
99
104
  }
100
105
  async enhancedStepHue(request) {
101
106
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -114,6 +119,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
114
119
  });
115
120
  device.log.debug(`MatterbridgeColorControlServer: enhancedStepHue called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
116
121
  await super.enhancedStepHue(request);
122
+ this.endpoint.emitCommand(ColorControl, 'enhancedStepHue', request, this.context);
117
123
  }
118
124
  async moveToSaturation(request) {
119
125
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -132,6 +138,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
132
138
  });
133
139
  device.log.debug(`MatterbridgeColorControlServer: moveToSaturation called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
134
140
  await super.moveToSaturation(request);
141
+ this.endpoint.emitCommand(ColorControl, 'moveToSaturation', request, this.context);
135
142
  }
136
143
  async moveSaturation(request) {
137
144
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -150,6 +157,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
150
157
  });
151
158
  device.log.debug(`MatterbridgeColorControlServer: moveSaturation called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
152
159
  await super.moveSaturation(request);
160
+ this.endpoint.emitCommand(ColorControl, 'moveSaturation', request, this.context);
153
161
  }
154
162
  async stepSaturation(request) {
155
163
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -168,6 +176,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
168
176
  });
169
177
  device.log.debug(`MatterbridgeColorControlServer: stepSaturation called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
170
178
  await super.stepSaturation(request);
179
+ this.endpoint.emitCommand(ColorControl, 'stepSaturation', request, this.context);
171
180
  }
172
181
  async moveToHueAndSaturation(request) {
173
182
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -186,6 +195,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
186
195
  });
187
196
  device.log.debug(`MatterbridgeColorControlServer: moveToHueAndSaturation called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
188
197
  await super.moveToHueAndSaturation(request);
198
+ this.endpoint.emitCommand(ColorControl, 'moveToHueAndSaturation', request, this.context);
189
199
  }
190
200
  async enhancedMoveToHueAndSaturation(request) {
191
201
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -204,6 +214,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
204
214
  });
205
215
  device.log.debug(`MatterbridgeColorControlServer: enhancedMoveToHueAndSaturation called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
206
216
  await super.enhancedMoveToHueAndSaturation(request);
217
+ this.endpoint.emitCommand(ColorControl, 'enhancedMoveToHueAndSaturation', request, this.context);
207
218
  }
208
219
  async moveToColor(request) {
209
220
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -222,6 +233,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
222
233
  });
223
234
  device.log.debug(`MatterbridgeColorControlServer: moveToColor called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
224
235
  await super.moveToColor(request);
236
+ this.endpoint.emitCommand(ColorControl, 'moveToColor', request, this.context);
225
237
  }
226
238
  async moveColor(request) {
227
239
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -240,6 +252,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
240
252
  });
241
253
  device.log.debug(`MatterbridgeColorControlServer: moveColor called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
242
254
  await super.moveColor(request);
255
+ this.endpoint.emitCommand(ColorControl, 'moveColor', request, this.context);
243
256
  }
244
257
  async stepColor(request) {
245
258
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -258,6 +271,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
258
271
  });
259
272
  device.log.debug(`MatterbridgeColorControlServer: stepColor called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
260
273
  await super.stepColor(request);
274
+ this.endpoint.emitCommand(ColorControl, 'stepColor', request, this.context);
261
275
  }
262
276
  async moveToColorTemperature(request) {
263
277
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -276,6 +290,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
276
290
  });
277
291
  device.log.debug(`MatterbridgeColorControlServer: moveToColorTemperature called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
278
292
  await super.moveToColorTemperature(request);
293
+ this.endpoint.emitCommand(ColorControl, 'moveToColorTemperature', request, this.context);
279
294
  }
280
295
  async moveColorTemperature(request) {
281
296
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -294,6 +309,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
294
309
  });
295
310
  device.log.debug(`MatterbridgeColorControlServer: moveColorTemperature called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
296
311
  await super.moveColorTemperature(request);
312
+ this.endpoint.emitCommand(ColorControl, 'moveColorTemperature', request, this.context);
297
313
  }
298
314
  async stepColorTemperature(request) {
299
315
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -312,6 +328,7 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
312
328
  });
313
329
  device.log.debug(`MatterbridgeColorControlServer: stepColorTemperature called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
314
330
  await super.stepColorTemperature(request);
331
+ this.endpoint.emitCommand(ColorControl, 'stepColorTemperature', request, this.context);
315
332
  }
316
333
  async stopMoveStep(request) {
317
334
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -330,5 +347,6 @@ export class MatterbridgeColorControlServer extends ColorControlServer.with(Colo
330
347
  });
331
348
  device.log.debug(`MatterbridgeColorControlServer: stopMoveStep called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
332
349
  await super.stopMoveStep(request);
350
+ this.endpoint.emitCommand(ColorControl, 'stopMoveStep', request, this.context);
333
351
  }
334
352
  }
@@ -1,7 +1,9 @@
1
1
  import type { MaybePromise } from '@matter/general';
2
2
  import { LevelControlServer } from '@matter/node/behaviors/level-control';
3
- import type { LevelControl } from '@matter/types/clusters/level-control';
3
+ import { LevelControl } from '@matter/types/clusters/level-control';
4
+ import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
4
5
  export declare class MatterbridgeLevelControlServer extends LevelControlServer {
6
+ readonly endpoint: MatterbridgeEndpoint;
5
7
  initialize(): MaybePromise;
6
8
  moveToLevel(request: LevelControl.MoveToLevelRequest): Promise<void>;
7
9
  moveToLevelWithOnOff(request: LevelControl.MoveToLevelRequest): Promise<void>;
@@ -1,4 +1,5 @@
1
1
  import { LevelControlServer } from '@matter/node/behaviors/level-control';
2
+ import { LevelControl } from '@matter/types/clusters/level-control';
2
3
  import { MatterbridgeServer } from './matterbridgeServer.js';
3
4
  export class MatterbridgeLevelControlServer extends LevelControlServer {
4
5
  initialize() {
@@ -23,6 +24,7 @@ export class MatterbridgeLevelControlServer extends LevelControlServer {
23
24
  });
24
25
  device.log.debug(`MatterbridgeLevelControlServer: moveToLevel called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
25
26
  await super.moveToLevel(request);
27
+ this.endpoint.emitCommand(LevelControl, 'moveToLevel', request, this.context);
26
28
  }
27
29
  async moveToLevelWithOnOff(request) {
28
30
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -41,6 +43,7 @@ export class MatterbridgeLevelControlServer extends LevelControlServer {
41
43
  });
42
44
  device.log.debug(`MatterbridgeLevelControlServer: moveToLevelWithOnOff called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
43
45
  await super.moveToLevelWithOnOff(request);
46
+ this.endpoint.emitCommand(LevelControl, 'moveToLevelWithOnOff', request, this.context);
44
47
  }
45
48
  async move(request) {
46
49
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -59,6 +62,7 @@ export class MatterbridgeLevelControlServer extends LevelControlServer {
59
62
  });
60
63
  device.log.debug(`MatterbridgeLevelControlServer: move called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
61
64
  await super.move(request);
65
+ this.endpoint.emitCommand(LevelControl, 'move', request, this.context);
62
66
  }
63
67
  async moveWithOnOff(request) {
64
68
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -77,6 +81,7 @@ export class MatterbridgeLevelControlServer extends LevelControlServer {
77
81
  });
78
82
  device.log.debug(`MatterbridgeLevelControlServer: moveWithOnOff called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
79
83
  await super.moveWithOnOff(request);
84
+ this.endpoint.emitCommand(LevelControl, 'moveWithOnOff', request, this.context);
80
85
  }
81
86
  async step(request) {
82
87
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -95,6 +100,7 @@ export class MatterbridgeLevelControlServer extends LevelControlServer {
95
100
  });
96
101
  device.log.debug(`MatterbridgeLevelControlServer: step called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
97
102
  await super.step(request);
103
+ this.endpoint.emitCommand(LevelControl, 'step', request, this.context);
98
104
  }
99
105
  async stepWithOnOff(request) {
100
106
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -113,6 +119,7 @@ export class MatterbridgeLevelControlServer extends LevelControlServer {
113
119
  });
114
120
  device.log.debug(`MatterbridgeLevelControlServer: stepWithOnOff called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
115
121
  await super.stepWithOnOff(request);
122
+ this.endpoint.emitCommand(LevelControl, 'stepWithOnOff', request, this.context);
116
123
  }
117
124
  async stop(request) {
118
125
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -131,6 +138,7 @@ export class MatterbridgeLevelControlServer extends LevelControlServer {
131
138
  });
132
139
  device.log.debug(`MatterbridgeLevelControlServer: stop called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
133
140
  await super.stop(request);
141
+ this.endpoint.emitCommand(LevelControl, 'stop', request, this.context);
134
142
  }
135
143
  async stopWithOnOff(request) {
136
144
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -149,5 +157,6 @@ export class MatterbridgeLevelControlServer extends LevelControlServer {
149
157
  });
150
158
  device.log.debug(`MatterbridgeLevelControlServer: stopWithOnOff called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
151
159
  await super.stopWithOnOff(request);
160
+ this.endpoint.emitCommand(LevelControl, 'stopWithOnOff', request, this.context);
152
161
  }
153
162
  }
@@ -1,5 +1,6 @@
1
1
  import { OnOffServer } from '@matter/node/behaviors/on-off';
2
2
  import { OnOff } from '@matter/types/clusters/on-off';
3
+ import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
3
4
  declare const MatterbridgeOnOffServer_base: import("@matter/node").ClusterBehavior.Type<typeof OnOffServer, import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<OnOff, {
4
5
  deadFrontBehavior: false;
5
6
  lighting: true;
@@ -14,6 +15,7 @@ declare const MatterbridgeOnOffServer_base: import("@matter/node").ClusterBehavi
14
15
  offOnly: false;
15
16
  }>, import("@matter/types").ClusterType.Concrete, typeof import("@matter/node/behaviors/on-off").OnOffBaseServer.Internal, "onOff">;
16
17
  export declare class MatterbridgeOnOffServer extends MatterbridgeOnOffServer_base {
18
+ readonly endpoint: MatterbridgeEndpoint;
17
19
  on(): Promise<void>;
18
20
  off(): Promise<void>;
19
21
  toggle(): Promise<void>;
@@ -19,6 +19,7 @@ export class MatterbridgeOnOffServer extends OnOffServer.with(OnOff.Feature.Ligh
19
19
  });
20
20
  device.log.debug(`MatterbridgeOnOffServer: on called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
21
21
  await super.on();
22
+ this.endpoint.emitCommand(OnOff, 'on', {}, this.context);
22
23
  }
23
24
  async off() {
24
25
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -37,6 +38,7 @@ export class MatterbridgeOnOffServer extends OnOffServer.with(OnOff.Feature.Ligh
37
38
  });
38
39
  device.log.debug(`MatterbridgeOnOffServer: off called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
39
40
  await super.off();
41
+ this.endpoint.emitCommand(OnOff, 'off', {}, this.context);
40
42
  }
41
43
  async toggle() {
42
44
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -55,6 +57,7 @@ export class MatterbridgeOnOffServer extends OnOffServer.with(OnOff.Feature.Ligh
55
57
  });
56
58
  device.log.debug(`MatterbridgeOnOffServer: toggle called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
57
59
  await super.toggle();
60
+ this.endpoint.emitCommand(OnOff, 'toggle', {}, this.context);
58
61
  }
59
62
  async offWithEffect(request) {
60
63
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -73,6 +76,7 @@ export class MatterbridgeOnOffServer extends OnOffServer.with(OnOff.Feature.Ligh
73
76
  });
74
77
  device.log.debug(`MatterbridgeOnOffServer: offWithEffect called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
75
78
  await super.offWithEffect(request);
79
+ this.endpoint.emitCommand(OnOff, 'offWithEffect', request, this.context);
76
80
  }
77
81
  async onWithRecallGlobalScene() {
78
82
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -91,6 +95,7 @@ export class MatterbridgeOnOffServer extends OnOffServer.with(OnOff.Feature.Ligh
91
95
  });
92
96
  device.log.debug(`MatterbridgeOnOffServer: onWithRecallGlobalScene called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
93
97
  await super.onWithRecallGlobalScene();
98
+ this.endpoint.emitCommand(OnOff, 'onWithRecallGlobalScene', {}, this.context);
94
99
  }
95
100
  async onWithTimedOff(request) {
96
101
  if (process.env.MATTERBRIDGE_CHIP_TEST) {
@@ -109,5 +114,6 @@ export class MatterbridgeOnOffServer extends OnOffServer.with(OnOff.Feature.Ligh
109
114
  });
110
115
  device.log.debug(`MatterbridgeOnOffServer: onWithTimedOff called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
111
116
  await super.onWithTimedOff(request);
117
+ this.endpoint.emitCommand(OnOff, 'onWithTimedOff', request, this.context);
112
118
  }
113
119
  }
@@ -1,5 +1,5 @@
1
1
  import { WebRtcTransportProviderServer } from '@matter/node/behaviors/web-rtc-transport-provider';
2
- import type { WebRtcTransportProvider } from '@matter/types/clusters/web-rtc-transport-provider';
2
+ import { WebRtcTransportProvider } from '@matter/types/clusters/web-rtc-transport-provider';
3
3
  import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
4
4
  import { type WeriftOfferOptions, WeriftWebRtcSession } from './weriftSession.js';
5
5
  export declare function allocateWebRtcSessionId(nextCandidate: number, activeSessionIds: ReadonlySet<number>): {
@@ -8,6 +8,7 @@ export declare function allocateWebRtcSessionId(nextCandidate: number, activeSes
8
8
  };
9
9
  export declare class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportProviderServer {
10
10
  #private;
11
+ readonly endpoint: MatterbridgeEndpoint;
11
12
  state: MatterbridgeWebRtcTransportProviderServer.State;
12
13
  internal: MatterbridgeWebRtcTransportProviderServer.Internal;
13
14
  solicitOffer(request: WebRtcTransportProvider.SolicitOfferRequest): Promise<WebRtcTransportProvider.SolicitOfferResponse>;
@@ -3,7 +3,7 @@ import { WebRtcTransportProviderServer } from '@matter/node/behaviors/web-rtc-tr
3
3
  import { WebRtcTransportRequestorClient } from '@matter/node/behaviors/web-rtc-transport-requestor';
4
4
  import { EndpointNumber, FabricIndex, NodeId, StreamUsage, Status, StatusResponseError } from '@matter/types';
5
5
  import { WebRtcTransportDefinitions } from '@matter/types/clusters/web-rtc-transport-definitions';
6
- import { emitCommand } from '../matterbridgeEndpointHelpers.js';
6
+ import { WebRtcTransportProvider } from '@matter/types/clusters/web-rtc-transport-provider';
7
7
  import { MatterbridgeCameraAvStreamManagementServer } from './cameraAvStreamManagementServer.js';
8
8
  import { MatterbridgeServer } from './matterbridgeServer.js';
9
9
  import { WeriftWebRtcSession } from './weriftSession.js';
@@ -249,7 +249,7 @@ export class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportPr
249
249
  device.log.info(`MatterbridgeWebRtcTransportProviderServer.solicitOffer: solicited a WebRTC offer for session ${webRtcSessionId} (stream usage ${request.streamUsage}) (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
250
250
  const requestorEndpoint = await this.#resolvePeerRequestorEndpoint(peerNodeId, fabricIndex, request.originatingEndpointId);
251
251
  if (this.#evictIfOverCapacity(webRtcSessionId, requestorEndpoint)) {
252
- emitCommand(this.endpoint, WebRtcTransportProviderServer.id, 'solicitOffer', request, this.context);
252
+ this.endpoint.emitCommand(WebRtcTransportProvider, 'solicitOffer', request, this.context);
253
253
  return { webRtcSessionId, deferredOffer: false, ...this.#echoDeprecatedStreamIds(request, videoStreams, audioStreams) };
254
254
  }
255
255
  const webRtcPeer = new WeriftWebRtcSession(webRtcSessionId, this.state.weriftOfferOptions);
@@ -266,7 +266,7 @@ export class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportPr
266
266
  else {
267
267
  device.log.info(`MatterbridgeWebRtcTransportProviderServer.solicitOffer: could not reach the peer's WebRtcTransportRequestor; the Offer for session ${webRtcSessionId} was not sent (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
268
268
  }
269
- emitCommand(this.endpoint, WebRtcTransportProviderServer.id, 'solicitOffer', request, this.context);
269
+ this.endpoint.emitCommand(WebRtcTransportProvider, 'solicitOffer', request, this.context);
270
270
  return { webRtcSessionId, deferredOffer: false, ...this.#echoDeprecatedStreamIds(request, videoStreams, audioStreams) };
271
271
  }
272
272
  async provideOffer(request) {
@@ -311,7 +311,7 @@ export class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportPr
311
311
  ];
312
312
  const requestorEndpointForCapacityCheck = await this.#resolvePeerRequestorEndpoint(peerNodeId, fabricIndex, request.originatingEndpointId ?? EndpointNumber(0));
313
313
  if (this.#evictIfOverCapacity(webRtcSessionId, requestorEndpointForCapacityCheck)) {
314
- emitCommand(this.endpoint, WebRtcTransportProviderServer.id, 'provideOffer', request, this.context);
314
+ this.endpoint.emitCommand(WebRtcTransportProvider, 'provideOffer', request, this.context);
315
315
  return { webRtcSessionId, ...this.#echoDeprecatedStreamIds(request, videoStreams, audioStreams) };
316
316
  }
317
317
  }
@@ -336,7 +336,7 @@ export class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportPr
336
336
  else {
337
337
  device.log.info(`MatterbridgeWebRtcTransportProviderServer.provideOffer: could not reach the peer's WebRtcTransportRequestor; the Answer for session ${webRtcSessionId} was not sent (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
338
338
  }
339
- emitCommand(this.endpoint, WebRtcTransportProviderServer.id, 'provideOffer', request, this.context);
339
+ this.endpoint.emitCommand(WebRtcTransportProvider, 'provideOffer', request, this.context);
340
340
  return { webRtcSessionId, ...this.#echoDeprecatedStreamIds(request, session.videoStreams && [...session.videoStreams], session.audioStreams && [...session.audioStreams]) };
341
341
  }
342
342
  async provideAnswer(request) {
@@ -350,7 +350,7 @@ export class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportPr
350
350
  if (webRtcPeer) {
351
351
  await webRtcPeer.applyAnswer(request.sdp);
352
352
  }
353
- emitCommand(this.endpoint, WebRtcTransportProviderServer.id, 'provideAnswer', request, this.context);
353
+ this.endpoint.emitCommand(WebRtcTransportProvider, 'provideAnswer', request, this.context);
354
354
  }
355
355
  async provideIceCandidates(request) {
356
356
  const device = this.endpoint.stateOf(MatterbridgeServer);
@@ -388,7 +388,7 @@ export class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportPr
388
388
  }
389
389
  }));
390
390
  }
391
- emitCommand(this.endpoint, WebRtcTransportProviderServer.id, 'provideIceCandidates', request, this.context);
391
+ this.endpoint.emitCommand(WebRtcTransportProvider, 'provideIceCandidates', request, this.context);
392
392
  }
393
393
  async endSession(request) {
394
394
  const device = this.endpoint.stateOf(MatterbridgeServer);
@@ -402,7 +402,7 @@ export class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportPr
402
402
  await webRtcPeer.close();
403
403
  }
404
404
  device.log.info(`MatterbridgeWebRtcTransportProviderServer.endSession: ended webRTC session ${request.webRtcSessionId} (reason ${request.reason}) (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
405
- emitCommand(this.endpoint, WebRtcTransportProviderServer.id, 'endSession', request, this.context);
405
+ this.endpoint.emitCommand(WebRtcTransportProvider, 'endSession', request, this.context);
406
406
  }
407
407
  }
408
408
  (function (MatterbridgeWebRtcTransportProviderServer) {
@@ -1,7 +1,8 @@
1
1
  import { WebRtcTransportRequestorServer } from '@matter/node/behaviors/web-rtc-transport-requestor';
2
- import type { WebRtcTransportRequestor } from '@matter/types/clusters/web-rtc-transport-requestor';
2
+ import { WebRtcTransportRequestor } from '@matter/types/clusters/web-rtc-transport-requestor';
3
3
  import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
4
4
  export declare class MatterbridgeWebRtcTransportRequestorServer extends WebRtcTransportRequestorServer {
5
+ readonly endpoint: MatterbridgeEndpoint;
5
6
  offer(request: WebRtcTransportRequestor.OfferRequest): Promise<void>;
6
7
  answer(request: WebRtcTransportRequestor.AnswerRequest): Promise<void>;
7
8
  iceCandidates(request: WebRtcTransportRequestor.IceCandidatesRequest): Promise<void>;
@@ -1,21 +1,21 @@
1
1
  import { WebRtcTransportRequestorServer } from '@matter/node/behaviors/web-rtc-transport-requestor';
2
- import { emitCommand } from '../matterbridgeEndpointHelpers.js';
2
+ import { WebRtcTransportRequestor } from '@matter/types/clusters/web-rtc-transport-requestor';
3
3
  export class MatterbridgeWebRtcTransportRequestorServer extends WebRtcTransportRequestorServer {
4
4
  async offer(request) {
5
5
  await super.offer(request);
6
- emitCommand(this.endpoint, WebRtcTransportRequestorServer.id, 'offer', request, this.context);
6
+ this.endpoint.emitCommand(WebRtcTransportRequestor, 'offer', request, this.context);
7
7
  }
8
8
  async answer(request) {
9
9
  await super.answer(request);
10
- emitCommand(this.endpoint, WebRtcTransportRequestorServer.id, 'answer', request, this.context);
10
+ this.endpoint.emitCommand(WebRtcTransportRequestor, 'answer', request, this.context);
11
11
  }
12
12
  async iceCandidates(request) {
13
13
  await super.iceCandidates(request);
14
- emitCommand(this.endpoint, WebRtcTransportRequestorServer.id, 'iceCandidates', request, this.context);
14
+ this.endpoint.emitCommand(WebRtcTransportRequestor, 'iceCandidates', request, this.context);
15
15
  }
16
16
  async end(request) {
17
17
  await super.end(request);
18
- emitCommand(this.endpoint, WebRtcTransportRequestorServer.id, 'end', request, this.context);
18
+ this.endpoint.emitCommand(WebRtcTransportRequestor, 'end', request, this.context);
19
19
  }
20
20
  }
21
21
  export function createDefaultWebRtcTransportRequestorClusterServer(endpoint) {
@@ -29,6 +29,8 @@ export declare class WeriftWebRtcSession {
29
29
  private static readonly DIAGNOSTICS_INTERVAL_MS;
30
30
  private lastDiagnosticsCounters?;
31
31
  private readonly dtlsTransportsWithStateLogging;
32
+ private static parseIcePortRange;
33
+ private static parseIceAdditionalHostAddresses;
32
34
  constructor(webRtcSessionId: number, options: WeriftOfferOptions);
33
35
  private summarizeSdp;
34
36
  private getFreeUdpPort;
@@ -22,11 +22,35 @@ export class WeriftWebRtcSession {
22
22
  static DIAGNOSTICS_INTERVAL_MS = 10_000;
23
23
  lastDiagnosticsCounters;
24
24
  dtlsTransportsWithStateLogging = new Set();
25
+ static parseIcePortRange() {
26
+ const raw = process.env.MATTERBRIDGE_ICE_PORT_RANGE?.trim();
27
+ if (!raw)
28
+ return undefined;
29
+ const match = /^(\d{1,5})-(\d{1,5})$/.exec(raw);
30
+ if (!match)
31
+ return undefined;
32
+ const min = Number(match[1]);
33
+ const max = Number(match[2]);
34
+ if (min < 1024 || max > 65_535 || min >= max)
35
+ return undefined;
36
+ return [min, max];
37
+ }
38
+ static parseIceAdditionalHostAddresses() {
39
+ const addresses = process.env.MATTERBRIDGE_ICE_HOST_ADDRESSES?.split(',')
40
+ .map((address) => address.trim())
41
+ .filter((address) => address.length > 0) ?? [];
42
+ return addresses.length > 0 ? addresses : undefined;
43
+ }
25
44
  constructor(webRtcSessionId, options) {
26
45
  this.webRtcSessionId = webRtcSessionId;
27
46
  this.options = { ...options };
28
- this.peerConnection = new RTCPeerConnection({ codecs: { audio: [useOPUS(), usePCMU()], video: [useH264(), useVP8()] } });
47
+ const icePortRange = WeriftWebRtcSession.parseIcePortRange();
48
+ const iceAdditionalHostAddresses = WeriftWebRtcSession.parseIceAdditionalHostAddresses();
49
+ this.peerConnection = new RTCPeerConnection({ codecs: { audio: [useOPUS(), usePCMU()], video: [useH264(), useVP8()] }, icePortRange, iceAdditionalHostAddresses });
29
50
  this.log = new AnsiLogger({ logName: `WebRTC session ${webRtcSessionId}`, logLevel: "debug", logNameColor: MAGENTA, logTimestampFormat: 4 });
51
+ if (icePortRange || iceAdditionalHostAddresses) {
52
+ this.log.debug(`ICE overrides: portRange=${icePortRange ? `${icePortRange[0]}-${icePortRange[1]}` : 'default'} additionalHostAddresses=${iceAdditionalHostAddresses?.join(', ') ?? 'none'}`);
53
+ }
30
54
  this.peerConnection.iceGatheringStateChange.subscribe((state) => {
31
55
  this.log.info(`ICE gathering state: ${state}`);
32
56
  });
@@ -5,6 +5,7 @@ import { AirQuality } from '@matter/types/clusters/air-quality';
5
5
  import { ClosureDimension } from '@matter/types/clusters/closure-dimension';
6
6
  import { DoorLock } from '@matter/types/clusters/door-lock';
7
7
  import { FanControl } from '@matter/types/clusters/fan-control';
8
+ import { Identify } from '@matter/types/clusters/identify';
8
9
  import { PowerSource } from '@matter/types/clusters/power-source';
9
10
  import { PowerTopology } from '@matter/types/clusters/power-topology';
10
11
  import { ResourceMonitoring } from '@matter/types/clusters/resource-monitoring';
@@ -14,18 +15,25 @@ import { Thermostat } from '@matter/types/clusters/thermostat';
14
15
  import { EndpointNumber } from '@matter/types/datatype';
15
16
  import { getErrorMessage } from '@matterbridge/utils/error';
16
17
  import { AirConditioner } from './devices/airConditioner.js';
18
+ import { AudioDoorbell } from './devices/audioDoorbell.js';
17
19
  import { BasicVideoPlayer } from './devices/basicVideoPlayer.js';
18
20
  import { BatteryStorage } from './devices/batteryStorage.js';
21
+ import { Camera } from './devices/camera.js';
22
+ import { CameraController } from './devices/cameraController.js';
19
23
  import { CastingVideoClient } from './devices/castingVideoClient.js';
20
24
  import { CastingVideoPlayer } from './devices/castingVideoPlayer.js';
25
+ import { Chime } from './devices/chime.js';
21
26
  import { Closure } from './devices/closure.js';
22
27
  import { ContentApp } from './devices/contentApp.js';
23
28
  import { Cooktop } from './devices/cooktop.js';
24
29
  import { Dishwasher } from './devices/dishwasher.js';
30
+ import { Doorbell } from './devices/doorbell.js';
25
31
  import { ElectricalUtilityMeter } from './devices/electricalUtilityMeter.js';
26
32
  import { Evse } from './devices/evse.js';
27
33
  import { ExtractorHood } from './devices/extractorHood.js';
34
+ import { FloodlightCamera } from './devices/floodlightCamera.js';
28
35
  import { HeatPump } from './devices/heatPump.js';
36
+ import { Intercom } from './devices/intercom.js';
29
37
  import { IrrigationSystem } from './devices/irrigationSystem.js';
30
38
  import { LaundryDryer } from './devices/laundryDryer.js';
31
39
  import { LaundryWasher } from './devices/laundryWasher.js';
@@ -33,8 +41,10 @@ import { MicrowaveOven } from './devices/microwaveOven.js';
33
41
  import { Oven } from './devices/oven.js';
34
42
  import { Refrigerator } from './devices/refrigerator.js';
35
43
  import { RoboticVacuumCleaner } from './devices/roboticVacuumCleaner.js';
44
+ import { SnapshotCamera } from './devices/snapshotCamera.js';
36
45
  import { SolarPower } from './devices/solarPower.js';
37
46
  import { Speaker } from './devices/speaker.js';
47
+ import { VideoDoorbell } from './devices/videoDoorbell.js';
38
48
  import { VideoRemoteControl } from './devices/videoRemoteControl.js';
39
49
  import { WaterHeater } from './devices/waterHeater.js';
40
50
  import { getSupportedDeviceType } from './matterbridgeDeviceTypes.js';
@@ -823,4 +833,58 @@ export async function createDemoDevices(matterbridge) {
823
833
  tagList: [getSemtag(ElectricalMeasurementTag.Ac), getSemtag(PowerSourceTag.Ev), getSemtag(CommodityTariffFlowTag.Import), getSemtag(CommodityTariffChronologyTag.Upcoming)],
824
834
  });
825
835
  await registerDevice(electricalUtilityMeterEvEndpoint, 'Electrical Utility Meter Ev', 'ENERGY-14-10');
836
+ ep = new Camera('Camera', 'CAMERA-16-01', {
837
+ id: 'Camera',
838
+ number: EndpointNumber(16_01),
839
+ weriftOfferOptions: { video: true, audio: true, videoSource: 'test', audioSource: 'test' },
840
+ });
841
+ await registerDevice(ep, 'Camera', 'CAMERA-16-01');
842
+ ep = new Camera('Camera Ptz', 'CAMERA-16-01-1', {
843
+ id: 'CameraPtz',
844
+ number: EndpointNumber(16_01_1),
845
+ ptz: true,
846
+ identifyType: Identify.IdentifyType.VisibleIndicator,
847
+ weriftOfferOptions: { video: true, audio: true, videoSource: 'test', audioSource: 'test' },
848
+ });
849
+ await registerDevice(ep, 'Camera Ptz', 'CAMERA-16-01-1');
850
+ ep = new FloodlightCamera('Floodlight Camera', 'CAMERA-16-02', {
851
+ id: 'FloodlightCamera',
852
+ number: EndpointNumber(16_02),
853
+ cameraOptions: { number: EndpointNumber(16_02_1), ptz: true, identifyType: Identify.IdentifyType.VisibleIndicator },
854
+ lightOptions: { number: EndpointNumber(16_02_2) },
855
+ });
856
+ await registerDevice(ep, 'Floodlight Camera', 'CAMERA-16-02');
857
+ ep = new VideoDoorbell('Video Doorbell', 'CAMERA-16-03', {
858
+ id: 'VideoDoorbell',
859
+ number: EndpointNumber(16_03),
860
+ cameraOptions: { number: EndpointNumber(16_03_1), ptz: true, identifyType: Identify.IdentifyType.VisibleIndicator },
861
+ doorbellOptions: { number: EndpointNumber(16_03_2) },
862
+ });
863
+ await registerDevice(ep, 'Video Doorbell', 'CAMERA-16-03');
864
+ ep = new Intercom('Intercom I', 'CAMERA-16-04', { id: 'Intercom', number: EndpointNumber(16_04), identifyType: Identify.IdentifyType.VisibleIndicator });
865
+ await registerDevice(ep, 'Intercom I', 'CAMERA-16-04');
866
+ ep = new Intercom('Intercom II', 'CAMERA-16-04-1', { id: 'IntercomII', number: EndpointNumber(16_04_1), identifyType: Identify.IdentifyType.VisibleIndicator });
867
+ await registerDevice(ep, 'Intercom II', 'CAMERA-16-04-1');
868
+ ep = new AudioDoorbell('Audio Doorbell', 'CAMERA-16-05', { id: 'AudioDoorbell', number: EndpointNumber(16_05) });
869
+ await registerDevice(ep, 'Audio Doorbell', 'CAMERA-16-05');
870
+ ep = new SnapshotCamera('Snapshot Camera', 'CAMERA-16-06', {
871
+ id: 'SnapshotCamera',
872
+ number: EndpointNumber(16_06),
873
+ identifyType: Identify.IdentifyType.VisibleIndicator,
874
+ });
875
+ await registerDevice(ep, 'Snapshot Camera', 'CAMERA-16-06');
876
+ ep = new Chime('Chime', 'CAMERA-16-07', {
877
+ id: 'Chime',
878
+ number: EndpointNumber(16_07),
879
+ identifyType: Identify.IdentifyType.AudibleBeep,
880
+ installedChimeSounds: [
881
+ { chimeId: 0, name: 'Default Chime' },
882
+ { chimeId: 1, name: 'Westminster' },
883
+ ],
884
+ });
885
+ await registerDevice(ep, 'Chime', 'CAMERA-16-07');
886
+ ep = new CameraController('Camera Controller', 'CAMERA-16-08', { id: 'CameraController', number: EndpointNumber(16_08) });
887
+ await registerDevice(ep, 'Camera Controller', 'CAMERA-16-08');
888
+ ep = new Doorbell('Doorbell', 'CAMERA-16-09', { id: 'Doorbell', number: EndpointNumber(16_09) });
889
+ await registerDevice(ep, 'Doorbell', 'CAMERA-16-09');
826
890
  }
@@ -0,0 +1,9 @@
1
+ export * from '../audioDoorbell.js';
2
+ export * from '../camera.js';
3
+ export * from '../cameraController.js';
4
+ export * from '../chime.js';
5
+ export * from '../doorbell.js';
6
+ export * from '../floodlightCamera.js';
7
+ export * from '../intercom.js';
8
+ export * from '../snapshotCamera.js';
9
+ export * from '../videoDoorbell.js';
@@ -0,0 +1,9 @@
1
+ export * from '../audioDoorbell.js';
2
+ export * from '../camera.js';
3
+ export * from '../cameraController.js';
4
+ export * from '../chime.js';
5
+ export * from '../doorbell.js';
6
+ export * from '../floodlightCamera.js';
7
+ export * from '../intercom.js';
8
+ export * from '../snapshotCamera.js';
9
+ export * from '../videoDoorbell.js';
@@ -0,0 +1,8 @@
1
+ import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
2
+ import type { MatterbridgeEndpointOptions } from '../matterbridgeEndpointTypes.js';
3
+ export interface CameraControllerOptions extends MatterbridgeEndpointOptions {
4
+ powerSourceType?: 'Rechargeable' | 'Replaceable' | 'Battery' | 'Wired' | 'None';
5
+ }
6
+ export declare class CameraController extends MatterbridgeEndpoint {
7
+ constructor(name: string, serial: string, options?: CameraControllerOptions);
8
+ }
@@ -0,0 +1,35 @@
1
+ import { addWebRtcTransportProviderClient } from '../behaviors/clients.js';
2
+ import { createDefaultWebRtcTransportRequestorClusterServer } from '../behaviors/webRtcTransportRequestorServer.js';
3
+ import { cameraController, powerSource } from '../matterbridgeDeviceTypes.js';
4
+ import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
5
+ export class CameraController extends MatterbridgeEndpoint {
6
+ constructor(name, serial, options = {}) {
7
+ const { powerSourceType = 'Wired', id, number, tagList, mode } = options;
8
+ super(powerSourceType === 'None' ? [cameraController] : [cameraController, powerSource], {
9
+ id: id ?? `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`,
10
+ number,
11
+ tagList,
12
+ mode,
13
+ });
14
+ this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Camera Controller');
15
+ switch (powerSourceType) {
16
+ case 'Rechargeable':
17
+ this.createDefaultPowerSourceRechargeableBatteryClusterServer();
18
+ break;
19
+ case 'Replaceable':
20
+ this.createDefaultPowerSourceReplaceableBatteryClusterServer();
21
+ break;
22
+ case 'Battery':
23
+ this.createDefaultPowerSourceBatteryClusterServer();
24
+ break;
25
+ case 'Wired':
26
+ this.createDefaultPowerSourceWiredClusterServer();
27
+ break;
28
+ case 'None':
29
+ break;
30
+ }
31
+ createDefaultWebRtcTransportRequestorClusterServer(this);
32
+ addWebRtcTransportProviderClient(this);
33
+ this.addRequiredClusters();
34
+ }
35
+ }
@@ -1,11 +1,13 @@
1
1
  import type { Semtag } from '@matter/types';
2
+ import type { EndpointNumber } from '@matter/types/datatype';
2
3
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
3
4
  import type { MatterbridgeEndpointOptions } from '../matterbridgeEndpointTypes.js';
4
5
  import type { CameraOptions } from './camera.js';
5
- export type FloodlightCameraCameraOptions = Omit<CameraOptions, 'id' | 'number' | 'tagList' | 'mode' | 'powerSourceType'>;
6
+ export type FloodlightCameraCameraOptions = Omit<CameraOptions, 'id' | 'mode' | 'powerSourceType'>;
6
7
  export interface FloodlightCameraLightOptions {
7
8
  name?: string;
8
9
  tagList?: Semtag[];
10
+ number?: EndpointNumber;
9
11
  onOff?: boolean;
10
12
  }
11
13
  export interface FloodlightCameraOptions extends MatterbridgeEndpointOptions {
@@ -15,5 +17,5 @@ export interface FloodlightCameraOptions extends MatterbridgeEndpointOptions {
15
17
  }
16
18
  export declare class FloodlightCamera extends MatterbridgeEndpoint {
17
19
  constructor(name: string, serial: string, options?: FloodlightCameraOptions);
18
- addLight(name: string, tagList?: Semtag[], onOff?: boolean): MatterbridgeEndpoint;
20
+ addLight(name: string, options?: FloodlightCameraLightOptions): MatterbridgeEndpoint;
19
21
  }
@@ -43,8 +43,8 @@ export class FloodlightCamera extends MatterbridgeEndpoint {
43
43
  { resolution: { width: 640, height: 480 }, maxFrameRate: 10, imageCodec: CameraAvStreamManagement.ImageCodec.Jpeg, requiresEncodedPixels: false },
44
44
  { resolution: { width: 1280, height: 720 }, maxFrameRate: 10, imageCodec: CameraAvStreamManagement.ImageCodec.Jpeg, requiresEncodedPixels: false },
45
45
  { resolution: { width: 1920, height: 1080 }, maxFrameRate: 10, imageCodec: CameraAvStreamManagement.ImageCodec.Jpeg, requiresEncodedPixels: false },
46
- ], weriftOfferOptions, } = cameraOptions;
47
- const cameraChild = this.addChildDeviceType('Camera', camera, {});
46
+ ], weriftOfferOptions, number: cameraNumber, tagList: cameraTagList = [], } = cameraOptions;
47
+ const cameraChild = this.addChildDeviceType('Camera', camera, { number: cameraNumber, ...(cameraTagList.length > 0 ? { tagList: cameraTagList } : {}) });
48
48
  cameraChild.log.logName = 'Camera';
49
49
  if (identifyType !== Identify.IdentifyType.None) {
50
50
  cameraChild.createDefaultIdentifyClusterServer(identifyTime, identifyType);
@@ -67,11 +67,12 @@ export class FloodlightCamera extends MatterbridgeEndpoint {
67
67
  createDefaultWebRtcTransportProviderClusterServer(cameraChild, weriftOfferOptions);
68
68
  addWebRtcTransportRequestorClient(cameraChild);
69
69
  cameraChild.addRequiredClusters();
70
- const { name: lightName = 'Light', tagList: lightTagList = [], onOff: lightOnOff = false } = lightOptions;
71
- this.addLight(lightName, lightTagList, lightOnOff);
70
+ const { name: lightName = 'Light', tagList: lightTagList = [], number: lightNumber, onOff: lightOnOff = false } = lightOptions;
71
+ this.addLight(lightName, { tagList: lightTagList, number: lightNumber, onOff: lightOnOff });
72
72
  }
73
- addLight(name, tagList = [], onOff = false) {
74
- const light = this.addChildDeviceType(name, onOffLight, tagList.length > 0 ? { tagList } : {});
73
+ addLight(name, options = {}) {
74
+ const { tagList = [], number, onOff = false } = options;
75
+ const light = this.addChildDeviceType(name, onOffLight, { number, ...(tagList.length > 0 ? { tagList } : {}) });
75
76
  light.log.logName = name;
76
77
  light.createDefaultIdentifyClusterServer();
77
78
  light.createDefaultOnOffClusterServer(onOff);
@@ -1,12 +1,14 @@
1
1
  import type { Semtag } from '@matter/types';
2
2
  import { Identify } from '@matter/types/clusters/identify';
3
+ import type { EndpointNumber } from '@matter/types/datatype';
3
4
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
4
5
  import type { MatterbridgeEndpointOptions } from '../matterbridgeEndpointTypes.js';
5
6
  import type { CameraOptions } from './camera.js';
6
- export type VideoDoorbellCameraOptions = Omit<CameraOptions, 'id' | 'number' | 'tagList' | 'mode' | 'powerSourceType'>;
7
+ export type VideoDoorbellCameraOptions = Omit<CameraOptions, 'id' | 'mode' | 'powerSourceType'>;
7
8
  export interface VideoDoorbellDoorbellOptions {
8
9
  name?: string;
9
10
  tagList?: Semtag[];
11
+ number?: EndpointNumber;
10
12
  identifyTime?: number;
11
13
  identifyType?: Identify.IdentifyType;
12
14
  }
@@ -17,5 +19,5 @@ export interface VideoDoorbellOptions extends MatterbridgeEndpointOptions {
17
19
  }
18
20
  export declare class VideoDoorbell extends MatterbridgeEndpoint {
19
21
  constructor(name: string, serial: string, options?: VideoDoorbellOptions);
20
- addDoorbell(name: string, tagList?: Semtag[], identifyTime?: number, identifyType?: Identify.IdentifyType): MatterbridgeEndpoint;
22
+ addDoorbell(name: string, options?: VideoDoorbellDoorbellOptions): MatterbridgeEndpoint;
21
23
  }
@@ -43,8 +43,8 @@ export class VideoDoorbell extends MatterbridgeEndpoint {
43
43
  { resolution: { width: 640, height: 480 }, maxFrameRate: 10, imageCodec: CameraAvStreamManagement.ImageCodec.Jpeg, requiresEncodedPixels: false },
44
44
  { resolution: { width: 1280, height: 720 }, maxFrameRate: 10, imageCodec: CameraAvStreamManagement.ImageCodec.Jpeg, requiresEncodedPixels: false },
45
45
  { resolution: { width: 1920, height: 1080 }, maxFrameRate: 10, imageCodec: CameraAvStreamManagement.ImageCodec.Jpeg, requiresEncodedPixels: false },
46
- ], weriftOfferOptions, } = cameraOptions;
47
- const cameraChild = this.addChildDeviceType('Camera', camera, {});
46
+ ], weriftOfferOptions, number: cameraNumber, tagList: cameraTagList = [], } = cameraOptions;
47
+ const cameraChild = this.addChildDeviceType('Camera', camera, { number: cameraNumber, ...(cameraTagList.length > 0 ? { tagList: cameraTagList } : {}) });
48
48
  cameraChild.log.logName = 'Camera';
49
49
  if (cameraIdentifyType !== Identify.IdentifyType.None) {
50
50
  cameraChild.createDefaultIdentifyClusterServer(cameraIdentifyTime, cameraIdentifyType);
@@ -67,11 +67,12 @@ export class VideoDoorbell extends MatterbridgeEndpoint {
67
67
  createDefaultWebRtcTransportProviderClusterServer(cameraChild, weriftOfferOptions);
68
68
  addWebRtcTransportRequestorClient(cameraChild);
69
69
  cameraChild.addRequiredClusters();
70
- const { name: doorbellName = 'Doorbell', tagList: doorbellTagList = [], identifyTime = 0, identifyType = Identify.IdentifyType.None } = doorbellOptions;
71
- this.addDoorbell(doorbellName, doorbellTagList, identifyTime, identifyType);
70
+ const { name: doorbellName = 'Doorbell', tagList: doorbellTagList = [], number: doorbellNumber, identifyTime = 0, identifyType = Identify.IdentifyType.None } = doorbellOptions;
71
+ this.addDoorbell(doorbellName, { tagList: doorbellTagList, number: doorbellNumber, identifyTime, identifyType });
72
72
  }
73
- addDoorbell(name, tagList = [], identifyTime = 0, identifyType = Identify.IdentifyType.None) {
74
- const doorbellChild = this.addChildDeviceType(name, doorbell, tagList.length > 0 ? { tagList } : {});
73
+ addDoorbell(name, options = {}) {
74
+ const { tagList = [], number, identifyTime = 0, identifyType = Identify.IdentifyType.None } = options;
75
+ const doorbellChild = this.addChildDeviceType(name, doorbell, { number, ...(tagList.length > 0 ? { tagList } : {}) });
75
76
  doorbellChild.log.logName = name;
76
77
  doorbellChild.createDefaultIdentifyClusterServer(identifyTime, identifyType);
77
78
  doorbellChild.createDefaultMomentarySwitchClusterServer();
package/dist/helpers.d.ts CHANGED
@@ -3,3 +3,4 @@ import type { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
3
3
  import type { Matterbridge } from './matterbridge.js';
4
4
  export declare function addVirtualDevice(aggregatorEndpoint: Endpoint<AggregatorEndpoint>, name: string, type: 'light' | 'outlet' | 'switch' | 'mounted_switch', callback: () => Promise<void>): Promise<Endpoint>;
5
5
  export declare function addVirtualDevices(matterbridge: Matterbridge, aggregatorEndpoint: Endpoint<AggregatorEndpoint>): Promise<void>;
6
+ export declare function resolveRootDirectory(currentFileDirectory: string, maxLevels?: number): Promise<string | undefined>;
package/dist/helpers.js CHANGED
@@ -1,3 +1,5 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
1
3
  import { Endpoint } from '@matter/node';
2
4
  import { BindingServer } from '@matter/node/behaviors/binding';
3
5
  import { BridgedDeviceBasicInformationServer } from '@matter/node/behaviors/bridged-device-basic-information';
@@ -71,3 +73,27 @@ export async function addVirtualDevices(matterbridge, aggregatorEndpoint) {
71
73
  });
72
74
  }
73
75
  }
76
+ async function isMatterbridgePackageDirectory(directory) {
77
+ try {
78
+ const packageJson = JSON.parse(await fs.promises.readFile(path.join(directory, 'package.json'), 'utf8'));
79
+ return packageJson?.name === 'matterbridge';
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ export async function resolveRootDirectory(currentFileDirectory, maxLevels = 10) {
86
+ let directory = currentFileDirectory;
87
+ for (let level = 0; level < maxLevels; level++) {
88
+ if (await isMatterbridgePackageDirectory(directory))
89
+ return directory;
90
+ const nodeModulesDirectory = path.join(directory, 'node_modules', 'matterbridge');
91
+ if (await isMatterbridgePackageDirectory(nodeModulesDirectory))
92
+ return nodeModulesDirectory;
93
+ const parentDirectory = path.dirname(directory);
94
+ if (parentDirectory === directory)
95
+ break;
96
+ directory = parentDirectory;
97
+ }
98
+ return undefined;
99
+ }
@@ -30,7 +30,7 @@ import { AnsiLogger, BLUE, BRIGHT, CYAN, db, debugStringify, er, GREEN, nf, nt,
30
30
  import { NodeStorageManager } from 'node-persist-manager';
31
31
  import { DeviceManager } from './deviceManager.js';
32
32
  import { Frontend } from './frontend.js';
33
- import { addVirtualDevice, addVirtualDevices } from './helpers.js';
33
+ import { addVirtualDevice, addVirtualDevices, resolveRootDirectory } from './helpers.js';
34
34
  import { bridge } from './matterbridgeDeviceTypes.js';
35
35
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
36
36
  import { PluginManager } from './pluginManager.js';
@@ -408,25 +408,14 @@ export class Matterbridge extends EventEmitter {
408
408
  await createDirectory(this.matterbridgeCertDirectory, 'Matterbridge Matter Certificate Directory', this.log);
409
409
  const currentFileDirectory = path.dirname(fileURLToPath(import.meta.url));
410
410
  this.log.debug(`Determining root directory from currentFileDirectory = ${CYAN}${currentFileDirectory}${db}`);
411
- if (currentFileDirectory.endsWith(path.join('matterbridge', 'packages', 'core', 'src')) ||
412
- currentFileDirectory.endsWith(path.join('matterbridge', 'packages', 'core', 'dist'))) {
413
- this.rootDirectory = path.resolve(currentFileDirectory, '..', '..', '..');
414
- this.log.debug(`Found packages core >>> root directory: ${CYAN}${this.rootDirectory}${db}`);
415
- }
416
- else if (currentFileDirectory.endsWith(path.join('matterbridge', 'dist'))) {
417
- this.rootDirectory = path.resolve(currentFileDirectory, '..');
418
- this.log.debug(`Found bundled core >>> root directory: ${CYAN}${this.rootDirectory}${db}`);
419
- }
420
- else {
421
- if (isBun()) {
422
- this.rootDirectory = path.join(getGlobalBunModules(), 'matterbridge');
423
- this.log.debug(`Found bun global core >>> root directory: ${CYAN}${this.rootDirectory}${db}`);
424
- }
425
- else {
426
- this.rootDirectory = path.resolve(currentFileDirectory, '..', '..', '..', '..');
427
- this.log.debug(`Found production core >>> root directory: ${CYAN}${this.rootDirectory}${db}`);
428
- }
429
- }
411
+ const rootDirectory = await resolveRootDirectory(currentFileDirectory);
412
+ if (rootDirectory === undefined) {
413
+ const message = `Cannot determine the matterbridge root directory from ${currentFileDirectory}: no matterbridge package.json found in the parent directories.`;
414
+ this.log.fatal(message);
415
+ throw new Error(message);
416
+ }
417
+ this.rootDirectory = rootDirectory;
418
+ this.log.debug(`Found root directory: ${CYAN}${this.rootDirectory}${db}`);
430
419
  this.environment.vars.set('log.level', MatterLogLevel.DEBUG);
431
420
  this.environment.vars.set('log.format', hasParameter('no-ansi') || process.env.NO_COLOR === '1' ? MatterLogFormat.PLAIN : MatterLogFormat.ANSI);
432
421
  this.environment.vars.set('path.root', path.join(this.matterbridgeDirectory, MATTER_STORAGE_DIR));
@@ -30,6 +30,7 @@ import type { DeviceTypeDefinition } from './matterbridgeDeviceTypes.js';
30
30
  import { CommandHandler, type CommandHandlerData, type CommandHandlerExecutionResult, type CommandHandlerFunction, type CommandHandlers } from './matterbridgeEndpointCommandHandler.js';
31
31
  import type { MatterbridgeEndpointOptions, SerializedMatterbridgeEndpoint, SubscribeCommandListener } from './matterbridgeEndpointTypes.js';
32
32
  type FirstCommandParam<Params extends unknown[]> = Params extends [] ? undefined : Params[0];
33
+ type CommandRequest<P> = [P] extends [undefined] ? Record<string, never> : P;
33
34
  type BehaviorCluster<T extends Behavior.Type> = T extends {
34
35
  cluster: infer C extends ClusterType;
35
36
  } ? C : ClusterType;
@@ -109,6 +110,9 @@ export declare class MatterbridgeEndpoint extends Endpoint {
109
110
  subscribeCommand<T extends Behavior.Type, C extends BehaviorCommandName<T>>(cluster: T, command: C, listener: SubscribeCommandListener<BehaviorCommandParams<T, C>>, log?: AnsiLogger): MatterbridgeEndpoint;
110
111
  subscribeCommand<T extends ClusterType, C extends ClusterCommandName<T>>(cluster: T, command: C, listener: SubscribeCommandListener<ClusterCommandParams<T, C>>, log?: AnsiLogger): MatterbridgeEndpoint;
111
112
  subscribeCommand(cluster: ClusterId | string, command: string, listener: SubscribeCommandListener, log?: AnsiLogger): MatterbridgeEndpoint;
113
+ emitCommand<T extends Behavior.Type, C extends BehaviorCommandName<T>>(cluster: T, command: C, request: CommandRequest<BehaviorCommandParams<T, C>>, context: ActionContext): void;
114
+ emitCommand<T extends ClusterType, C extends ClusterCommandName<T>>(cluster: T, command: C, request: CommandRequest<ClusterCommandParams<T, C>>, context: ActionContext): void;
115
+ emitCommand(cluster: string, command: string, request: unknown, context: ActionContext): void;
112
116
  setCluster<T extends Behavior.Type>(cluster: T, value: Behavior.StateOf<T>, log?: AnsiLogger): Promise<boolean>;
113
117
  setCluster<T extends ClusterType>(cluster: T, value: Partial<ClusterAttributesOf<T>>, log?: AnsiLogger): Promise<boolean>;
114
118
  setCluster(cluster: ClusterId | string, value: Record<string, boolean | number | bigint | string | object | undefined | null>, log?: AnsiLogger): Promise<boolean>;
@@ -149,7 +153,7 @@ export declare class MatterbridgeEndpoint extends Endpoint {
149
153
  createDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining?: number | null, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: number | null, batReplacementDescription?: string, batQuantity?: number, batReplaceability?: PowerSource.BatReplaceability): this;
150
154
  createDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining?: number | null, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: number | null, batReplaceability?: PowerSource.BatReplaceability): this;
151
155
  createDefaultBasicInformationClusterServer(deviceName: string, serialNumber: string, vendorId?: number, vendorName?: string, productId?: number, productName?: string, softwareVersion?: number, softwareVersionString?: string, hardwareVersion?: number, hardwareVersionString?: string, productLabel?: string, productUrl?: string, configurationVersion?: number): this;
152
- createDefaultBridgedDeviceBasicInformationClusterServer(deviceName: string, serialNumber: string, vendorId?: number, vendorName?: string, productName?: string, softwareVersion?: number, softwareVersionString?: string, hardwareVersion?: number, hardwareVersionString?: string, productLabel?: string, productUrl?: string, configurationVersion?: number): this;
156
+ createDefaultBridgedDeviceBasicInformationClusterServer(deviceName: string, serialNumber: string, vendorId?: number, vendorName?: string, productName?: string, softwareVersion?: number, softwareVersionString?: string, hardwareVersion?: number, hardwareVersionString?: string, productLabel?: string, productUrl?: string, configurationVersion?: number, productId?: number): this;
153
157
  createDefaultPowerTopologyClusterServer(feature?: PowerTopology.Feature, availableEndpoints?: EndpointNumber[], activeEndpoints?: EndpointNumber[]): this;
154
158
  createDefaultElectricalEnergyMeasurementClusterServer(energyImported?: number | bigint | null, energyExported?: number | bigint | null): this;
155
159
  createImportedElectricalEnergyMeasurementClusterServer(energyImported?: number | bigint | null): this;
@@ -85,7 +85,7 @@ import { MatterbridgeValveConfigurationAndControlServer } from './behaviors/valv
85
85
  import { MatterbridgeWaterTankLevelMonitoringServer } from './behaviors/waterTankLevelMonitoringServer.js';
86
86
  import { MatterbridgeWindowCoveringServer } from './behaviors/windowCoveringServer.js';
87
87
  import { CommandHandler, } from './matterbridgeEndpointCommandHandler.js';
88
- import { addClusterClients, addClusterServers, addFixedLabel, addOptionalClusterClients, addOptionalClusterServers, addRequiredClusterClients, addRequiredClusterServers, addUserLabel, checkNotLatinCharacters, createUniqueId, defaultFor, featuresFor, generateUniqueId, getApparentElectricalPowerMeasurementClusterServer, getAttribute, getAttributeId, getBehavior, getBehaviourTypesFromClusterClientIds, getBehaviourTypesFromClusterServerIds, getCluster, getClusterId, getDefaultDeviceEnergyManagementClusterServer, getDefaultDeviceEnergyManagementModeClusterServer, getDefaultElectricalEnergyMeasurementClusterServer, getDefaultElectricalPowerMeasurementClusterServer, getDefaultFlowMeasurementClusterServer, getDefaultIlluminanceMeasurementClusterServer, getDefaultOccupancySensingClusterServer, getDefaultOperationalStateClusterServer, getDefaultPowerSourceBatteryClusterServer, getDefaultPowerSourceRechargeableBatteryClusterServer, getDefaultPowerSourceReplaceableBatteryClusterServer, getDefaultPowerSourceWiredClusterServer, getDefaultPressureMeasurementClusterServer, getDefaultRelativeHumidityMeasurementClusterServer, getDefaultSoilMeasurementClusterServer, getDefaultTemperatureMeasurementClusterServer, getExportedElectricalEnergyMeasurementClusterServer, getImportedElectricalEnergyMeasurementClusterServer, invokeBehaviorCommand, lowercaseFirstLetter, setAttribute, setCluster, subscribeAttribute, subscribeCommand, triggerEvent, updateAttribute, } from './matterbridgeEndpointHelpers.js';
88
+ import { addClusterClients, addClusterServers, addFixedLabel, addOptionalClusterClients, addOptionalClusterServers, addRequiredClusterClients, addRequiredClusterServers, addUserLabel, checkNotLatinCharacters, createUniqueId, defaultFor, emitCommand, featuresFor, generateUniqueId, getApparentElectricalPowerMeasurementClusterServer, getAttribute, getAttributeId, getBehavior, getBehaviourTypesFromClusterClientIds, getBehaviourTypesFromClusterServerIds, getCluster, getClusterId, getDefaultDeviceEnergyManagementClusterServer, getDefaultDeviceEnergyManagementModeClusterServer, getDefaultElectricalEnergyMeasurementClusterServer, getDefaultElectricalPowerMeasurementClusterServer, getDefaultFlowMeasurementClusterServer, getDefaultIlluminanceMeasurementClusterServer, getDefaultOccupancySensingClusterServer, getDefaultOperationalStateClusterServer, getDefaultPowerSourceBatteryClusterServer, getDefaultPowerSourceRechargeableBatteryClusterServer, getDefaultPowerSourceReplaceableBatteryClusterServer, getDefaultPowerSourceWiredClusterServer, getDefaultPressureMeasurementClusterServer, getDefaultRelativeHumidityMeasurementClusterServer, getDefaultSoilMeasurementClusterServer, getDefaultTemperatureMeasurementClusterServer, getExportedElectricalEnergyMeasurementClusterServer, getImportedElectricalEnergyMeasurementClusterServer, invokeBehaviorCommand, lowercaseFirstLetter, setAttribute, setCluster, subscribeAttribute, subscribeCommand, triggerEvent, updateAttribute, } from './matterbridgeEndpointHelpers.js';
89
89
  logModuleLoaded('MatterbridgeEndpoint');
90
90
  const MATTERBRIDGE_ENDPOINT_BRAND = Symbol('MatterbridgeEndpoint.brand');
91
91
  export function isMatterbridgeEndpoint(value) {
@@ -254,6 +254,10 @@ export class MatterbridgeEndpoint extends Endpoint {
254
254
  subscribeCommand(cluster, command, listener, log) {
255
255
  return subscribeCommand(this, cluster, command, listener, log);
256
256
  }
257
+ emitCommand(cluster, command, request, context) {
258
+ const clusterName = typeof cluster === 'string' ? cluster : typeof cluster.id === 'string' ? cluster.id : cluster.name;
259
+ emitCommand(this, clusterName, command, request, context);
260
+ }
257
261
  async setCluster(cluster, value, log) {
258
262
  return await setCluster(this, cluster, value, log);
259
263
  }
@@ -518,7 +522,7 @@ export class MatterbridgeEndpoint extends Endpoint {
518
522
  device.hardwareVersionString = serializedDevice.hardwareVersionString;
519
523
  for (const clusterId of serializedDevice.clusterServersId) {
520
524
  if (clusterId === BridgedDeviceBasicInformation.id)
521
- device.createDefaultBridgedDeviceBasicInformationClusterServer(serializedDevice.deviceName, serializedDevice.serialNumber, serializedDevice.vendorId ?? 0xfff1, serializedDevice.vendorName ?? 'Matterbridge', serializedDevice.productName ?? 'Matterbridge device', serializedDevice.softwareVersion, serializedDevice.softwareVersionString, serializedDevice.hardwareVersion, serializedDevice.hardwareVersionString, serializedDevice.productLabel, serializedDevice.productUrl, serializedDevice.configurationVersion);
525
+ device.createDefaultBridgedDeviceBasicInformationClusterServer(serializedDevice.deviceName, serializedDevice.serialNumber, serializedDevice.vendorId ?? 0xfff1, serializedDevice.vendorName ?? 'Matterbridge', serializedDevice.productName ?? 'Matterbridge device', serializedDevice.softwareVersion, serializedDevice.softwareVersionString, serializedDevice.hardwareVersion, serializedDevice.hardwareVersionString, serializedDevice.productLabel, serializedDevice.productUrl, serializedDevice.configurationVersion, serializedDevice.productId);
522
526
  else if (clusterId === BasicInformation.id)
523
527
  device.createDefaultBasicInformationClusterServer(serializedDevice.deviceName, serializedDevice.serialNumber, serializedDevice.vendorId ?? 0xfff1, serializedDevice.vendorName ?? 'Matterbridge', serializedDevice.productId ?? 0x8000, serializedDevice.productName ?? 'Matterbridge device', serializedDevice.softwareVersion, serializedDevice.softwareVersionString, serializedDevice.hardwareVersion, serializedDevice.hardwareVersionString, serializedDevice.productLabel, serializedDevice.productUrl, serializedDevice.configurationVersion);
524
528
  else if (clusterId === PowerSource.id)
@@ -560,12 +564,12 @@ export class MatterbridgeEndpoint extends Endpoint {
560
564
  this.configurationVersion = configurationVersion;
561
565
  return this;
562
566
  }
563
- createDefaultBridgedDeviceBasicInformationClusterServer(deviceName, serialNumber, vendorId = 0xfff1, vendorName = 'Matterbridge', productName = 'Matterbridge device', softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0', productLabel = 'Matter Bridged Endpoint', productUrl = 'https://matterbridge.io', configurationVersion = 1) {
567
+ createDefaultBridgedDeviceBasicInformationClusterServer(deviceName, serialNumber, vendorId = 0xfff1, vendorName = 'Matterbridge', productName = 'Matterbridge device', softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0', productLabel = 'Matter Bridged Endpoint', productUrl = 'https://matterbridge.io', configurationVersion = 1, productId) {
564
568
  this.log.logName = deviceName;
565
569
  this.deviceName = deviceName;
566
570
  this.serialNumber = serialNumber;
567
571
  this.uniqueId = createUniqueId(deviceName, serialNumber, vendorName, productName);
568
- this.productId = undefined;
572
+ this.productId = productId;
569
573
  this.productName = productName;
570
574
  this.productLabel = productLabel;
571
575
  this.productUrl = productUrl;
@@ -593,6 +597,7 @@ export class MatterbridgeEndpoint extends Endpoint {
593
597
  hardwareVersionString: isValidString(hardwareVersionString, 1, 64) ? hardwareVersionString : '1.0.0',
594
598
  configurationVersion: isValidInteger(configurationVersion, 1, UINT32_MAX) ? configurationVersion : 1,
595
599
  reachable: true,
600
+ ...(isValidInteger(productId, 0, UINT16_MAX) ? { productId } : {}),
596
601
  });
597
602
  return this;
598
603
  }
@@ -59,7 +59,7 @@ export declare function setAttribute(endpoint: MatterbridgeEndpoint, cluster: Be
59
59
  export declare function updateAttribute(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, attribute: string, value: boolean | number | bigint | string | object | null, log?: AnsiLogger): Promise<boolean>;
60
60
  export declare function subscribeAttribute(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, attribute: string, listener: (newValue: any, oldValue: any, context: ActionContext) => void, log?: AnsiLogger): MatterbridgeEndpoint;
61
61
  export declare function subscribeCommand(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, command: string, listener: SubscribeCommandListener, log?: AnsiLogger): MatterbridgeEndpoint;
62
- export declare function emitCommand(endpoint: Endpoint, cluster: string, command: string, request: unknown, context: ActionContext): void;
62
+ export declare function emitCommand(endpoint: MatterbridgeEndpoint, cluster: string, command: string, request: unknown, context: ActionContext): void;
63
63
  export declare function setCluster(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, value: Record<string, boolean | number | bigint | string | object | undefined | null>, log?: AnsiLogger): Promise<boolean>;
64
64
  export declare function getCluster(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, log?: AnsiLogger): Record<string, boolean | number | bigint | string | object | undefined | null> | undefined;
65
65
  export declare function triggerEvent(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, event: string, payload: Record<string, boolean | number | bigint | string | object | undefined | null>, log?: AnsiLogger): Promise<boolean>;
@@ -836,15 +836,10 @@ export function subscribeCommand(endpoint, cluster, command, listener, log) {
836
836
  return endpoint;
837
837
  }
838
838
  export function emitCommand(endpoint, cluster, command, request, context) {
839
- if (!isCommandEndpoint(endpoint))
840
- return;
841
839
  const clusterName = lowercaseFirstLetter(cluster);
842
840
  const commandName = lowercaseFirstLetter(command);
843
841
  getCommandObservable(endpoint, clusterName, commandName, false)?.emit({ command: commandName, cluster: clusterName, request, endpoint, context });
844
842
  }
845
- function isCommandEndpoint(endpoint) {
846
- return 'subscribeCommand' in endpoint && typeof endpoint.subscribeCommand === 'function';
847
- }
848
843
  export async function setCluster(endpoint, cluster, value, log) {
849
844
  const clusterName = getBehavior(endpoint, cluster)?.id;
850
845
  if (!clusterName) {
@@ -247,7 +247,7 @@ export class MatterbridgePlatform {
247
247
  }
248
248
  if (!device.hasClusterServer(BridgedDeviceBasicInformation.id)) {
249
249
  this.log.debug(`Device with name ${CYAN}${device.deviceName}${db} has no BridgedDeviceBasicInformation cluster. Adding it...`);
250
- device.createDefaultBridgedDeviceBasicInformationClusterServer(device.deviceName, device.serialNumber, device.vendorId, device.vendorName, device.productName, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString, device.productLabel === 'Matter Endpoint' ? 'Matter Bridged Endpoint' : device.productLabel, device.productUrl, device.configurationVersion);
250
+ device.createDefaultBridgedDeviceBasicInformationClusterServer(device.deviceName, device.serialNumber, device.vendorId, device.vendorName, device.productName, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString, device.productLabel === 'Matter Endpoint' ? 'Matter Bridged Endpoint' : device.productLabel, device.productUrl, device.configurationVersion, device.productId);
251
251
  }
252
252
  }
253
253
  await this.#addBridgedEndpoint?.(this.name, device);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matterbridge/core",
3
- "version": "3.10.10-dev-20260912-2c1c047",
3
+ "version": "3.10.10-dev-20260914-784e019",
4
4
  "description": "Matterbridge core library",
5
5
  "author": "https://github.com/Luligu",
6
6
  "homepage": "https://matterbridge.io/",
@@ -54,6 +54,10 @@
54
54
  "types": "./dist/devices/export.d.ts",
55
55
  "import": "./dist/devices/export.js"
56
56
  },
57
+ "./devices/camera": {
58
+ "types": "./dist/devices/camera/export.d.ts",
59
+ "import": "./dist/devices/camera/export.js"
60
+ },
57
61
  "./clusters": {
58
62
  "types": "./dist/clusters/export.d.ts",
59
63
  "import": "./dist/clusters/export.js"
@@ -132,10 +136,10 @@
132
136
  },
133
137
  "dependencies": {
134
138
  "@matter/main": "0.17.9",
135
- "@matterbridge/dgram": "3.10.10-dev-20260912-2c1c047",
136
- "@matterbridge/thread": "3.10.10-dev-20260912-2c1c047",
137
- "@matterbridge/types": "3.10.10-dev-20260912-2c1c047",
138
- "@matterbridge/utils": "3.10.10-dev-20260912-2c1c047",
139
+ "@matterbridge/dgram": "3.10.10-dev-20260914-784e019",
140
+ "@matterbridge/thread": "3.10.10-dev-20260914-784e019",
141
+ "@matterbridge/types": "3.10.10-dev-20260914-784e019",
142
+ "@matterbridge/utils": "3.10.10-dev-20260914-784e019",
139
143
  "escape-html": "1.0.3",
140
144
  "express": "5.2.1",
141
145
  "express-rate-limit": "8.7.0",