matterbridge 1.6.3 → 1.6.5-dev.1
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/CHANGELOG.md +23 -0
- package/README-DEV.md +12 -7
- package/dist/cli.js +0 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -8
- package/dist/index.js.map +1 -1
- package/dist/matterbridge.d.ts.map +1 -1
- package/dist/matterbridge.js +58 -37
- package/dist/matterbridge.js.map +1 -1
- package/dist/matterbridgeBehaviors.d.ts +4 -0
- package/dist/matterbridgeBehaviors.d.ts.map +1 -1
- package/dist/matterbridgeBehaviors.js +56 -39
- package/dist/matterbridgeBehaviors.js.map +1 -1
- package/dist/matterbridgeDevice.d.ts +18 -10
- package/dist/matterbridgeDevice.d.ts.map +1 -1
- package/dist/matterbridgeDevice.js +41 -1
- package/dist/matterbridgeDevice.js.map +1 -1
- package/dist/matterbridgeDeviceTypes.d.ts +1 -1
- package/dist/matterbridgeDeviceTypes.d.ts.map +1 -1
- package/dist/matterbridgeDeviceTypes.js +1 -1
- package/dist/matterbridgeDeviceTypes.js.map +1 -1
- package/dist/matterbridgeEdge.js +12 -12
- package/dist/matterbridgeEdge.js.map +1 -1
- package/dist/matterbridgeEndpoint.d.ts +183 -7
- package/dist/matterbridgeEndpoint.d.ts.map +1 -1
- package/dist/matterbridgeEndpoint.js +120 -31
- package/dist/matterbridgeEndpoint.js.map +1 -1
- package/npm-shrinkwrap.json +61 -58
- package/package.json +4 -4
|
@@ -64,6 +64,8 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
64
64
|
softwareVersionString = undefined;
|
|
65
65
|
hardwareVersion = undefined;
|
|
66
66
|
hardwareVersionString = undefined;
|
|
67
|
+
name = undefined;
|
|
68
|
+
deviceType;
|
|
67
69
|
uniqueStorageKey = undefined;
|
|
68
70
|
tagList = undefined;
|
|
69
71
|
// Maps matter deviceTypes and endpoints
|
|
@@ -78,12 +80,20 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
78
80
|
* @param {MatterbridgeEndpointOptions} [options={}] - The options for the device.
|
|
79
81
|
*/
|
|
80
82
|
constructor(definition, options = {}, debug = false) {
|
|
83
|
+
let deviceTypeList = [];
|
|
81
84
|
// Get the first DeviceTypeDefinition
|
|
82
85
|
let firstDefinition;
|
|
83
|
-
if (Array.isArray(definition))
|
|
86
|
+
if (Array.isArray(definition)) {
|
|
84
87
|
firstDefinition = definition[0];
|
|
85
|
-
|
|
88
|
+
deviceTypeList = Array.from(definition.values()).map((dt) => ({
|
|
89
|
+
deviceType: dt.code,
|
|
90
|
+
revision: dt.revision,
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
86
94
|
firstDefinition = definition;
|
|
95
|
+
deviceTypeList = [{ deviceType: firstDefinition.code, revision: firstDefinition.revision }];
|
|
96
|
+
}
|
|
87
97
|
// Convert the first DeviceTypeDefinition to an EndpointType.Options
|
|
88
98
|
const deviceTypeDefinitionV8 = {
|
|
89
99
|
name: firstDefinition.name.replace('-', '_'),
|
|
@@ -104,31 +114,30 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
104
114
|
};
|
|
105
115
|
const endpointV8 = MutableEndpoint(deviceTypeDefinitionV8);
|
|
106
116
|
// Convert the options to an Endpoint.Options
|
|
107
|
-
// [{ mfgCode: null, namespaceId: 0x07, tag: 1, label: 'Switch1' }]
|
|
108
|
-
// endpoint = endpoint.enable({features: { tagList: true }});
|
|
109
117
|
const optionsV8 = {
|
|
110
118
|
id: options.uniqueStorageKey?.replace(/[ .]/g, ''),
|
|
111
119
|
number: options.endpointId,
|
|
112
|
-
descriptor: options.tagList ? { tagList: options.tagList } :
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
120
|
+
descriptor: options.tagList ? { tagList: options.tagList, deviceTypeList } : { deviceTypeList },
|
|
114
121
|
};
|
|
115
122
|
super(endpointV8, optionsV8);
|
|
116
123
|
this.uniqueStorageKey = options.uniqueStorageKey;
|
|
124
|
+
this.name = firstDefinition.name;
|
|
125
|
+
this.deviceType = firstDefinition.code;
|
|
117
126
|
this.tagList = options.tagList;
|
|
127
|
+
if (Array.isArray(definition)) {
|
|
128
|
+
definition.forEach((deviceType) => {
|
|
129
|
+
this.deviceTypes.set(deviceType.code, deviceType);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
else
|
|
133
|
+
this.deviceTypes.set(firstDefinition.code, firstDefinition);
|
|
118
134
|
// console.log('MatterbridgeEndpoint.option', options);
|
|
119
135
|
// console.log('MatterbridgeEndpoint.endpointV8', endpointV8);
|
|
120
136
|
// console.log('MatterbridgeEndpoint.optionsV8', optionsV8);
|
|
121
|
-
//
|
|
137
|
+
// Create the logger
|
|
122
138
|
this.log = new AnsiLogger({ logName: 'MatterbridgeEndpoint', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: debug === true ? "debug" /* LogLevel.DEBUG */ : MatterbridgeEndpoint.logLevel });
|
|
123
139
|
this.log.debug(`${YELLOW}new${db} MatterbridgeEndpoint: ${zb}${'0x' + firstDefinition.code.toString(16).padStart(4, '0')}${db}-${zb}${firstDefinition.name}${db} ` +
|
|
124
140
|
`id: ${CYAN}${options.uniqueStorageKey}${db} number: ${CYAN}${options.endpointId}${db} taglist: ${CYAN}${options.tagList ? debugStringify(options.tagList) : 'undefined'}${db}`);
|
|
125
|
-
this.deviceTypes.set(firstDefinition.code, firstDefinition);
|
|
126
|
-
// Add the other device types to the descriptor server
|
|
127
|
-
if (Array.isArray(definition)) {
|
|
128
|
-
definition.forEach((deviceType) => {
|
|
129
|
-
this.addDeviceType(deviceType);
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
141
|
// Add MatterbridgeBehavior with MatterbridgeBehaviorDevice
|
|
133
142
|
this.behaviors.require(MatterbridgeBehavior, { deviceCommand: new MatterbridgeBehaviorDevice(this.log, this.commandHandler, undefined) });
|
|
134
143
|
}
|
|
@@ -164,7 +173,7 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
164
173
|
if (clusterId === Groups.Cluster.id)
|
|
165
174
|
return GroupsServer;
|
|
166
175
|
if (clusterId === OnOff.Cluster.id)
|
|
167
|
-
return MatterbridgeOnOffServer;
|
|
176
|
+
return MatterbridgeOnOffServer.with('Lighting');
|
|
168
177
|
if (clusterId === LevelControl.Cluster.id)
|
|
169
178
|
return MatterbridgeLevelControlServer;
|
|
170
179
|
if (clusterId === ColorControl.Cluster.id)
|
|
@@ -298,7 +307,12 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
298
307
|
});
|
|
299
308
|
});
|
|
300
309
|
includeServerList.forEach((clusterId) => {
|
|
301
|
-
this.
|
|
310
|
+
if (!this.getClusterServerById(clusterId)) {
|
|
311
|
+
this.log.debug(`- with cluster: ${hk}${'0x' + clusterId.toString(16).padStart(4, '0')}${db}-${hk}${getClusterNameById(clusterId)}${db}`);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
includeServerList.splice(includeServerList.indexOf(clusterId), 1);
|
|
315
|
+
}
|
|
302
316
|
});
|
|
303
317
|
deviceTypes.forEach((deviceType) => {
|
|
304
318
|
this.addDeviceType(deviceType);
|
|
@@ -349,6 +363,47 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
349
363
|
this.addClusterServerFromList(endpoint, optionalServerList);
|
|
350
364
|
return endpoint;
|
|
351
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* Adds a child endpoint with the specified device types and options.
|
|
368
|
+
* If the child endpoint is not already present, it will be created and added.
|
|
369
|
+
* If the child endpoint is already present, the device types will be added to the existing child endpoint.
|
|
370
|
+
*
|
|
371
|
+
* @param {string} endpointName - The name of the new endpoint to add.
|
|
372
|
+
* @param {AtLeastOne<DeviceTypeDefinition>} deviceTypes - The device types to add.
|
|
373
|
+
* @param {MatterbridgeEndpointOptions} [options={}] - The options for the endpoint.
|
|
374
|
+
* @param {boolean} [debug=false] - Whether to enable debug logging.
|
|
375
|
+
* @returns {MatterbridgeEndpoint} - The child endpoint that was found or added.
|
|
376
|
+
*/
|
|
377
|
+
addChildDeviceType(endpointName, deviceTypes, options = {}, debug = false) {
|
|
378
|
+
this.log.debug(`addChildDeviceType: ${CYAN}${endpointName}${db}`);
|
|
379
|
+
let child = this.getChildEndpointByName(endpointName);
|
|
380
|
+
if (!child) {
|
|
381
|
+
if ('tagList' in options) {
|
|
382
|
+
for (const tag of options.tagList) {
|
|
383
|
+
this.log.debug(`- with tagList: mfgCode ${CYAN}${tag.mfgCode}${db} namespaceId ${CYAN}${tag.namespaceId}${db} tag ${CYAN}${tag.tag}${db} label ${CYAN}${tag.label}${db}`);
|
|
384
|
+
}
|
|
385
|
+
child = new MatterbridgeEndpoint(deviceTypes[0], { uniqueStorageKey: endpointName, tagList: options.tagList }, debug);
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
child = new MatterbridgeEndpoint(deviceTypes[0], { uniqueStorageKey: endpointName }, debug);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
deviceTypes.forEach((deviceType) => {
|
|
392
|
+
this.log.debug(`- with deviceType: ${zb}${'0x' + deviceType.code.toString(16).padStart(4, '0')}${db}-${zb}${deviceType.name}${db}`);
|
|
393
|
+
});
|
|
394
|
+
deviceTypes.forEach((deviceType) => {
|
|
395
|
+
child.addDeviceType(deviceType);
|
|
396
|
+
});
|
|
397
|
+
if (this.lifecycle.isInstalled) {
|
|
398
|
+
this.log.debug(`- with lifecycle installed`);
|
|
399
|
+
this.add(child);
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
this.log.debug(`- with lifecycle NOT installed`);
|
|
403
|
+
this.parts.add(child);
|
|
404
|
+
}
|
|
405
|
+
return child;
|
|
406
|
+
}
|
|
352
407
|
/**
|
|
353
408
|
* Adds a child endpoint with one or more device types with the required cluster servers and the specified cluster servers.
|
|
354
409
|
* If the child endpoint is not already present in the childEndpoints, it will be added.
|
|
@@ -383,7 +438,15 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
383
438
|
});
|
|
384
439
|
});
|
|
385
440
|
includeServerList.forEach((clusterId) => {
|
|
386
|
-
|
|
441
|
+
if (!child.getClusterServerById(clusterId)) {
|
|
442
|
+
this.log.debug(`- with cluster: ${hk}${'0x' + clusterId.toString(16).padStart(4, '0')}${db}-${hk}${getClusterNameById(clusterId)}${db}`);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
includeServerList.splice(includeServerList.indexOf(clusterId), 1);
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
deviceTypes.forEach((deviceType) => {
|
|
449
|
+
child.addDeviceType(deviceType);
|
|
387
450
|
});
|
|
388
451
|
this.addClusterServerFromList(child, includeServerList);
|
|
389
452
|
if (this.lifecycle.isInstalled) {
|
|
@@ -419,6 +482,10 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
419
482
|
this.addDeviceType(deviceType);
|
|
420
483
|
});
|
|
421
484
|
}
|
|
485
|
+
async setBridgedDeviceReachability(reachable) {
|
|
486
|
+
// await this.setAttribute(BridgedDeviceBasicInformationCluster.id, 'reachable', reachable, this.log);
|
|
487
|
+
// await this.triggerEvent(BridgedDeviceBasicInformationCluster.id, 'reachableChanged', { reachableNewValue: reachable }, this.log);
|
|
488
|
+
}
|
|
422
489
|
hasClusterServer(cluster) {
|
|
423
490
|
return this.clusterServers.has(cluster.id);
|
|
424
491
|
}
|
|
@@ -428,6 +495,9 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
428
495
|
return clusterServer;
|
|
429
496
|
}
|
|
430
497
|
}
|
|
498
|
+
getAllClusterServers() {
|
|
499
|
+
return [...this.clusterServers.values()];
|
|
500
|
+
}
|
|
431
501
|
getClusterServerById(clusterId) {
|
|
432
502
|
return this.clusterServers.get(clusterId);
|
|
433
503
|
}
|
|
@@ -1121,34 +1191,53 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
1121
1191
|
/**
|
|
1122
1192
|
* Get a default OnOff cluster server.
|
|
1123
1193
|
*
|
|
1124
|
-
* @param onOff - The initial state of the OnOff cluster
|
|
1194
|
+
* @param {boolean} [onOff=false] - The initial state of the OnOff cluster.
|
|
1195
|
+
* @param {boolean} [globalSceneControl=false] - The global scene control state.
|
|
1196
|
+
* @param {number} [onTime=0] - The on time value.
|
|
1197
|
+
* @param {number} [offWaitTime=0] - The off wait time value.
|
|
1198
|
+
* @param {OnOff.StartUpOnOff | null} [startUpOnOff=null] - The start-up OnOff state. Null means previous state.
|
|
1199
|
+
* @returns {ClusterServer} - The configured OnOff cluster server.
|
|
1125
1200
|
*/
|
|
1126
|
-
getDefaultOnOffClusterServer(onOff = false) {
|
|
1127
|
-
return ClusterServer(OnOffCluster, {
|
|
1201
|
+
getDefaultOnOffClusterServer(onOff = false, globalSceneControl = false, onTime = 0, offWaitTime = 0, startUpOnOff = null) {
|
|
1202
|
+
return ClusterServer(OnOffCluster.with(OnOff.Feature.Lighting), {
|
|
1128
1203
|
onOff,
|
|
1204
|
+
globalSceneControl,
|
|
1205
|
+
onTime,
|
|
1206
|
+
offWaitTime,
|
|
1207
|
+
startUpOnOff,
|
|
1129
1208
|
}, {
|
|
1130
1209
|
on: async (data) => {
|
|
1131
|
-
|
|
1132
|
-
await this.commandHandler.executeHandler('on', data);
|
|
1210
|
+
// Never called in edge
|
|
1133
1211
|
},
|
|
1134
1212
|
off: async (data) => {
|
|
1135
|
-
|
|
1136
|
-
await this.commandHandler.executeHandler('off', data);
|
|
1213
|
+
// Never called in edge
|
|
1137
1214
|
},
|
|
1138
1215
|
toggle: async (data) => {
|
|
1139
|
-
|
|
1140
|
-
|
|
1216
|
+
// Never called in edge
|
|
1217
|
+
},
|
|
1218
|
+
offWithEffect: async () => {
|
|
1219
|
+
// Never called in edge
|
|
1220
|
+
},
|
|
1221
|
+
onWithRecallGlobalScene: async () => {
|
|
1222
|
+
// Never called in edge
|
|
1223
|
+
},
|
|
1224
|
+
onWithTimedOff: async () => {
|
|
1225
|
+
// Never called in edge
|
|
1141
1226
|
},
|
|
1142
1227
|
}, {});
|
|
1143
1228
|
}
|
|
1144
1229
|
/**
|
|
1145
1230
|
* Creates a default OnOff cluster server.
|
|
1146
1231
|
*
|
|
1147
|
-
* @param onOff - The initial state of the OnOff cluster
|
|
1232
|
+
* @param {boolean} [onOff=false] - The initial state of the OnOff cluster.
|
|
1233
|
+
* @param {boolean} [globalSceneControl=false] - The global scene control state.
|
|
1234
|
+
* @param {number} [onTime=0] - The on time value.
|
|
1235
|
+
* @param {number} [offWaitTime=0] - The off wait time value.
|
|
1236
|
+
* @param {OnOff.StartUpOnOff | null} [startUpOnOff=null] - The start-up OnOff state. Null means previous state.
|
|
1148
1237
|
* @returns {void}
|
|
1149
1238
|
*/
|
|
1150
|
-
createDefaultOnOffClusterServer(onOff = false) {
|
|
1151
|
-
this.addClusterServer(this.getDefaultOnOffClusterServer(onOff));
|
|
1239
|
+
createDefaultOnOffClusterServer(onOff = false, globalSceneControl = false, onTime = 0, offWaitTime = 0, startUpOnOff = null) {
|
|
1240
|
+
this.addClusterServer(this.getDefaultOnOffClusterServer(onOff, globalSceneControl, onTime, offWaitTime, startUpOnOff));
|
|
1152
1241
|
}
|
|
1153
1242
|
/**
|
|
1154
1243
|
* Get a default level control cluster server.
|
|
@@ -1158,7 +1247,7 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
1158
1247
|
* @param maxLevel - The maximum level (default: 254).
|
|
1159
1248
|
* @param onLevel - The on level (default: null).
|
|
1160
1249
|
*/
|
|
1161
|
-
getDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 0, maxLevel = 254, onLevel =
|
|
1250
|
+
getDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 0, maxLevel = 254, onLevel = 254) {
|
|
1162
1251
|
return ClusterServer(LevelControlCluster.with(LevelControl.Feature.OnOff), {
|
|
1163
1252
|
currentLevel,
|
|
1164
1253
|
minLevel,
|
|
@@ -1205,7 +1294,7 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
1205
1294
|
* @param maxLevel - The maximum level (default: 254).
|
|
1206
1295
|
* @param onLevel - The on level (default: null).
|
|
1207
1296
|
*/
|
|
1208
|
-
createDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 0, maxLevel = 254, onLevel =
|
|
1297
|
+
createDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 0, maxLevel = 254, onLevel = 254) {
|
|
1209
1298
|
this.addClusterServer(this.getDefaultLevelControlClusterServer(currentLevel, minLevel, maxLevel, onLevel));
|
|
1210
1299
|
}
|
|
1211
1300
|
/**
|