@matterbridge/core 3.11.0-dev-20261021-c0f9ee2 → 3.11.0-dev-20261022-ad61eed

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.
@@ -1,3 +1,4 @@
1
+ import { type Timer } from '@matter/general';
1
2
  import { CameraAvSettingsUserLevelManagementServer } from '@matter/node/behaviors/camera-av-settings-user-level-management';
2
3
  import { CameraAvSettingsUserLevelManagement } from '@matter/types/clusters/camera-av-settings-user-level-management';
3
4
  import type { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
@@ -11,6 +12,7 @@ declare const MatterbridgeCameraAvSettingsUserLevelManagementServer_base: import
11
12
  mechanicalZoom: true;
12
13
  }>, import("@matter/types").ClusterType.Concrete, new () => {}, "cameraAvSettingsUserLevelManagement">;
13
14
  export declare class MatterbridgeCameraAvSettingsUserLevelManagementServer extends MatterbridgeCameraAvSettingsUserLevelManagementServer_base {
15
+ #private;
14
16
  readonly endpoint: MatterbridgeEndpoint;
15
17
  protected internal: MatterbridgeCameraAvSettingsUserLevelManagementServer.Internal;
16
18
  initialize(): void;
@@ -26,10 +28,13 @@ export declare class MatterbridgeCameraAvSettingsUserLevelManagementServer exten
26
28
  private applyDptzViewport;
27
29
  dptzSetViewport(request: CameraAvSettingsUserLevelManagement.DptzSetViewportRequest): void;
28
30
  dptzRelativeMove(request: CameraAvSettingsUserLevelManagement.DptzRelativeMoveRequest): void;
31
+ [Symbol.asyncDispose](): Promise<void>;
29
32
  }
30
33
  export declare namespace MatterbridgeCameraAvSettingsUserLevelManagementServer {
31
34
  class Internal {
32
35
  lastGeneratedPresetId: number;
36
+ movementTimer?: Timer;
37
+ movementTarget?: CameraAvSettingsUserLevelManagement.Mptz;
33
38
  }
34
39
  }
35
40
  export interface CameraAvSettingsUserLevelManagementClusterOptions {
@@ -1,9 +1,11 @@
1
+ import { Millis, Time } from '@matter/general';
1
2
  import { CameraAvSettingsUserLevelManagementServer } from '@matter/node/behaviors/camera-av-settings-user-level-management';
2
3
  import { CameraAvSettingsUserLevelManagement } from '@matter/types/clusters/camera-av-settings-user-level-management';
3
4
  import { StatusResponseError } from '@matter/types/common';
4
5
  import { Status } from '@matter/types/globals';
5
6
  import { MatterbridgeCameraAvStreamManagementServer } from './cameraAvStreamManagementServer.js';
6
7
  import { MatterbridgeServer } from './matterbridgeServer.js';
8
+ const MPTZ_MOVEMENT_DURATION = Millis(100);
7
9
  function clamp(value, min, max) {
8
10
  return Math.min(Math.max(value, min), max);
9
11
  }
@@ -56,12 +58,14 @@ export class MatterbridgeCameraAvSettingsUserLevelManagementServer extends Camer
56
58
  if (zoom !== undefined && (zoom < 1 || zoom > this.state.zoomMax)) {
57
59
  throw new StatusResponseError(`MatterbridgeCameraAvSettingsUserLevelManagementServer: zoom ${zoom} is outside of the supported range [1, ${this.state.zoomMax}] (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.ConstraintError);
58
60
  }
59
- this.state.mptzPosition = {
61
+ this.#assertNotMoving('mptzSetPosition');
62
+ const target = {
60
63
  pan: pan ?? this.state.mptzPosition.pan,
61
64
  tilt: tilt ?? this.state.mptzPosition.tilt,
62
65
  zoom: zoom ?? this.state.mptzPosition.zoom,
63
66
  };
64
- 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})`);
67
+ device.log.info(`MatterbridgeCameraAvSettingsUserLevelManagementServer: set mechanical PTZ position to pan ${target.pan}°, tilt ${target.tilt}°, zoom ${target.zoom} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
68
+ this.#startMovement(target);
65
69
  this.endpoint.emitCommand(CameraAvSettingsUserLevelManagement, 'mptzSetPosition', request, this.context);
66
70
  }
67
71
  mptzRelativeMove(request) {
@@ -69,12 +73,13 @@ export class MatterbridgeCameraAvSettingsUserLevelManagementServer extends Camer
69
73
  if (request.panDelta === undefined && request.tiltDelta === undefined && request.zoomDelta === undefined) {
70
74
  throw new StatusResponseError(`MatterbridgeCameraAvSettingsUserLevelManagementServer: mptzRelativeMove requires at least one of panDelta, tiltDelta or zoomDelta to be present (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.InvalidCommand);
71
75
  }
76
+ this.#assertNotMoving('mptzRelativeMove');
72
77
  const current = this.state.mptzPosition;
73
78
  const pan = request.panDelta === undefined ? current.pan : clamp((current.pan ?? 0) + request.panDelta, this.state.panMin, this.state.panMax);
74
79
  const tilt = request.tiltDelta === undefined ? current.tilt : clamp((current.tilt ?? 0) + request.tiltDelta, this.state.tiltMin, this.state.tiltMax);
75
80
  const zoom = request.zoomDelta === undefined ? current.zoom : clamp((current.zoom ?? 1) + request.zoomDelta, 1, this.state.zoomMax);
76
- this.state.mptzPosition = { pan, tilt, zoom };
77
81
  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})`);
82
+ this.#startMovement({ pan, tilt, zoom });
78
83
  this.endpoint.emitCommand(CameraAvSettingsUserLevelManagement, 'mptzRelativeMove', request, this.context);
79
84
  }
80
85
  mptzMoveToPreset(request) {
@@ -87,10 +92,28 @@ export class MatterbridgeCameraAvSettingsUserLevelManagementServer extends Camer
87
92
  if (preset === undefined) {
88
93
  throw new StatusResponseError(`MatterbridgeCameraAvSettingsUserLevelManagementServer: presetId ${presetId} is not present in mptzPresets (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.NotFound);
