@matterbridge/core 3.7.2-dev-20260330-bb55c39 → 3.7.2-dev-20260402-c12a10e

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,7 +1,13 @@
1
1
  import { DoorLockServer } from '@matter/node/behaviors/door-lock';
2
+ import { hasRemoteActor } from '@matter/protocol';
2
3
  import { DoorLock } from '@matter/types/clusters/door-lock';
4
+ import { StatusResponse } from '@matter/types/common';
5
+ import { FabricIndex } from '@matter/types/datatype';
6
+ import { Status } from '@matter/types/globals';
7
+ import { getEnumDescription } from '@matterbridge/utils/enum';
8
+ import { debugStringify } from 'node-ansi-logger';
3
9
  import { MatterbridgeServer } from './matterbridgeServer.js';
4
- export class MatterbridgeDoorLockServer extends DoorLockServer.enable({
10
+ export class MatterbridgeDoorLockServer extends DoorLockServer.with(DoorLock.Feature.User, DoorLock.Feature.PinCredential).enable({
5
11
  events: { doorLockAlarm: true, lockOperation: true, lockOperationError: true },
6
12
  commands: { lockDoor: true, unlockDoor: true, unlockWithTimeout: true },
7
13
  }) {
@@ -43,7 +49,7 @@ export class MatterbridgeDoorLockServer extends DoorLockServer.enable({
43
49
  endpoint: this.endpoint,
44
50
  context: this.context,
45
51
  });
46
- device.log.debug(`MatterbridgeDoorLockServer: unlockDoor called`);
52
+ device.log.debug(`MatterbridgeDoorLockServer: unlockDoor called ${this.state.autoRelockTime ? 'with ' + this.state.autoRelockTime + ' seconds' : 'without'} autoRelockTime ${this.internal.enableTimeout ? 'with' : 'without'} enableTimeout`);
47
53
  await super.unlockDoor(request);
48
54
  if (!this.internal.enableTimeout)
49
55
  return;
@@ -52,9 +58,9 @@ export class MatterbridgeDoorLockServer extends DoorLockServer.enable({
52
58
  this.internal.unlockTimeout = setTimeout(async () => {
53
59
  this.internal.unlockTimeout = undefined;
54
60
  const device = this.endpoint.stateOf(MatterbridgeServer);
55
- const state = this.endpoint.stateOf(MatterbridgeDoorLockServer);
61
+ const state = this.endpoint.stateOf(MatterbridgeDoorLockServer.with());
56
62
  device.log.info(`Auto-relocking door after ${state.autoRelockTime} seconds (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
57
- await this.endpoint.act((agent) => agent.get(MatterbridgeDoorLockServer).lockDoor({ pinCode: request.pinCode }));
63
+ await this.endpoint.act((agent) => agent.get(MatterbridgeDoorLockServer.with()).lockDoor({ pinCode: request.pinCode }));
58
64
  }, this.state.autoRelockTime * 1000).unref();
59
65
  }
60
66
  }
@@ -73,7 +79,7 @@ export class MatterbridgeDoorLockServer extends DoorLockServer.enable({
73
79
  endpoint: this.endpoint,
74
80
  context: this.context,
75
81
  });
76
- device.log.debug(`MatterbridgeDoorLockServer: unlockWithTimeout called`);
82
+ device.log.debug(`MatterbridgeDoorLockServer: unlockWithTimeout called ${this.internal.enableTimeout ? 'with' : 'without'} enableTimeout`);
77
83
  this.state.lockState = DoorLock.LockState.Unlocked;
78
84
  if (!this.internal.enableTimeout)
79
85
  return;
@@ -83,15 +89,355 @@ export class MatterbridgeDoorLockServer extends DoorLockServer.enable({
83
89
  this.internal.unlockTimeout = undefined;
84
90
  const device = this.endpoint.stateOf(MatterbridgeServer);
85
91
  device.log.info(`Locking door after ${request.timeout} seconds (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
86
- await this.endpoint.act((agent) => agent.get(MatterbridgeDoorLockServer).lockDoor({ pinCode: request.pinCode }));
92
+ await this.endpoint.act((agent) => agent.get(MatterbridgeDoorLockServer.with()).lockDoor({ pinCode: request.pinCode }));
87
93
  }, request.timeout * 1000).unref();
88
94
  }
89
95
  }
96
+ async setUser(request) {
97
+ const device = this.endpoint.stateOf(MatterbridgeServer);
98
+ const accessingFabricIndex = this.getAccessingFabricIndex();
99
+ device.log.info(`Setting user operationType ${getEnumDescription(DoorLock.DataOperationType, request.operationType)} userIndex ${request.userIndex} userName ${request.userName ?? 'null'} userUniqueId ${request.userUniqueId ?? 'null'} userStatus ${getEnumDescription(DoorLock.UserStatus, request.userStatus, { fallback: 'null' })} userType ${getEnumDescription(DoorLock.UserType, request.userType, { fallback: 'null' })} credentialRule ${getEnumDescription(DoorLock.CredentialRule, request.credentialRule, { fallback: 'null' })} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
100
+ device.log.debug(`MatterbridgeDoorLockServer: setUser accessingFabricIndex ${accessingFabricIndex ?? 'null'}`);
101
+ await device.commandHandler.executeHandler('DoorLock.setUser', {
102
+ command: 'setUser',
103
+ request,
104
+ cluster: DoorLockServer.id,
105
+ attributes: this.state,
106
+ endpoint: this.endpoint,
107
+ context: this.context,
108
+ });
109
+ const user = this.internal.users.find((storedUser) => storedUser.userIndex === request.userIndex);
110
+ device.log.debug(`MatterbridgeDoorLockServer: setUser called for userIndex ${request.userIndex} (${user ? 'existing user ' + debugStringify(user) : 'new user'})`);
111
+ if (!user && request.operationType === DoorLock.DataOperationType.Add) {
112
+ this.internal.users.push({
113
+ userIndex: request.userIndex,
114
+ userName: request.userName ?? '',
115
+ userUniqueId: request.userUniqueId ?? 0xffffffff,
116
+ userStatus: request.userStatus ?? DoorLock.UserStatus.OccupiedEnabled,
117
+ userType: request.userType ?? DoorLock.UserType.UnrestrictedUser,
118
+ credentialRule: request.credentialRule ?? DoorLock.CredentialRule.Single,
119
+ credentials: [],
120
+ creatorFabricIndex: accessingFabricIndex,
121
+ lastModifiedFabricIndex: accessingFabricIndex,
122
+ });
123
+ this.events.lockUserChange.emit({
124
+ lockDataType: DoorLock.LockDataType.UserIndex,
125
+ dataOperationType: DoorLock.DataOperationType.Add,
126
+ operationSource: this.getOperationSource(),
127
+ userIndex: request.userIndex,
128
+ fabricIndex: accessingFabricIndex,
129
+ sourceNode: this.getAccessingNodeId(),
130
+ dataIndex: request.userIndex,
131
+ }, this.context);
132
+ device.log.debug(`MatterbridgeDoorLockServer: added userIndex ${request.userIndex} (total users: ${this.internal.users.length}) to internal state: ${debugStringify(this.internal.users.find((storedUser) => storedUser.userIndex === request.userIndex))}`);
133
+ }
134
+ else if (user && request.operationType === DoorLock.DataOperationType.Modify) {
135
+ user.userName = request.userName ?? user.userName;
136
+ user.userUniqueId = request.userUniqueId ?? user.userUniqueId;
137
+ user.userStatus = request.userStatus ?? user.userStatus;
138
+ user.userType = request.userType ?? user.userType;
139
+ user.credentialRule = request.credentialRule ?? user.credentialRule;
140
+ user.lastModifiedFabricIndex = accessingFabricIndex;
141
+ this.events.lockUserChange.emit({
142
+ lockDataType: DoorLock.LockDataType.UserIndex,
143
+ dataOperationType: DoorLock.DataOperationType.Modify,
144
+ operationSource: this.getOperationSource(),
145
+ userIndex: request.userIndex,
146
+ fabricIndex: accessingFabricIndex,
147
+ sourceNode: this.getAccessingNodeId(),
148
+ dataIndex: request.userIndex,
149
+ }, this.context);
150
+ device.log.debug(`MatterbridgeDoorLockServer: modified userIndex ${request.userIndex} (total users: ${this.internal.users.length}) in internal state: ${debugStringify(user)}`);
151
+ }
152
+ }
153
+ async getUser(request) {
154
+ const device = this.endpoint.stateOf(MatterbridgeServer);
155
+ device.log.info(`Getting userIndex ${request.userIndex} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
156
+ const response = await device.commandHandler.executeHandler('DoorLock.getUser', {
157
+ command: 'getUser',
158
+ request,
159
+ cluster: DoorLockServer.id,
160
+ attributes: this.state,
161
+ endpoint: this.endpoint,
162
+ context: this.context,
163
+ });
164
+ if (response !== undefined) {
165
+ return response;
166
+ }
167
+ device.log.debug(`MatterbridgeDoorLockServer: getUser called for userIndex ${request.userIndex}`);
168
+ if (!this.validateUserIndex(request.userIndex))
169
+ throw new StatusResponse.InvalidCommandError('Invalid userIndex in GetUser request');
170
+ const user = this.internal.users.find((storedUser) => storedUser.userIndex === request.userIndex);
171
+ if (!user) {
172
+ return {
173
+ userIndex: request.userIndex,
174
+ userName: null,
175
+ userUniqueId: null,
176
+ userStatus: null,
177
+ userType: null,
178
+ credentialRule: null,
179
+ credentials: null,
180
+ creatorFabricIndex: null,
181
+ lastModifiedFabricIndex: null,
182
+ nextUserIndex: null,
183
+ };
184
+ }
185
+ return {
186
+ ...user,
187
+ credentials: user.credentials?.map(({ credentialType, credentialIndex }) => ({ credentialType, credentialIndex })) ?? null,
188
+ nextUserIndex: this.getNextUserIndex(request.userIndex),
189
+ };
190
+ }
191
+ async clearUser(request) {
192
+ const device = this.endpoint.stateOf(MatterbridgeServer);
193
+ const accessingFabricIndex = this.getAccessingFabricIndex();
194
+ device.log.info(`Clearing userIndex ${request.userIndex} ${request.userIndex === 0xfffe ? '(all users)' : ''} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
195
+ await device.commandHandler.executeHandler('DoorLock.clearUser', {
196
+ command: 'clearUser',
197
+ request,
198
+ cluster: DoorLockServer.id,
199
+ attributes: this.state,
200
+ endpoint: this.endpoint,
201
+ context: this.context,
202
+ });
203
+ device.log.debug(`MatterbridgeDoorLockServer: clearUser called for userIndex ${request.userIndex}`);
204
+ if (request.userIndex != 0xfffe && !this.validateUserIndex(request.userIndex))
205
+ throw new StatusResponse.InvalidCommandError('Invalid userIndex in ClearUser request');
206
+ if (request.userIndex === 0xfffe) {
207
+ this.internal.users = [];
208
+ }
209
+ else {
210
+ this.internal.users = this.internal.users.filter((storedUser) => storedUser.userIndex !== request.userIndex);
211
+ }
212
+ this.events.lockUserChange.emit({
213
+ lockDataType: DoorLock.LockDataType.UserIndex,
214
+ dataOperationType: DoorLock.DataOperationType.Clear,
215
+ operationSource: this.getOperationSource(),
216
+ userIndex: request.userIndex,
217
+ fabricIndex: accessingFabricIndex,
218
+ sourceNode: this.getAccessingNodeId(),
219
+ dataIndex: request.userIndex,
220
+ }, this.context);
221
+ }
222
+ async setCredential(request) {
223
+ const device = this.endpoint.stateOf(MatterbridgeServer);
224
+ const accessingFabricIndex = this.getAccessingFabricIndex();
225
+ device.log.info(`Setting credential operationType ${getEnumDescription(DoorLock.DataOperationType, request.operationType)} credentialType ${getEnumDescription(DoorLock.CredentialType, request.credential.credentialType)} credentialIndex ${request.credential.credentialIndex} credentialData ${Buffer.from(request.credentialData).toString('hex') ? '0x' + Buffer.from(request.credentialData).toString('hex') : '0x'} userIndex ${request.userIndex ?? 'null'} userStatus ${getEnumDescription(DoorLock.UserStatus, request.userStatus, { fallback: 'null' })} userType ${getEnumDescription(DoorLock.UserType, request.userType, { fallback: 'null' })} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
226
+ await device.commandHandler.executeHandler('DoorLock.setCredential', {
227
+ command: 'setCredential',
228
+ request,
229
+ cluster: DoorLockServer.id,
230
+ attributes: this.state,
231
+ endpoint: this.endpoint,
232
+ context: this.context,
233
+ });
234
+ const user = this.internal.users.find((storedUser) => storedUser.userIndex === request.userIndex);
235
+ const existingCredential = this.findStoredCredential(request.credential);
236
+ device.log.debug(`MatterbridgeDoorLockServer: setCredential pre-update lookup for credentialIndex ${request.credential.credentialIndex} (${existingCredential ? 'existing credential found' : 'no existing credential'})`);
237
+ if (user && (request.operationType === DoorLock.DataOperationType.Add || request.operationType === DoorLock.DataOperationType.Modify)) {
238
+ const credential = user.credentials?.find((storedCredential) => storedCredential.credentialType === request.credential.credentialType && storedCredential.credentialIndex === request.credential.credentialIndex);
239
+ if (credential) {
240
+ credential.credentialData = request.credentialData;
241
+ credential.creatorFabricIndex = credential.creatorFabricIndex ?? accessingFabricIndex;
242
+ credential.lastModifiedFabricIndex = accessingFabricIndex;
243
+ device.log.debug(`MatterbridgeDoorLockServer: modified credentialIndex ${request.credential.credentialIndex} for userIndex ${request.userIndex} in internal state: ${debugStringify(user)}`);
244
+ }
245
+ else {
246
+ user.credentials = user.credentials ?? [];
247
+ user.credentials.push({
248
+ credentialType: request.credential.credentialType,
249
+ credentialIndex: request.credential.credentialIndex,
250
+ credentialData: request.credentialData,
251
+ creatorFabricIndex: accessingFabricIndex,
252
+ lastModifiedFabricIndex: accessingFabricIndex,
253
+ });
254
+ device.log.debug(`MatterbridgeDoorLockServer: added credentialIndex ${request.credential.credentialIndex} for userIndex ${request.userIndex} to internal state: ${debugStringify(user)}`);
255
+ }
256
+ this.events.lockUserChange.emit({
257
+ lockDataType: this.getLockDataTypeForCredentialType(request.credential.credentialType),
258
+ dataOperationType: request.operationType,
259
+ operationSource: this.getOperationSource(),
260
+ userIndex: request.userIndex,
261
+ fabricIndex: accessingFabricIndex,
262
+ sourceNode: this.getAccessingNodeId(),
263
+ dataIndex: this.getCredentialDataIndex(request.credential),
264
+ }, this.context);
265
+ }
266
+ else {
267
+ device.log.debug(`MatterbridgeDoorLockServer: setCredential did not update internal state for credentialIndex ${request.credential.credentialIndex} (user ${request.userIndex ?? 'null'} not found or operation not handled)`);
268
+ }
269
+ return {
270
+ status: Status.Success,
271
+ userIndex: request.userIndex,
272
+ };
273
+ }
274
+ async getCredentialStatus(request) {
275
+ const device = this.endpoint.stateOf(MatterbridgeServer);
276
+ device.log.info(`Getting credential status for credentialType ${getEnumDescription(DoorLock.CredentialType, request.credential.credentialType)} credentialIndex ${request.credential.credentialIndex} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
277
+ await device.commandHandler.executeHandler('DoorLock.getCredentialStatus', {
278
+ command: 'getCredentialStatus',
279
+ request,
280
+ cluster: DoorLockServer.id,
281
+ attributes: this.state,
282
+ endpoint: this.endpoint,
283
+ context: this.context,
284
+ });
285
+ device.log.debug(`MatterbridgeDoorLockServer: getCredentialStatus called`);
286
+ const credentialRecord = this.findStoredCredential(request.credential);
287
+ const nextCredentialIndex = this.getNextOccupiedCredentialIndex(request.credential);
288
+ const response = {
289
+ credentialExists: credentialRecord !== null,
290
+ userIndex: credentialRecord?.user.userIndex ?? null,
291
+ creatorFabricIndex: credentialRecord?.storedCredential.creatorFabricIndex ?? null,
292
+ lastModifiedFabricIndex: credentialRecord?.storedCredential.lastModifiedFabricIndex ?? null,
293
+ nextCredentialIndex,
294
+ };
295
+ device.log.debug(`MatterbridgeDoorLockServer: getCredentialStatus result ${debugStringify(response)}`);
296
+ return response;
297
+ }
298
+ async clearCredential(request) {
299
+ const device = this.endpoint.stateOf(MatterbridgeServer);
300
+ const accessingFabricIndex = this.getAccessingFabricIndex();
301
+ const clearedCredentialUserIndex = request.credential !== null && request.credential.credentialIndex !== 0xfffe ? (this.findStoredCredential(request.credential)?.user.userIndex ?? null) : null;
302
+ const credentialTypesToClear = request.credential !== null ? [request.credential.credentialType] : this.getStoredCredentialTypes();
303
+ device.log.info(`Clearing credentialType ${request.credential ? getEnumDescription(DoorLock.CredentialType, request.credential.credentialType) : 'null'} credentialIndex ${request.credential ? request.credential.credentialIndex : 'null'} ${request.credential === null ? '(all credentials)' : ''} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
304
+ await device.commandHandler.executeHandler('DoorLock.clearCredential', {
305
+ command: 'clearCredential',
306
+ request,
307
+ cluster: DoorLockServer.id,
308
+ attributes: this.state,
309
+ endpoint: this.endpoint,
310
+ context: this.context,
311
+ });
312
+ device.log.debug('MatterbridgeDoorLockServer: clearCredential called');
313
+ for (const user of this.internal.users) {
314
+ user.credentials =
315
+ user.credentials?.filter((storedCredential) => {
316
+ if (request.credential === null) {
317
+ return false;
318
+ }
319
+ if (storedCredential.credentialType !== request.credential.credentialType) {
320
+ return true;
321
+ }
322
+ if (request.credential.credentialIndex === 0xfffe) {
323
+ return false;
324
+ }
325
+ return storedCredential.credentialIndex !== request.credential.credentialIndex;
326
+ }) ?? user.credentials;
327
+ }
328
+ for (const credentialType of credentialTypesToClear) {
329
+ this.events.lockUserChange.emit({
330
+ lockDataType: this.getLockDataTypeForCredentialType(credentialType),
331
+ dataOperationType: DoorLock.DataOperationType.Clear,
332
+ operationSource: this.getOperationSource(),
333
+ userIndex: request.credential === null || request.credential.credentialIndex === 0xfffe ? null : clearedCredentialUserIndex,
334
+ fabricIndex: accessingFabricIndex,
335
+ sourceNode: this.getAccessingNodeId(),
336
+ dataIndex: request.credential === null ? 0xfffe : this.getCredentialDataIndex(request.credential),
337
+ }, this.context);
338
+ }
339
+ }
340
+ validateUserIndex(userIndex) {
341
+ if (userIndex < 1 || userIndex > this.state.numberOfTotalUsersSupported) {
342
+ return false;
343
+ }
344
+ return true;
345
+ }
346
+ getNextUserIndex(userIndex) {
347
+ const nextUser = this.internal.users.find((storedUser) => storedUser.userIndex === userIndex + 1);
348
+ if (nextUser && nextUser.userStatus !== DoorLock.UserStatus.Available) {
349
+ return nextUser.userIndex;
350
+ }
351
+ return null;
352
+ }
353
+ getAccessingFabricIndex() {
354
+ let fabricIndex;
355
+ try {
356
+ fabricIndex = this.context.fabric;
357
+ }
358
+ catch {
359
+ return null;
360
+ }
361
+ if (fabricIndex === undefined || fabricIndex === FabricIndex.NO_FABRIC) {
362
+ return null;
363
+ }
364
+ return fabricIndex;
365
+ }
366
+ getAccessingNodeId() {
367
+ if (!hasRemoteActor(this.context)) {
368
+ return null;
369
+ }
370
+ return this.context.session.peerNodeId ?? null;
371
+ }
372
+ getOperationSource() {
373
+ return this.getAccessingNodeId() !== null ? DoorLock.OperationSource.Remote : DoorLock.OperationSource.Unspecified;
374
+ }
375
+ getLockDataTypeForCredentialType(credentialType) {
376
+ switch (credentialType) {
377
+ case DoorLock.CredentialType.ProgrammingPin:
378
+ return DoorLock.LockDataType.ProgrammingCode;
379
+ case DoorLock.CredentialType.Pin:
380
+ return DoorLock.LockDataType.Pin;
381
+ case DoorLock.CredentialType.Rfid:
382
+ return DoorLock.LockDataType.Rfid;
383
+ case DoorLock.CredentialType.Fingerprint:
384
+ return DoorLock.LockDataType.Fingerprint;
385
+ case DoorLock.CredentialType.FingerVein:
386
+ return DoorLock.LockDataType.FingerVein;
387
+ case DoorLock.CredentialType.Face:
388
+ return DoorLock.LockDataType.Face;
389
+ case DoorLock.CredentialType.AliroCredentialIssuerKey:
390
+ return DoorLock.LockDataType.AliroCredentialIssuerKey;
391
+ case DoorLock.CredentialType.AliroEvictableEndpointKey:
392
+ return DoorLock.LockDataType.AliroEvictableEndpointKey;
393
+ case DoorLock.CredentialType.AliroNonEvictableEndpointKey:
394
+ return DoorLock.LockDataType.AliroNonEvictableEndpointKey;
395
+ default:
396
+ return DoorLock.LockDataType.Unspecified;
397
+ }
398
+ }
399
+ getCredentialDataIndex(credential) {
400
+ if (credential.credentialType === DoorLock.CredentialType.ProgrammingPin) {
401
+ return null;
402
+ }
403
+ return credential.credentialIndex;
404
+ }
405
+ getStoredCredentialTypes() {
406
+ const credentialTypes = new Set();
407
+ for (const user of this.internal.users) {
408
+ for (const credential of user.credentials ?? []) {
409
+ credentialTypes.add(credential.credentialType);
410
+ }
411
+ }
412
+ return [...credentialTypes];
413
+ }
414
+ findStoredCredential(credential) {
415
+ for (const user of this.internal.users) {
416
+ for (const storedCredential of user.credentials ?? []) {
417
+ if (storedCredential.credentialType === credential.credentialType && storedCredential.credentialIndex === credential.credentialIndex) {
418
+ return { user, storedCredential };
419
+ }
420
+ }
421
+ }
422
+ return null;
423
+ }
424
+ getNextOccupiedCredentialIndex(credential) {
425
+ for (const user of this.internal.users) {
426
+ for (const storedCredential of user.credentials ?? []) {
427
+ if (storedCredential.credentialType !== credential.credentialType || storedCredential.credentialIndex <= credential.credentialIndex) {
428
+ continue;
429
+ }
430
+ return storedCredential.credentialIndex;
431
+ }
432
+ }
433
+ return null;
434
+ }
90
435
  }
91
436
  (function (MatterbridgeDoorLockServer) {
92
437
  class Internal {
93
438
  enableTimeout = true;
94
439
  unlockTimeout;
440
+ users = [];
95
441
  }
96
442
  MatterbridgeDoorLockServer.Internal = Internal;
97
443
  })(MatterbridgeDoorLockServer || (MatterbridgeDoorLockServer = {}));
@@ -13,12 +13,10 @@ export * from './matterbridgeServer.js';
13
13
  export * from './modeSelectServer.js';
14
14
  export * from './onOffServer.js';
15
15
  export * from './operationalStateServer.js';
16
- export * from './pinDoorLockServer.js';
17
16
  export * from './powerSourceServer.js';
18
17
  export * from './serviceAreaServer.js';
19
18
  export * from './smokeCoAlarmServer.js';
20
19
  export * from './switchServer.js';
21
20
  export * from './thermostatServer.js';
22
- export * from './userPinDoorLockServer.js';
23
21
  export * from './valveConfigurationAndControlServer.js';
24
22
  export * from './windowCoveringServer.js';
@@ -13,12 +13,10 @@ export * from './matterbridgeServer.js';
13
13
  export * from './modeSelectServer.js';
14
14
  export * from './onOffServer.js';
15
15
  export * from './operationalStateServer.js';
16
- export * from './pinDoorLockServer.js';
17
16
  export * from './powerSourceServer.js';
18
17
  export * from './serviceAreaServer.js';
19
18
  export * from './smokeCoAlarmServer.js';
20
19
  export * from './switchServer.js';
21
20
  export * from './thermostatServer.js';
22
- export * from './userPinDoorLockServer.js';
23
21
  export * from './valveConfigurationAndControlServer.js';
24
22
  export * from './windowCoveringServer.js';
package/dist/cli.js CHANGED
@@ -12,7 +12,8 @@ export let instance;
12
12
  export const tracker = new Tracker('Cli', false, false);
13
13
  export const inspector = new Inspector('Cli', false, false);
14
14
  const manager = new ThreadsManager();
15
- if (process.argv.includes('--no-ansi') || process.argv.includes('-no-ansi'))
15
+ const colorEnabled = Boolean(process.stdout.isTTY && !process.env.NO_COLOR && process.env.TERM !== 'dumb' && process.env.FORCE_COLOR !== '0' && !hasParameter('no-ansi'));
16
+ if (!colorEnabled)
16
17
  process.env.NO_COLOR = '1';
17
18
  const log = new AnsiLogger({ logName: 'Cli', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
18
19
  function startCpuMemoryCheck() {
package/dist/export.d.ts CHANGED
@@ -13,13 +13,11 @@ export * from './behaviors/matterbridgeServer.js';
13
13
  export * from './behaviors/modeSelectServer.js';
14
14
  export * from './behaviors/onOffServer.js';
15
15
  export * from './behaviors/operationalStateServer.js';
16
- export * from './behaviors/pinDoorLockServer.js';
17
16
  export * from './behaviors/powerSourceServer.js';
18
17
  export * from './behaviors/serviceAreaServer.js';
19
18
  export * from './behaviors/smokeCoAlarmServer.js';
20
19
  export * from './behaviors/switchServer.js';
21
20
  export * from './behaviors/thermostatServer.js';
22
- export * from './behaviors/userPinDoorLockServer.js';
23
21
  export * from './behaviors/valveConfigurationAndControlServer.js';
24
22
  export * from './behaviors/windowCoveringServer.js';
25
23
  export { addVirtualDevice } from './helpers.js';
package/dist/export.js CHANGED
@@ -15,13 +15,11 @@ export * from './behaviors/matterbridgeServer.js';
15
15
  export * from './behaviors/modeSelectServer.js';
16
16
  export * from './behaviors/onOffServer.js';
17
17
  export * from './behaviors/operationalStateServer.js';
18
- export * from './behaviors/pinDoorLockServer.js';
19
18
  export * from './behaviors/powerSourceServer.js';
20
19
  export * from './behaviors/serviceAreaServer.js';
21
20
  export * from './behaviors/smokeCoAlarmServer.js';
22
21
  export * from './behaviors/switchServer.js';
23
22
  export * from './behaviors/thermostatServer.js';
24
- export * from './behaviors/userPinDoorLockServer.js';
25
23
  export * from './behaviors/valveConfigurationAndControlServer.js';
26
24
  export * from './behaviors/windowCoveringServer.js';
27
25
  export { addVirtualDevice } from './helpers.js';
@@ -1,6 +1,6 @@
1
1
  import EventEmitter from 'node:events';
2
2
  import { EndpointNumber } from '@matter/types/datatype';
3
- import type { ApiMatter, RefreshRequiredChanged, WsMessageBroadcast } from '@matterbridge/types';
3
+ import type { ApiClusters, ApiDevice, ApiMatter, ApiPlugin, ApiSettings, RefreshRequiredChanged, WsMessageBroadcast } from '@matterbridge/types';
4
4
  import { LogLevel } from 'node-ansi-logger';
5
5
  import type { Matterbridge } from './matterbridge.js';
6
6
  interface FrontendEvents {
@@ -15,8 +15,8 @@ export declare class Frontend extends EventEmitter<FrontendEvents> {
15
15
  private log;
16
16
  private port;
17
17
  private listening;
18
- private storedPassword;
19
- private authClients;
18
+ storedPassword: string | undefined;
19
+ authClients: Set<string>;
20
20
  private expressApp;
21
21
  private httpServer;
22
22
  private httpsServer;
@@ -25,22 +25,29 @@ export declare class Frontend extends EventEmitter<FrontendEvents> {
25
25
  private serverFetchTimeout;
26
26
  private readonly debug;
27
27
  private readonly verbose;
28
+ readonly readOnly: boolean;
29
+ readonly shellyBoard: boolean;
30
+ shellySysUpdate: boolean;
31
+ shellyMainUpdate: boolean;
32
+ restartRequired: boolean;
33
+ fixedRestartRequired: boolean;
34
+ updateRequired: boolean;
28
35
  constructor(matterbridge: Matterbridge);
29
36
  destroy(): void;
30
- private msgHandler;
37
+ private broadcastMsgHandler;
31
38
  set logLevel(logLevel: LogLevel);
32
39
  private validateReq;
33
40
  start(port?: number): Promise<void>;
34
41
  stop(): Promise<void>;
35
- private getApiSettings;
42
+ getApiSettings(): ApiSettings;
36
43
  private getReachability;
37
44
  private getPowerSource;
38
45
  private getBatteryLevel;
39
46
  private getClusterTextFromDevice;
40
- private getPlugins;
41
- private getDevices;
42
- private getClusters;
43
- private generateDiagnostic;
47
+ getApiPlugins(): ApiPlugin[];
48
+ getApiDevices(pluginName?: string): ApiDevice[];
49
+ getClusters(pluginName: string, endpointNumber: number, serialNumber?: string, uniqueId?: string): ApiClusters | undefined;
50
+ generateDiagnostic(): Promise<void>;
44
51
  private wsMessageHandler;
45
52
  wssSendLogMessage(level: string, time: string, name: string, message: string): void;
46
53
  wssSendRefreshRequired(changed: RefreshRequiredChanged, params?: {