@matterbridge/core 3.7.2-dev-20260330-bb55c39 → 3.7.2-dev-20260331-ac050d8
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.
- package/dist/behaviors/doorLockServer.d.ts +36 -2
- package/dist/behaviors/doorLockServer.js +352 -6
- package/dist/behaviors/export.d.ts +0 -2
- package/dist/behaviors/export.js +0 -2
- package/dist/export.d.ts +0 -2
- package/dist/export.js +0 -2
- package/dist/frontend.js +6 -6
- package/dist/helpers.js +0 -5
- package/dist/matterNode.js +10 -2
- package/dist/matterbridge.js +10 -2
- package/dist/matterbridgeEndpoint.d.ts +4 -5
- package/dist/matterbridgeEndpoint.js +9 -33
- package/dist/matterbridgeEndpointCommandHandler.d.ts +8 -2
- package/dist/matterbridgeEndpointCommandHandler.js +2 -1
- package/package.json +5 -5
- package/dist/behaviors/pinDoorLockServer.d.ts +0 -32
- package/dist/behaviors/pinDoorLockServer.js +0 -168
- package/dist/behaviors/userPinDoorLockServer.d.ts +0 -57
- package/dist/behaviors/userPinDoorLockServer.js +0 -348
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DoorLockServer } from '@matter/node/behaviors/door-lock';
|
|
2
2
|
import { DoorLock } from '@matter/types/clusters/door-lock';
|
|
3
|
-
|
|
3
|
+
import { FabricIndex } from '@matter/types/datatype';
|
|
4
|
+
declare const MatterbridgeDoorLockServer_base: import("@matter/node").ClusterBehavior.Type<import("@matter/types").ClusterTypeModifier.WithAlterations<import("@matter/types").ClusterComposer.WithFeatures<DoorLock.Cluster, readonly [DoorLock.Feature.User, DoorLock.Feature.PinCredential]>, import("@matter/types").ClusterTypeModifier.ElementFlagAlterations<{
|
|
4
5
|
readonly events: {
|
|
5
6
|
readonly doorLockAlarm: true;
|
|
6
7
|
readonly lockOperation: true;
|
|
@@ -11,18 +12,51 @@ declare const MatterbridgeDoorLockServer_base: import("@matter/node").ClusterBeh
|
|
|
11
12
|
readonly unlockDoor: true;
|
|
12
13
|
readonly unlockWithTimeout: true;
|
|
13
14
|
};
|
|
14
|
-
}>>, typeof DoorLockServer, import("@matter/node/behaviors/door-lock").DoorLockInterface>;
|
|
15
|
+
}>>, import("@matter/node").ClusterBehavior.Type<import("@matter/types").ClusterComposer.WithFeatures<DoorLock.Cluster, readonly [DoorLock.Feature.User, DoorLock.Feature.PinCredential]>, typeof DoorLockServer, import("@matter/node/behaviors/door-lock").DoorLockInterface>, import("@matter/node/behaviors/door-lock").DoorLockInterface>;
|
|
15
16
|
export declare class MatterbridgeDoorLockServer extends MatterbridgeDoorLockServer_base {
|
|
16
17
|
protected internal: MatterbridgeDoorLockServer.Internal;
|
|
17
18
|
initialize(): Promise<void>;
|
|
18
19
|
lockDoor(request: DoorLock.LockDoorRequest): Promise<void>;
|
|
19
20
|
unlockDoor(request: DoorLock.UnlockDoorRequest): Promise<void>;
|
|
20
21
|
unlockWithTimeout(request: DoorLock.UnlockWithTimeoutRequest): Promise<void>;
|
|
22
|
+
setUser(request: DoorLock.SetUserRequest): Promise<void>;
|
|
23
|
+
getUser(request: DoorLock.GetUserRequest): Promise<DoorLock.GetUserResponse>;
|
|
24
|
+
clearUser(request: DoorLock.ClearUserRequest): Promise<void>;
|
|
25
|
+
setCredential(request: DoorLock.SetCredentialRequest): Promise<DoorLock.SetCredentialResponse>;
|
|
26
|
+
getCredentialStatus(request: DoorLock.GetCredentialStatusRequest): Promise<DoorLock.GetCredentialStatusResponse>;
|
|
27
|
+
clearCredential(request: DoorLock.ClearCredentialRequest): Promise<void>;
|
|
28
|
+
private validateUserIndex;
|
|
29
|
+
private getNextUserIndex;
|
|
30
|
+
private getAccessingFabricIndex;
|
|
31
|
+
private getAccessingNodeId;
|
|
32
|
+
private getOperationSource;
|
|
33
|
+
private getLockDataTypeForCredentialType;
|
|
34
|
+
private getCredentialDataIndex;
|
|
35
|
+
private getStoredCredentialTypes;
|
|
36
|
+
private findStoredCredential;
|
|
37
|
+
private getNextOccupiedCredentialIndex;
|
|
21
38
|
}
|
|
22
39
|
export declare namespace MatterbridgeDoorLockServer {
|
|
40
|
+
type StoredCredential = DoorLock.Credential & {
|
|
41
|
+
creatorFabricIndex: FabricIndex | null;
|
|
42
|
+
lastModifiedFabricIndex: FabricIndex | null;
|
|
43
|
+
credentialData: Uint8Array;
|
|
44
|
+
};
|
|
45
|
+
type StoredUser = {
|
|
46
|
+
userIndex: number;
|
|
47
|
+
userName: string | null;
|
|
48
|
+
userUniqueId: number | null;
|
|
49
|
+
userStatus: DoorLock.UserStatus | null;
|
|
50
|
+
userType: DoorLock.UserType | null;
|
|
51
|
+
credentialRule: DoorLock.CredentialRule | null;
|
|
52
|
+
credentials: StoredCredential[] | null;
|
|
53
|
+
creatorFabricIndex: FabricIndex | null;
|
|
54
|
+
lastModifiedFabricIndex: FabricIndex | null;
|
|
55
|
+
};
|
|
23
56
|
class Internal {
|
|
24
57
|
enableTimeout: boolean;
|
|
25
58
|
unlockTimeout: NodeJS.Timeout | undefined;
|
|
59
|
+
users: StoredUser[];
|
|
26
60
|
}
|
|
27
61
|
}
|
|
28
62
|
export {};
|
|
@@ -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';
|
package/dist/behaviors/export.js
CHANGED
|
@@ -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/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';
|
package/dist/frontend.js
CHANGED
|
@@ -486,7 +486,7 @@ export class Frontend extends EventEmitter {
|
|
|
486
486
|
};
|
|
487
487
|
res.status(200).json(memoryReport);
|
|
488
488
|
});
|
|
489
|
-
this.expressApp.get('/api/settings',
|
|
489
|
+
this.expressApp.get('/api/settings', async (req, res) => {
|
|
490
490
|
this.log.debug('The frontend sent /api/settings');
|
|
491
491
|
if (!this.validateReq(req, res))
|
|
492
492
|
return;
|
|
@@ -863,10 +863,10 @@ export class Frontend extends EventEmitter {
|
|
|
863
863
|
matterbridgeLatestVersion: this.matterbridge.matterbridgeLatestVersion,
|
|
864
864
|
matterbridgeDevVersion: this.matterbridge.matterbridgeDevVersion,
|
|
865
865
|
frontendVersion: this.matterbridge.frontendVersion,
|
|
866
|
-
dockerDev:
|
|
867
|
-
dockerVersion:
|
|
868
|
-
dockerLatestVersion:
|
|
869
|
-
dockerDevVersion:
|
|
866
|
+
dockerDev: this.matterbridge.dockerDev,
|
|
867
|
+
dockerVersion: this.matterbridge.dockerVersion,
|
|
868
|
+
dockerLatestVersion: this.matterbridge.dockerLatestVersion,
|
|
869
|
+
dockerDevVersion: this.matterbridge.dockerDevVersion,
|
|
870
870
|
bridgeMode: this.matterbridge.bridgeMode,
|
|
871
871
|
restartMode: this.matterbridge.restartMode,
|
|
872
872
|
virtualMode: this.matterbridge.virtualMode,
|
|
@@ -2119,7 +2119,7 @@ export class Frontend extends EventEmitter {
|
|
|
2119
2119
|
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
2120
2120
|
return;
|
|
2121
2121
|
const stringifiedMsg = JSON.stringify(msg);
|
|
2122
|
-
if (
|
|
2122
|
+
if (!['log', 'cpu_update', 'memory_update', 'uptime_update'].includes(msg.method))
|
|
2123
2123
|
this.log.debug(`Sending a broadcast message: ${debugStringify(msg)}`);
|
|
2124
2124
|
this.webSocketServer?.clients.forEach((client) => {
|
|
2125
2125
|
if (client.readyState === client.OPEN) {
|
package/dist/helpers.js
CHANGED
|
@@ -74,11 +74,6 @@ export async function addVirtualDevice(aggregatorEndpoint, name, type, callback)
|
|
|
74
74
|
}
|
|
75
75
|
export async function addVirtualDevices(matterbridge, aggregatorEndpoint) {
|
|
76
76
|
if (hasParameter('experimental') && matterbridge.bridgeMode === 'bridge' && aggregatorEndpoint) {
|
|
77
|
-
const lockPin = new MatterbridgeEndpoint(doorLockDevice, { id: 'door_lock_pin' });
|
|
78
|
-
lockPin.createDefaultBridgedDeviceBasicInformationClusterServer('Matterbridge Pin Lock', 'sn_system_lock', 0xfff1, 'Matterbridge', 'Matterbridge Virtual Device', 20000, '2.0.0');
|
|
79
|
-
lockPin.createPinDoorLockClusterServer();
|
|
80
|
-
lockPin.addRequiredClusterServers();
|
|
81
|
-
await aggregatorEndpoint.add(lockPin);
|
|
82
77
|
const lockUserPin = new MatterbridgeEndpoint(doorLockDevice, { id: 'door_lock_user_pin' });
|
|
83
78
|
lockUserPin.createDefaultBridgedDeviceBasicInformationClusterServer('Matterbridge User Pin Lock', 'sn_system_lock', 0xfff1, 'Matterbridge', 'Matterbridge Virtual Device', 20000, '2.0.0');
|
|
84
79
|
lockUserPin.createUserPinDoorLockClusterServer();
|
package/dist/matterNode.js
CHANGED
|
@@ -280,8 +280,16 @@ export class MatterNode extends EventEmitter {
|
|
|
280
280
|
this.matterLog.logFilePath = path.join(this.matterbridge.matterbridgeDirectory, MATTER_LOGGER_FILE);
|
|
281
281
|
}
|
|
282
282
|
return (text, message) => {
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
let logger;
|
|
284
|
+
let msg;
|
|
285
|
+
if (!hasParameter('no-ansi') && process.env.NO_ANSI !== 'true') {
|
|
286
|
+
logger = text.slice(44, 44 + 20).trim();
|
|
287
|
+
msg = text.slice(65);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
logger = text.slice(30).trim().split(/\s+/, 1)[0];
|
|
291
|
+
msg = text.slice(30).trim().slice(logger.length).trimStart();
|
|
292
|
+
}
|
|
285
293
|
this.matterLog.logName = logger;
|
|
286
294
|
this.matterLog.log(MatterLogLevel.names[message.level], msg);
|
|
287
295
|
};
|
package/dist/matterbridge.js
CHANGED
|
@@ -1053,8 +1053,16 @@ export class Matterbridge extends EventEmitter {
|
|
|
1053
1053
|
this.matterLog.logFilePath = path.join(this.matterbridgeDirectory, MATTER_LOGGER_FILE);
|
|
1054
1054
|
}
|
|
1055
1055
|
return (text, message) => {
|
|
1056
|
-
|
|
1057
|
-
|
|
1056
|
+
let logger;
|
|
1057
|
+
let msg;
|
|
1058
|
+
if (!hasParameter('no-ansi') && process.env.NO_ANSI !== 'true') {
|
|
1059
|
+
logger = text.slice(44, 44 + 20).trim();
|
|
1060
|
+
msg = text.slice(65);
|
|
1061
|
+
}
|
|
1062
|
+
else {
|
|
1063
|
+
logger = text.slice(30).trim().split(/\s+/, 1)[0];
|
|
1064
|
+
msg = text.slice(30).trim().slice(logger.length).trimStart();
|
|
1065
|
+
}
|
|
1058
1066
|
this.matterLog.logName = logger;
|
|
1059
1067
|
switch (message.level) {
|
|
1060
1068
|
case MatterLogLevel.DEBUG:
|
|
@@ -24,7 +24,7 @@ import { ClusterId, EndpointNumber } from '@matter/types/datatype';
|
|
|
24
24
|
import { Semtag } from '@matter/types/globals';
|
|
25
25
|
import { AnsiLogger, LogLevel } from 'node-ansi-logger';
|
|
26
26
|
import { DeviceTypeDefinition } from './matterbridgeDeviceTypes.js';
|
|
27
|
-
import { CommandHandler, CommandHandlerData, CommandHandlerFunction, CommandHandlers } from './matterbridgeEndpointCommandHandler.js';
|
|
27
|
+
import { CommandHandler, CommandHandlerData, CommandHandlerExecutionResult, CommandHandlerFunction, CommandHandlers } from './matterbridgeEndpointCommandHandler.js';
|
|
28
28
|
import { MatterbridgeEndpointOptions, SerializedMatterbridgeEndpoint } from './matterbridgeEndpointTypes.js';
|
|
29
29
|
type BehaviorCommandName<T extends Behavior.Type> = {
|
|
30
30
|
[K in keyof CommandsOfBehavior<T>]: K;
|
|
@@ -101,7 +101,7 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
101
101
|
addUserLabel(label: string, value: string): Promise<this>;
|
|
102
102
|
addCommandHandler<C extends CommandHandlers>(command: C, handler: CommandHandlerFunction<C>): this;
|
|
103
103
|
removeCommandHandler<C extends CommandHandlers>(command: C, handler: CommandHandlerFunction<C>): this;
|
|
104
|
-
executeCommandHandler<C extends CommandHandlers>(command: C, request: CommandHandlerData<C>['request'], cluster: CommandHandlerData<C>['cluster'], attributes: CommandHandlerData<C>['attributes'], endpoint: CommandHandlerData<C>['endpoint']): Promise<
|
|
104
|
+
executeCommandHandler<C extends CommandHandlers>(command: C, request: CommandHandlerData<C>['request'], cluster: CommandHandlerData<C>['cluster'], attributes: CommandHandlerData<C>['attributes'], endpoint: CommandHandlerData<C>['endpoint']): Promise<CommandHandlerExecutionResult<C>>;
|
|
105
105
|
invokeBehaviorCommand<T extends Behavior.Type, C extends BehaviorCommandName<T>>(cluster: T, command: C, params?: BehaviorCommandParams<T, C>): Promise<void>;
|
|
106
106
|
invokeBehaviorCommand<T extends ClusterType, C extends keyof ClusterType.CommandsOf<T>>(cluster: T, command: C, params?: ClusterType.CommandsOf<T>[C] extends {
|
|
107
107
|
requestSchema: infer S extends import('@matter/types/tlv').TlvSchema<unknown>;
|
|
@@ -182,9 +182,8 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
182
182
|
}, airflowDirection?: FanControl.AirflowDirection): this;
|
|
183
183
|
createDefaultHepaFilterMonitoringClusterServer(condition?: number, changeIndication?: ResourceMonitoring.ChangeIndication, inPlaceIndicator?: boolean | undefined, lastChangedTime?: number | null | undefined, replacementProductList?: ResourceMonitoring.ReplacementProduct[]): this;
|
|
184
184
|
createDefaultActivatedCarbonFilterMonitoringClusterServer(condition?: number, changeIndication?: ResourceMonitoring.ChangeIndication, inPlaceIndicator?: boolean | undefined, lastChangedTime?: number | null | undefined, replacementProductList?: ResourceMonitoring.ReplacementProduct[]): this;
|
|
185
|
-
createDefaultDoorLockClusterServer(lockState?: DoorLock.LockState, lockType?: DoorLock.LockType): this;
|
|
186
|
-
|
|
187
|
-
createUserPinDoorLockClusterServer(lockState?: DoorLock.LockState, lockType?: DoorLock.LockType): this;
|
|
185
|
+
createDefaultDoorLockClusterServer(lockState?: DoorLock.LockState, lockType?: DoorLock.LockType, autoRelockTime?: number): this;
|
|
186
|
+
createUserPinDoorLockClusterServer(lockState?: DoorLock.LockState, lockType?: DoorLock.LockType, autoRelockTime?: number, minPinCodeLength?: number, maxPinCodeLength?: number): this;
|
|
188
187
|
createDefaultModeSelectClusterServer(description: string, supportedModes: ModeSelect.ModeOption[], currentMode?: number, startUpMode?: number): this;
|
|
189
188
|
createDefaultValveConfigurationAndControlClusterServer(valveState?: ValveConfigurationAndControl.ValveState, valveLevel?: number): this;
|
|
190
189
|
createDefaultPumpConfigurationAndControlClusterServer(pumpMode?: PumpConfigurationAndControl.OperationMode): this;
|