89
94
  }
90
- this.state.mptzPosition = preset.settings;
95
+ this.#assertNotMoving('mptzMoveToPreset');
91
96
  device.log.info(`MatterbridgeCameraAvSettingsUserLevelManagementServer: moved mechanical PTZ position to preset ${presetId} "${preset.name}": pan ${preset.settings.pan}°, tilt ${preset.settings.tilt}°, zoom ${preset.settings.zoom} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
97
+ this.#startMovement(preset.settings);
92
98
  this.endpoint.emitCommand(CameraAvSettingsUserLevelManagement, 'mptzMoveToPreset', request, this.context);
93
99
  }
100
+ #assertNotMoving(command) {
101
+ if (this.state.movementState === CameraAvSettingsUserLevelManagement.PhysicalMovement.Moving) {
102
+ throw new StatusResponseError(`MatterbridgeCameraAvSettingsUserLevelManagementServer: ${command} rejected, the camera is already moving (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.Busy);
103
+ }
104
+ }
105
+ #startMovement(target) {
106
+ this.state.movementState = CameraAvSettingsUserLevelManagement.PhysicalMovement.Moving;
107
+ this.internal.movementTarget = target;
108
+ this.internal.movementTimer = Time.getTimer('CameraAvSettingsUserLevelManagement movement complete', MPTZ_MOVEMENT_DURATION, this.callback(this.#completeMovement, { lock: true })).start();
109
+ }
110
+ #completeMovement() {
111
+ this.internal.movementTimer = undefined;
112
+ if (this.internal.movementTarget !== undefined)
113
+ this.state.mptzPosition = this.internal.movementTarget;
114
+ this.internal.movementTarget = undefined;
115
+ this.state.movementState = CameraAvSettingsUserLevelManagement.PhysicalMovement.Idle;
116
+ }
94
117
  mptzSavePreset(request) {
95
118
  const device = this.endpoint.stateOf(MatterbridgeServer);
96
119
  const { presetId, name } = request;
@@ -205,10 +228,17 @@ export class MatterbridgeCameraAvSettingsUserLevelManagementServer extends Camer
205
228
  device.log.info(`MatterbridgeCameraAvSettingsUserLevelManagementServer: moved the viewport of video stream ${videoStreamId} by deltaX ${deltaX ?? 0}, deltaY ${deltaY ?? 0}, zoomDelta ${zoomDelta ?? 0} to (${viewport.x1}, ${viewport.y1})-(${viewport.x2}, ${viewport.y2}) (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
206
229
  this.endpoint.emitCommand(CameraAvSettingsUserLevelManagement, 'dptzRelativeMove', request, this.context);
207
230
  }
231
+ async [Symbol.asyncDispose]() {
232
+ this.internal.movementTimer?.stop();
233
+ this.internal.movementTimer = undefined;
234
+ await super[Symbol.asyncDispose]?.();
235
+ }
208
236
  }
209
237
  (function (MatterbridgeCameraAvSettingsUserLevelManagementServer) {
210
238
  class Internal {
211
239
  lastGeneratedPresetId = 0;
240
+ movementTimer;
241
+ movementTarget;
212
242
  }
213
243
  MatterbridgeCameraAvSettingsUserLevelManagementServer.Internal = Internal;
214
244
  })(MatterbridgeCameraAvSettingsUserLevelManagementServer || (MatterbridgeCameraAvSettingsUserLevelManagementServer = {}));
package/dist/chipTests.js CHANGED
@@ -52,6 +52,11 @@ const smokeCoAlarmHardwareFaultAlertTrigger = 0xffffffff00000093n;
52
52
  const smokeCoAlarmHardwareFaultAlertClearTrigger = 0xffffffff000000a3n;
53
53
  const smokeCoAlarmEndOfServiceAlertTrigger = 0xffffffff0000009an;
54
54
  const smokeCoAlarmEndOfServiceAlertClearTrigger = 0xffffffff000000aan;
55
+ const smokeCoAlarmYamlCriticalBatteryAlertTrigger = 0x005c00000000009en;
56
+ const smokeCoAlarmYamlHardwareFaultAlertTrigger = 0x005c000000000093n;
57
+ const smokeCoAlarmYamlHardwareFaultAlertClearTrigger = 0x005c0000000000a3n;
58
+ const smokeCoAlarmYamlEndOfServiceAlertTrigger = 0x005c00000000009an;
59
+ const smokeCoAlarmYamlEndOfServiceAlertClearTrigger = 0x005c0000000000aan;
55
60
  const smokeCoAlarmDeviceMutedTrigger = 0x005c00000000009bn;
56
61
  const smokeCoAlarmDeviceMutedClearTrigger = 0x005c0000000000abn;
57
62
  const electricalPowerMeasurementStartFakeLoadTrigger = 0x0091000000000001n;
@@ -299,7 +304,7 @@ export function createChipTestAppPipe(matterbridge) {
299
304
  return;
300
305
  matterbridge.log.error(`CHIP test app pipe ${chipTestAppPipePath} read error: ${error instanceof Error ? error.message : String(error)}`);
301
306
  }
302
- }, 50);
307
+ }, 10);
303
308
  pollInterval.unref();
304
309
  const closePipeWithInterval = () => {
305
310
  clearInterval(pollInterval);
@@ -340,6 +345,11 @@ async function handleChipTestEventTrigger(eventTrigger) {
340
345
  normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmHardwareFaultAlertClearTrigger) &&
341
346
  normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmEndOfServiceAlertTrigger) &&
342
347
  normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmEndOfServiceAlertClearTrigger) &&
348
+ normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmYamlCriticalBatteryAlertTrigger) &&
349
+ normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmYamlHardwareFaultAlertTrigger) &&
350
+ normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmYamlHardwareFaultAlertClearTrigger) &&
351
+ normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmYamlEndOfServiceAlertTrigger) &&
352
+ normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmYamlEndOfServiceAlertClearTrigger) &&
343
353
  normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmDeviceMutedTrigger) &&
344
354
  normalizedEventTrigger !== normalizeTestEventTrigger(smokeCoAlarmDeviceMutedClearTrigger)) {
345
355
  return ((await handleElectricalEnergyTestEventTrigger(normalizedEventTrigger)) ||
@@ -606,6 +616,7 @@ async function applySmokeCoAlarmTestEventTrigger(endpoint, eventTrigger, log) {
606
616
  await endpoint.triggerEvent(SmokeCoAlarm, 'lowBattery', { alarmSeverityLevel: SmokeCoAlarm.AlarmState.Warning }, log);
607
617
  return;
608
618
  case normalizeTestEventTrigger(smokeCoAlarmCriticalBatteryAlertTrigger):
619
+ case normalizeTestEventTrigger(smokeCoAlarmYamlCriticalBatteryAlertTrigger):
609
620
  await endpoint.setCluster(SmokeCoAlarm, { batteryAlert: SmokeCoAlarm.AlarmState.Critical, expressedState: getSmokeCoAlarmExpressedState(endpoint, { batteryAlert: SmokeCoAlarm.AlarmState.Critical }) }, log);
610
621
  await endpoint.triggerEvent(SmokeCoAlarm, 'lowBattery', { alarmSeverityLevel: SmokeCoAlarm.AlarmState.Critical }, log);
611
622
  return;
@@ -615,18 +626,22 @@ async function applySmokeCoAlarmTestEventTrigger(endpoint, eventTrigger, log) {
615
626
  await endpoint.triggerEvent(SmokeCoAlarm, 'allClear', undefined, log);
616
627
  return;
617
628
  case normalizeTestEventTrigger(smokeCoAlarmHardwareFaultAlertTrigger):
629
+ case normalizeTestEventTrigger(smokeCoAlarmYamlHardwareFaultAlertTrigger):
618
630
  await endpoint.setCluster(SmokeCoAlarm, { hardwareFaultAlert: true, expressedState: SmokeCoAlarm.ExpressedState.HardwareFault }, log);
619
631
  await endpoint.triggerEvent(SmokeCoAlarm, 'hardwareFault', undefined, log);
620
632
  return;
621
633
  case normalizeTestEventTrigger(smokeCoAlarmHardwareFaultAlertClearTrigger):
634
+ case normalizeTestEventTrigger(smokeCoAlarmYamlHardwareFaultAlertClearTrigger):
622
635
  await endpoint.setCluster(SmokeCoAlarm, { hardwareFaultAlert: false, expressedState: SmokeCoAlarm.ExpressedState.Normal }, log);
623
636
  await endpoint.triggerEvent(SmokeCoAlarm, 'allClear', undefined, log);
624
637
  return;
625
638
  case normalizeTestEventTrigger(smokeCoAlarmEndOfServiceAlertTrigger):
639
+ case normalizeTestEventTrigger(smokeCoAlarmYamlEndOfServiceAlertTrigger):
626
640
  await endpoint.setCluster(SmokeCoAlarm, { endOfServiceAlert: SmokeCoAlarm.EndOfService.Expired, expressedState: SmokeCoAlarm.ExpressedState.EndOfService }, log);
627
641
  await endpoint.triggerEvent(SmokeCoAlarm, 'endOfService', undefined, log);
628
642
  return;
629
643
  case normalizeTestEventTrigger(smokeCoAlarmEndOfServiceAlertClearTrigger):
644
+ case normalizeTestEventTrigger(smokeCoAlarmYamlEndOfServiceAlertClearTrigger):
630
645
  await endpoint.setCluster(SmokeCoAlarm, { endOfServiceAlert: SmokeCoAlarm.EndOfService.Normal, expressedState: SmokeCoAlarm.ExpressedState.Normal }, log);
631
646
  await endpoint.triggerEvent(SmokeCoAlarm, 'allClear', undefined, log);
632
647
  return;
@@ -1172,6 +1187,10 @@ async function handleChipTestAppPipeCommand(matterbridge, command) {
1172
1187
  case 'SimulateLongPress':
1173
1188
  await simulateChipTestSwitchLongPress(matterbridge, endpoint, endpointId, command);
1174
1189
  return;
1190
+ case 'LongPress':
1191
+ await endpoint.invokeBehaviorCommand(SmokeCoAlarm, 'selfTestRequest');
1192
+ matterbridge.log.info(`CHIP test app pipe started the SmokeCoAlarm self-test on endpoint ${endpointId}`);
1193
+ return;
1175
1194
  case 'SimulateLatchPosition': {
1176
1195
  const newPosition = command.PositionId ?? 0;
1177
1196
  if (endpoint.getAttribute(Switch.id, 'currentPosition', matterbridge.log) === newPosition) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matterbridge/core",
3
- "version": "3.11.0-dev-20261021-c0f9ee2",
3
+ "version": "3.11.0-dev-20261022-ad61eed",
4
4
  "description": "Matterbridge core library",
5
5
  "author": "https://github.com/Luligu",
6
6
  "homepage": "https://matterbridge.io/",
@@ -136,10 +136,10 @@
136
136
  },
137
137
  "dependencies": {
138
138
  "@matter/main": "0.18.0",
139
- "@matterbridge/dgram": "3.11.0-dev-20261021-c0f9ee2",
140
- "@matterbridge/thread": "3.11.0-dev-20261021-c0f9ee2",
141
- "@matterbridge/types": "3.11.0-dev-20261021-c0f9ee2",
142
- "@matterbridge/utils": "3.11.0-dev-20261021-c0f9ee2",
139
+ "@matterbridge/dgram": "3.11.0-dev-20261022-ad61eed",
140
+ "@matterbridge/thread": "3.11.0-dev-20261022-ad61eed",
141
+ "@matterbridge/types": "3.11.0-dev-20261022-ad61eed",
142
+ "@matterbridge/utils": "3.11.0-dev-20261022-ad61eed",
143
143
  "escape-html": "1.0.3",
144
144
  "express": "5.3.0",
145
145
  "express-rate-limit": "8.7.1",