@matterbridge/core 3.10.6 → 3.10.7-dev-20260822-149e3eb

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,4 +1,4 @@
1
- import { CommonNumberTag } from '@matter/node';
1
+ import { ClosureTag, ClosureWindowTag, CommonNumberTag } from '@matter/node';
2
2
  import { AirQuality } from '@matter/types/clusters/air-quality';
3
3
  import { FanControl } from '@matter/types/clusters/fan-control';
4
4
  import { PowerSource } from '@matter/types/clusters/power-source';
@@ -205,6 +205,27 @@ export async function createDemoDevices(matterbridge) {
205
205
  await registerDevice(ep, 'Window Covering Controller', 'ENTRY-08-04');
206
206
  ep = new Closure('Closure', 'ENTRY-08-05', { id: 'Closure', number: EndpointNumber(8_05) });
207
207
  await registerDevice(ep, 'Closure', 'ENTRY-08-05');
208
+ ep = new Closure('Closure Pedestrian', 'ENTRY-08-05-1', {
209
+ id: 'ClosurePedestrian',
210
+ number: EndpointNumber(8_05_1),
211
+ pedestrian: true,
212
+ tagList: [getSemtag(ClosureTag.Gate)],
213
+ });
214
+ await registerDevice(ep, 'Closure Pedestrian', 'ENTRY-08-05-1');
215
+ ep = new Closure('Closure Ventilation', 'ENTRY-08-05-2', {
216
+ id: 'ClosureVentilation',
217
+ number: EndpointNumber(8_05_2),
218
+ ventilation: true,
219
+ tagList: [getSemtag(ClosureTag.Window), getSemtag(ClosureWindowTag.Facade)],
220
+ });
221
+ await registerDevice(ep, 'Closure Ventilation', 'ENTRY-08-05-2');
222
+ ep = new Closure('Closure Calibrate', 'ENTRY-08-05-3', {
223
+ id: 'ClosureCalibrate',
224
+ number: EndpointNumber(8_05_3),
225
+ calibration: true,
226
+ tagList: [getSemtag(ClosureTag.GarageDoor)],
227
+ });
228
+ await registerDevice(ep, 'Closure Calibrate', 'ENTRY-08-05-3');
208
229
  ep = new MatterbridgeEndpoint([getSupportedDeviceType('ClosureController'), bridgedNode, powerSource], { id: 'ClosureController', number: EndpointNumber(8_07) });
209
230
  await registerDevice(ep, 'Closure Controller', 'ENTRY-08-07');
210
231
  ep = new MatterbridgeEndpoint([getSupportedDeviceType('Thermostat'), bridgedNode, powerSource], { id: 'Thermostat', number: EndpointNumber(9_01) });
@@ -6,7 +6,7 @@ import type { Semtag } from '@matter/types/globals';
6
6
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
7
7
  import { type ClosureDimensionType, type ClosurePanelOptions } from './closurePanel.js';
8
8
  declare const MatterbridgeClosureControlServer_base: import("@matter/node").ClusterBehavior.Type<typeof ClosureControlServer, import("@matter/types").ClusterType.WithSupportedFeatures<ClosureControl, {
9
- calibration: false;
9
+ calibration: true;
10
10
  instantaneous: false;
11
11
  manuallyOperable: false;
12
12
  motionLatching: true;
@@ -19,6 +19,7 @@ declare const MatterbridgeClosureControlServer_base: import("@matter/node").Clus
19
19
  export declare class MatterbridgeClosureControlServer extends MatterbridgeClosureControlServer_base {
20
20
  moveTo: (request: ClosureControl.MoveToRequest) => Promise<void>;
21
21
  stop: () => Promise<void>;
22
+ calibrate: () => Promise<void>;
22
23
  }
23
24
  export interface ClosureOptions {
24
25
  identifyTime?: number;
@@ -30,6 +31,9 @@ export interface ClosureOptions {
30
31
  overallCurrentState?: ClosureControl.OverallCurrentState;
31
32
  overallTargetState?: ClosureControl.OverallTargetState;
32
33
  latchControlModes?: ClosureControl.LatchControlModes;
34
+ ventilation?: boolean;
35
+ pedestrian?: boolean;
36
+ calibration?: boolean;
33
37
  id?: string;
34
38
  number?: EndpointNumber;
35
39
  tagList?: Semtag[];
@@ -9,7 +9,7 @@ import { closure, closurePanel, powerSource } from '../matterbridgeDeviceTypes.j
9
9
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
10
10
  import { getSemtag } from '../matterbridgeEndpointHelpers.js';
11
11
  import { createClosureDimensionClusterServer } from './closurePanel.js';
12
- export class MatterbridgeClosureControlServer extends ClosureControlServer.with(ClosureControl.Feature.Positioning, ClosureControl.Feature.MotionLatching, ClosureControl.Feature.Speed) {
12
+ export class MatterbridgeClosureControlServer extends ClosureControlServer.with(ClosureControl.Feature.Positioning, ClosureControl.Feature.MotionLatching, ClosureControl.Feature.Speed, ClosureControl.Feature.Calibration) {
13
13
  moveTo = async (request) => {
14
14
  const device = this.endpoint.stateOf(MatterbridgeServer);
15
15
  device.log.info(`MoveTo (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
@@ -62,6 +62,24 @@ export class MatterbridgeClosureControlServer extends ClosureControlServer.with(
62
62
  this.state.mainState = ClosureControl.MainState.Stopped;
63
63
  }
64
64
  };
65
+ calibrate = async () => {
66
+ const device = this.endpoint.stateOf(MatterbridgeServer);
67
+ device.log.info(`Calibrate (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
68
+ await device.commandHandler.executeHandler('ClosureControl.calibrate', {
69
+ command: 'calibrate',
70
+ request: {},
71
+ cluster: ClosureControlServer.id,
72
+ attributes: this.state,
73
+ endpoint: this.endpoint,
74
+ });
75
+ if (this.state.mainState === ClosureControl.MainState.Calibrating) {
76
+ return;
77
+ }
78
+ if (![ClosureControl.MainState.Stopped, ClosureControl.MainState.SetupRequired].includes(this.state.mainState)) {
79
+ throw new StatusResponse.InvalidInStateError('ClosureControl.calibrate is only allowed while Stopped or SetupRequired');
80
+ }
81
+ this.state.mainState = ClosureControl.MainState.Calibrating;
82
+ };
65
83
  }
66
84
  export class Closure extends MatterbridgeEndpoint {
67
85
  constructor(name, serial, options = {}) {
@@ -74,7 +92,7 @@ export class Closure extends MatterbridgeEndpoint {
74
92
  position: ClosureControl.TargetPosition.MoveToFullyClosed,
75
93
  latch: true,
76
94
  speed: ThreeLevelAuto.Auto,
77
- }, latchControlModes = { remoteLatching: true, remoteUnlatching: true }, id, number, tagList = [getSemtag(ClosureTag.Covering)], } = options;
95
+ }, latchControlModes = { remoteLatching: true, remoteUnlatching: true }, ventilation = false, pedestrian = false, calibration = false, id, number, tagList = [getSemtag(ClosureTag.Covering)], } = options;
78
96
  super(powerSourceType === 'None' ? [closure] : [closure, powerSource], {
79
97
  id: id ?? `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`,
80
98
  number,
@@ -98,14 +116,17 @@ export class Closure extends MatterbridgeEndpoint {
98
116
  case 'None':
99
117
  break;
100
118
  }
101
- this.behaviors.require(MatterbridgeClosureControlServer, {
119
+ const closureControlOptions = {
102
120
  countdownTime,
103
121
  mainState,
104
122
  currentErrorList,
105
123
  overallCurrentState,
106
124
  overallTargetState,
107
125
  latchControlModes,
108
- });
126
+ };
127
+ this.behaviors.require(calibration || ventilation || pedestrian
128
+ ? MatterbridgeClosureControlServer.with(ClosureControl.Feature.Positioning, ClosureControl.Feature.MotionLatching, ClosureControl.Feature.Speed, ...(calibration ? [ClosureControl.Feature.Calibration] : []), ...(ventilation ? [ClosureControl.Feature.Ventilation] : []), ...(pedestrian ? [ClosureControl.Feature.Pedestrian] : []))
129
+ : MatterbridgeClosureControlServer, closureControlOptions);
109
130
  }
110
131
  getMainState() {
111
132
  return this.getAttribute(ClosureControlServer, 'mainState');
package/dist/frontend.js CHANGED
@@ -17,6 +17,7 @@ import { SoilMeasurement } from '@matter/types/clusters/soil-measurement';
17
17
  import { ValveConfigurationAndControl } from '@matter/types/clusters/valve-configuration-and-control';
18
18
  import { CommissioningOptions } from '@matter/types/commissioning';
19
19
  import { FabricIndex } from '@matter/types/datatype';
20
+ import { ThreeLevelAuto } from '@matter/types/globals';
20
21
  import { BroadcastServer } from '@matterbridge/thread/server';
21
22
  import { MATTER_LOGGER_FILE, MATTER_STORAGE_DIR, MATTERBRIDGE_DIAGNOSTIC_FILE, MATTERBRIDGE_HISTORY_FILE, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg, } from '@matterbridge/types';
22
23
  import { isBun } from '@matterbridge/utils/bun';
@@ -1126,11 +1127,12 @@ export class Frontend extends EventEmitter {
1126
1127
  if (clusterName === 'doorLock' && attributeName === 'lockState')
1127
1128
  attributes += `State: ${attributeValue === 1 ? 'Locked' : 'Not locked'} `;
1128
1129
  if (clusterName === 'closureControl' && attributeName === 'overallCurrentState' && attributeValue === null)
1129
- attributes += `Position: unknown Latch: unknown SecureState: unknown `;
1130
+ attributes += `Position: unknown Latch: unknown Speed: unknown SecureState: unknown `;
1130
1131
  if (clusterName === 'closureControl' && attributeName === 'overallCurrentState' && isValidObject(attributeValue)) {
1131
1132
  const overallCurrentState = attributeValue;
1132
1133
  attributes += `Position: ${getEnumDescription(ClosureControl.CurrentPosition, overallCurrentState.position, { fallback: 'unknown' })} `;
1133
1134
  attributes += `Latch: ${overallCurrentState.latch ?? 'unknown'} `;
1135
+ attributes += `Speed: ${getEnumDescription(ThreeLevelAuto, overallCurrentState.speed, { fallback: 'unknown' })} `;
1134
1136
  attributes += `SecureState: ${overallCurrentState.secureState ?? 'unknown'} `;
1135
1137
  }
1136
1138
  if (clusterName === 'thermostat' && attributeName === 'localTemperature' && isValidNumber(attributeValue))
@@ -376,6 +376,13 @@ export type CommandHandlerDataMap = {
376
376
  attributes: ClusterAttributeValues<(typeof ClosureControl)['attributes']>;
377
377
  endpoint: MatterbridgeEndpoint;
378
378
  };
379
+ 'ClosureControl.calibrate': {
380
+ command: 'calibrate';
381
+ request: {};
382
+ cluster: 'closureControl';
383
+ attributes: ClusterAttributeValues<(typeof ClosureControl)['attributes']>;
384
+ endpoint: MatterbridgeEndpoint;
385
+ };
379
386
  'setTarget': CommandHandlerData<'ClosureDimension.setTarget'>;
380
387
  'ClosureDimension.setTarget': {
381
388
  command: 'setTarget';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matterbridge/core",
3
- "version": "3.10.6",
3
+ "version": "3.10.7-dev-20260822-149e3eb",
4
4
  "description": "Matterbridge core library",
5
5
  "author": "https://github.com/Luligu",
6
6
  "homepage": "https://matterbridge.io/",
@@ -132,10 +132,10 @@
132
132
  },
133
133
  "dependencies": {
134
134
  "@matter/main": "0.17.9",
135
- "@matterbridge/dgram": "3.10.6",
136
- "@matterbridge/thread": "3.10.6",
137
- "@matterbridge/types": "3.10.6",
138
- "@matterbridge/utils": "3.10.6",
135
+ "@matterbridge/dgram": "3.10.7-dev-20260822-149e3eb",
136
+ "@matterbridge/thread": "3.10.7-dev-20260822-149e3eb",
137
+ "@matterbridge/types": "3.10.7-dev-20260822-149e3eb",
138
+ "@matterbridge/utils": "3.10.7-dev-20260822-149e3eb",
139
139
  "escape-html": "1.0.3",
140
140
  "express": "5.2.1",
141
141
  "express-rate-limit": "8.6.2",