matterbridge 1.3.8 → 1.3.10
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 +29 -0
- package/__mocks__/@project-chip/matter-node.js/util.js +41 -0
- package/dist/cluster/ElectricalPowerMeasurementCluster.js +4 -4
- package/dist/cluster/ElectricalPowerMeasurementCluster.js.map +1 -1
- package/dist/matterbridge.d.ts +57 -6
- package/dist/matterbridge.d.ts.map +1 -1
- package/dist/matterbridge.js +183 -57
- package/dist/matterbridge.js.map +1 -1
- package/dist/utils.d.ts +21 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +23 -2
- package/dist/utils.js.map +1 -1
- package/frontend/build/asset-manifest.json +6 -6
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/css/main.8e9f022b.css +2 -0
- package/frontend/build/static/css/main.8e9f022b.css.map +1 -0
- package/frontend/build/static/js/{main.942a74a2.js → main.cf22e7af.js} +3 -3
- package/frontend/build/static/js/{main.942a74a2.js.map → main.cf22e7af.js.map} +1 -1
- package/package.json +5 -4
- package/dist/matterbridgeDeviceV8.d.ts +0 -2981
- package/dist/matterbridgeDeviceV8.d.ts.map +0 -1
- package/dist/matterbridgeDeviceV8.js +0 -1888
- package/dist/matterbridgeDeviceV8.js.map +0 -1
- package/dist/matterbridgeV8.d.ts +0 -142
- package/dist/matterbridgeV8.d.ts.map +0 -1
- package/dist/matterbridgeV8.js +0 -703
- package/dist/matterbridgeV8.js.map +0 -1
- package/frontend/build/static/css/main.abff2627.css +0 -8
- package/frontend/build/static/css/main.abff2627.css.map +0 -1
- /package/frontend/build/static/js/{main.942a74a2.js.LICENSE.txt → main.cf22e7af.js.LICENSE.txt} +0 -0
package/dist/matterbridge.js
CHANGED
|
@@ -79,7 +79,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
79
79
|
globalModulesDirectory: '',
|
|
80
80
|
matterbridgeVersion: '',
|
|
81
81
|
matterbridgeLatestVersion: '',
|
|
82
|
-
|
|
82
|
+
matterbridgeFabricInformations: [],
|
|
83
|
+
matterbridgeSessionInformations: [],
|
|
83
84
|
matterbridgePaired: false,
|
|
84
85
|
matterbridgeConnected: false,
|
|
85
86
|
bridgeMode: '',
|
|
@@ -93,15 +94,18 @@ export class Matterbridge extends EventEmitter {
|
|
|
93
94
|
globalModulesDirectory = '';
|
|
94
95
|
matterbridgeVersion = '';
|
|
95
96
|
matterbridgeLatestVersion = '';
|
|
96
|
-
|
|
97
|
+
matterbridgeFabricInformations = [];
|
|
97
98
|
matterbridgePaired = false;
|
|
98
99
|
matterbridgeConnected = false;
|
|
100
|
+
matterbridgeSessionInformations = [];
|
|
99
101
|
checkUpdateInterval; // = 24 * 60 * 60 * 1000; // 24 hours
|
|
100
102
|
bridgeMode = '';
|
|
101
103
|
restartMode = '';
|
|
102
104
|
debugEnabled = false;
|
|
103
105
|
mdnsInterface; // matter server mdnsInterface: 'eth0' or 'wlan0' or 'WiFi'
|
|
104
106
|
port = 5540; // first commissioning server port
|
|
107
|
+
passcode; // first commissioning server passcode
|
|
108
|
+
discriminator; // first commissioning server discriminator
|
|
105
109
|
log;
|
|
106
110
|
hasCleanupStarted = false;
|
|
107
111
|
// private plugins = new Map<string, RegisteredPlugin>();
|
|
@@ -145,6 +149,14 @@ export class Matterbridge extends EventEmitter {
|
|
|
145
149
|
}
|
|
146
150
|
return Matterbridge.instance;
|
|
147
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Call shutdownProcess.
|
|
154
|
+
* @deprecated This method is deprecated and is only used for jest.
|
|
155
|
+
*
|
|
156
|
+
*/
|
|
157
|
+
async destroyInstance() {
|
|
158
|
+
await this.shutdownProcess();
|
|
159
|
+
}
|
|
148
160
|
/**
|
|
149
161
|
* Initializes the Matterbridge instance as extension for zigbee2mqtt.
|
|
150
162
|
* @deprecated This method is deprecated and will be removed in a future version.
|
|
@@ -271,7 +283,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
271
283
|
- reset: remove the commissioning for Matterbridge (bridge mode). Shutdown Matterbridge before using it!
|
|
272
284
|
- factoryreset: remove all commissioning information and reset all internal storages. Shutdown Matterbridge before using it!
|
|
273
285
|
- list: list the registered plugins
|
|
274
|
-
- loginterfaces: log the network interfaces
|
|
286
|
+
- loginterfaces: log the network interfaces (usefull for finding the name of the interface to use with -mdnsinterface option)
|
|
275
287
|
- logstorage: log the node storage
|
|
276
288
|
- ssl: enable SSL for the frontend and WebSockerServer (certificates in .matterbridge/certs directory cert.pem, key.pem and ca.pem (optional))
|
|
277
289
|
- add [plugin path]: register the plugin from the given absolute or relative path
|
|
@@ -290,6 +302,10 @@ export class Matterbridge extends EventEmitter {
|
|
|
290
302
|
this.mdnsInterface = getParameter('mdnsinterface');
|
|
291
303
|
// Set the first port to use for the commissioning server
|
|
292
304
|
this.port = getIntParameter('port') ?? 5540;
|
|
305
|
+
// Set the first passcode to use for the commissioning server
|
|
306
|
+
this.passcode = getIntParameter('passcode');
|
|
307
|
+
// Set the first discriminator to use for the commissioning server
|
|
308
|
+
this.discriminator = getIntParameter('discriminator');
|
|
293
309
|
// Set the restart mode
|
|
294
310
|
if (hasParameter('service'))
|
|
295
311
|
this.restartMode = 'service';
|
|
@@ -310,6 +326,27 @@ export class Matterbridge extends EventEmitter {
|
|
|
310
326
|
// Get the plugins from node storage and create the plugin node storage contexts
|
|
311
327
|
this.registeredPlugins = await this.nodeContext.get('plugins', []);
|
|
312
328
|
for (const plugin of this.registeredPlugins) {
|
|
329
|
+
const packageJson = await this.parsePlugin(plugin);
|
|
330
|
+
if (packageJson) {
|
|
331
|
+
// Update the plugin information
|
|
332
|
+
plugin.name = packageJson.name;
|
|
333
|
+
plugin.version = packageJson.version;
|
|
334
|
+
plugin.description = packageJson.description;
|
|
335
|
+
plugin.author = packageJson.author;
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
this.log.info(`Error parsing plugin ${plg}${plugin.name}${nf}. Trying to reinstall it from npm.`);
|
|
339
|
+
try {
|
|
340
|
+
await this.spawnCommand('npm', ['install', '-g', plugin.name]);
|
|
341
|
+
this.log.info(`Plugin ${plg}${plugin.name}${nf} reinstalled.`);
|
|
342
|
+
plugin.error = false;
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
plugin.error = true;
|
|
346
|
+
plugin.enabled = false;
|
|
347
|
+
this.log.error(`Error installing plugin ${plg}${plugin.name}${er}. The plugin is disabled.`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
313
350
|
this.log.debug(`Creating node storage context for plugin ${plugin.name}`);
|
|
314
351
|
plugin.nodeContext = await this.nodeStorage.createStorage(plugin.name);
|
|
315
352
|
await plugin.nodeContext.set('name', plugin.name);
|
|
@@ -322,7 +359,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
322
359
|
// Log system info and create .matterbridge directory
|
|
323
360
|
await this.logNodeAndSystemInfo();
|
|
324
361
|
this.log.info(`Matterbridge version ${this.matterbridgeVersion} mode ${hasParameter('bridge') ? 'bridge' : ''}${hasParameter('childbridge') ? 'childbridge' : ''}${hasParameter('controller') ? 'controller' : ''} ` +
|
|
325
|
-
`${this.restartMode !== '' ? 'restart mode ' + this.restartMode + ' ' : ''}running on ${this.systemInformation.osType} ${this.systemInformation.osRelease} ${this.systemInformation.osPlatform} ${this.systemInformation.osArch}`);
|
|
362
|
+
`${this.restartMode !== '' ? 'restart mode ' + this.restartMode + ' ' : ''}running on ${this.systemInformation.osType} ${this.systemInformation.osRelease} ${this.systemInformation.osPlatform} ${this.systemInformation.osArch} `);
|
|
326
363
|
// Check node version and throw error
|
|
327
364
|
requireMinNodeVersion(18);
|
|
328
365
|
// Register SIGINT SIGTERM signal handlers
|
|
@@ -471,7 +508,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
471
508
|
process.exit(0);
|
|
472
509
|
}
|
|
473
510
|
// Initialize frontend
|
|
474
|
-
|
|
511
|
+
if (getIntParameter('frontend') !== 0 || getIntParameter('frontend') === undefined)
|
|
512
|
+
await this.initializeFrontend(getIntParameter('frontend'));
|
|
475
513
|
// Check each 60 minutes the latest versions
|
|
476
514
|
this.checkUpdateInterval = setInterval(() => {
|
|
477
515
|
this.getMatterbridgeLatestVersion();
|
|
@@ -521,6 +559,14 @@ export class Matterbridge extends EventEmitter {
|
|
|
521
559
|
for (const plugin of this.registeredPlugins) {
|
|
522
560
|
plugin.configJson = await this.loadPluginConfig(plugin);
|
|
523
561
|
plugin.schemaJson = await this.loadPluginSchema(plugin);
|
|
562
|
+
// Check if the plugin is available
|
|
563
|
+
if (!(await this.resolvePluginName(plugin.path))) {
|
|
564
|
+
this.log.error(`Plugin ${plg}${plugin.name}${er} not found. Disabling it.`);
|
|
565
|
+
plugin.enabled = false;
|
|
566
|
+
plugin.error = true;
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
// Check if the plugin has a new version
|
|
524
570
|
this.getPluginLatestVersion(plugin);
|
|
525
571
|
if (!plugin.enabled) {
|
|
526
572
|
this.log.info(`Plugin ${plg}${plugin.name}${nf} not enabled`);
|
|
@@ -554,6 +600,14 @@ export class Matterbridge extends EventEmitter {
|
|
|
554
600
|
for (const plugin of this.registeredPlugins) {
|
|
555
601
|
plugin.configJson = await this.loadPluginConfig(plugin);
|
|
556
602
|
plugin.schemaJson = await this.loadPluginSchema(plugin);
|
|
603
|
+
// Check if the plugin is available
|
|
604
|
+
if (!(await this.resolvePluginName(plugin.path))) {
|
|
605
|
+
this.log.error(`Plugin ${plg}${plugin.name}${er} not found. Disabling it.`);
|
|
606
|
+
plugin.enabled = false;
|
|
607
|
+
plugin.error = true;
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
// Check if the plugin has a new version
|
|
557
611
|
this.getPluginLatestVersion(plugin);
|
|
558
612
|
if (!plugin.enabled) {
|
|
559
613
|
this.log.info(`Plugin ${plg}${plugin.name}${nf} not enabled`);
|
|
@@ -906,7 +960,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
906
960
|
});
|
|
907
961
|
this.webSocketServer = undefined;
|
|
908
962
|
}
|
|
909
|
-
setTimeout(async () => {
|
|
963
|
+
const clenupTimeout1 = setTimeout(async () => {
|
|
910
964
|
// Closing matter
|
|
911
965
|
await this.stopMatter();
|
|
912
966
|
// Closing storage
|
|
@@ -937,7 +991,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
937
991
|
this.registeredPlugins = [];
|
|
938
992
|
this.registeredDevices = [];
|
|
939
993
|
this.log.info('Waiting for matter to deliver last messages...');
|
|
940
|
-
setTimeout(async () => {
|
|
994
|
+
const clenupTimeout2 = setTimeout(async () => {
|
|
941
995
|
if (restart) {
|
|
942
996
|
if (message === 'updating...') {
|
|
943
997
|
this.log.info('Cleanup completed. Updating...');
|
|
@@ -971,7 +1025,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
971
1025
|
this.emit('shutdown');
|
|
972
1026
|
}
|
|
973
1027
|
}, 2 * 1000);
|
|
1028
|
+
clenupTimeout2.unref();
|
|
974
1029
|
}, 3 * 1000);
|
|
1030
|
+
clenupTimeout1.unref();
|
|
975
1031
|
}
|
|
976
1032
|
}
|
|
977
1033
|
/**
|
|
@@ -1016,7 +1072,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
1016
1072
|
if (!plugin.locked) {
|
|
1017
1073
|
plugin.locked = true;
|
|
1018
1074
|
this.log.debug(`Creating commissioning server context for ${plg}${plugin.name}${db}`);
|
|
1019
|
-
plugin.storageContext = await this.createCommissioningServerContext(plugin.name, 'Matterbridge', DeviceTypes.AGGREGATOR.code, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Dynamic Platform');
|
|
1075
|
+
// plugin.storageContext = await this.createCommissioningServerContext(plugin.name, 'Matterbridge', DeviceTypes.AGGREGATOR.code, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Dynamic Platform');
|
|
1076
|
+
plugin.storageContext = await this.createCommissioningServerContext(plugin.name, 'Matterbridge', DeviceTypes.AGGREGATOR.code, 0xfff1, 'Matterbridge', 0x8000, plugin.description);
|
|
1020
1077
|
this.log.debug(`Creating commissioning server for ${plg}${plugin.name}${db}`);
|
|
1021
1078
|
plugin.commissioningServer = await this.createCommisioningServer(plugin.storageContext, plugin.name);
|
|
1022
1079
|
this.log.debug(`Creating aggregator for plugin ${plg}${plugin.name}${db}`);
|
|
@@ -1453,6 +1510,23 @@ export class Matterbridge extends EventEmitter {
|
|
|
1453
1510
|
return Promise.resolve();
|
|
1454
1511
|
}
|
|
1455
1512
|
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Loads and parse the plugin package.json and returns it.
|
|
1515
|
+
* @param plugin - The plugin to load the package from.
|
|
1516
|
+
* @returns A Promise that resolves to the package.json object or undefined if the package.json could not be loaded.
|
|
1517
|
+
*/
|
|
1518
|
+
async parsePlugin(plugin) {
|
|
1519
|
+
this.log.debug(`Parsing package.json of plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
|
|
1520
|
+
try {
|
|
1521
|
+
const packageJson = JSON.parse(await fs.readFile(plugin.path, 'utf8'));
|
|
1522
|
+
return packageJson;
|
|
1523
|
+
}
|
|
1524
|
+
catch (err) {
|
|
1525
|
+
this.log.error(`Failed to parse plugin ${plg}${plugin.name}${er} package.json: ${err}`);
|
|
1526
|
+
plugin.error = true;
|
|
1527
|
+
return undefined;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1456
1530
|
/**
|
|
1457
1531
|
* Loads a plugin and returns the corresponding MatterbridgePlatform instance.
|
|
1458
1532
|
* @param plugin - The plugin to load.
|
|
@@ -1937,12 +2011,21 @@ export class Matterbridge extends EventEmitter {
|
|
|
1937
2011
|
const QrCode = new QrCodeSchema();
|
|
1938
2012
|
this.log.info(`***The commissioning server on port ${commissioningServer.getPort()} for ${plg}${pluginName}${nf} is not commissioned. Pair it scanning the QR code:\n\n` +
|
|
1939
2013
|
`${QrCode.encode(qrPairingCode)}\n${plg}${pluginName}${nf}\n\nqrPairingCode: ${qrPairingCode}\n\nManual pairing code: ${manualPairingCode}\n`);
|
|
2014
|
+
if (pluginName === 'Matterbridge') {
|
|
2015
|
+
this.matterbridgeFabricInformations = [];
|
|
2016
|
+
this.matterbridgeSessionInformations = [];
|
|
2017
|
+
this.matterbridgePaired = false;
|
|
2018
|
+
this.matterbridgeConnected = false;
|
|
2019
|
+
}
|
|
1940
2020
|
if (pluginName !== 'Matterbridge') {
|
|
1941
2021
|
const plugin = this.findPlugin(pluginName);
|
|
1942
2022
|
if (plugin) {
|
|
1943
2023
|
plugin.qrPairingCode = qrPairingCode;
|
|
1944
2024
|
plugin.manualPairingCode = manualPairingCode;
|
|
2025
|
+
plugin.fabricInformations = [];
|
|
2026
|
+
plugin.sessionInformations = [];
|
|
1945
2027
|
plugin.paired = false;
|
|
2028
|
+
plugin.connected = false;
|
|
1946
2029
|
}
|
|
1947
2030
|
}
|
|
1948
2031
|
await this.nodeContext?.set('plugins', await this.getBaseRegisteredPlugins());
|
|
@@ -1956,19 +2039,71 @@ export class Matterbridge extends EventEmitter {
|
|
|
1956
2039
|
this.log.info(`- fabric index ${zb}${info.fabricIndex}${nf} id ${zb}${info.fabricId}${nf} vendor ${zb}${info.rootVendorId}${nf} ${this.getVendorIdName(info.rootVendorId)} ${info.label}`);
|
|
1957
2040
|
});
|
|
1958
2041
|
if (pluginName === 'Matterbridge') {
|
|
1959
|
-
this.
|
|
2042
|
+
this.matterbridgeFabricInformations = this.sanitizeFabricInformations(fabricInfo);
|
|
2043
|
+
this.matterbridgeSessionInformations = [];
|
|
1960
2044
|
this.matterbridgePaired = true;
|
|
1961
2045
|
}
|
|
1962
2046
|
if (pluginName !== 'Matterbridge') {
|
|
1963
2047
|
const plugin = this.findPlugin(pluginName);
|
|
1964
2048
|
if (plugin) {
|
|
1965
|
-
plugin.
|
|
2049
|
+
plugin.fabricInformations = this.sanitizeFabricInformations(fabricInfo);
|
|
2050
|
+
plugin.sessionInformations = [];
|
|
1966
2051
|
plugin.paired = true;
|
|
1967
2052
|
}
|
|
1968
2053
|
}
|
|
1969
2054
|
await this.nodeContext?.set('plugins', await this.getBaseRegisteredPlugins());
|
|
1970
2055
|
}
|
|
1971
2056
|
}
|
|
2057
|
+
/**
|
|
2058
|
+
* Sanitizes the fabric information by converting bigint properties to string cause res..
|
|
2059
|
+
*
|
|
2060
|
+
* @param fabricInfo - The array of exposed fabric information objects.
|
|
2061
|
+
* @returns An array of sanitized exposed fabric information objects.
|
|
2062
|
+
*/
|
|
2063
|
+
sanitizeFabricInformations(fabricInfo) {
|
|
2064
|
+
return fabricInfo.map((info) => {
|
|
2065
|
+
return {
|
|
2066
|
+
fabricIndex: info.fabricIndex,
|
|
2067
|
+
fabricId: info.fabricId.toString(),
|
|
2068
|
+
nodeId: info.nodeId.toString(),
|
|
2069
|
+
rootNodeId: info.rootNodeId.toString(),
|
|
2070
|
+
rootVendorId: info.rootVendorId,
|
|
2071
|
+
rootVendorName: this.getVendorIdName(info.rootVendorId),
|
|
2072
|
+
label: info.label,
|
|
2073
|
+
};
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
/**
|
|
2077
|
+
* Sanitizes the session information by converting bigint properties to string.
|
|
2078
|
+
*
|
|
2079
|
+
* @param sessionInfo - The array of session information objects.
|
|
2080
|
+
* @returns An array of sanitized session information objects.
|
|
2081
|
+
*/
|
|
2082
|
+
sanitizeSessionInformation(sessionInfo) {
|
|
2083
|
+
return sessionInfo.map((info) => {
|
|
2084
|
+
return {
|
|
2085
|
+
name: info.name,
|
|
2086
|
+
nodeId: info.nodeId.toString(),
|
|
2087
|
+
peerNodeId: info.peerNodeId.toString(),
|
|
2088
|
+
fabric: info.fabric
|
|
2089
|
+
? {
|
|
2090
|
+
fabricIndex: info.fabric.fabricIndex,
|
|
2091
|
+
fabricId: info.fabric.fabricId.toString(),
|
|
2092
|
+
nodeId: info.fabric.nodeId.toString(),
|
|
2093
|
+
rootNodeId: info.fabric.rootNodeId.toString(),
|
|
2094
|
+
rootVendorId: info.fabric.rootVendorId,
|
|
2095
|
+
rootVendorName: this.getVendorIdName(info.fabric.rootVendorId),
|
|
2096
|
+
label: info.fabric.label,
|
|
2097
|
+
}
|
|
2098
|
+
: undefined,
|
|
2099
|
+
isPeerActive: info.isPeerActive,
|
|
2100
|
+
secure: info.secure,
|
|
2101
|
+
lastInteractionTimestamp: info.lastInteractionTimestamp,
|
|
2102
|
+
lastActiveTimestamp: info.lastActiveTimestamp,
|
|
2103
|
+
numberOfActiveSubscriptions: info.numberOfActiveSubscriptions,
|
|
2104
|
+
};
|
|
2105
|
+
});
|
|
2106
|
+
}
|
|
1972
2107
|
/**
|
|
1973
2108
|
* Finds a plugin by its name.
|
|
1974
2109
|
*
|
|
@@ -2055,6 +2190,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
2055
2190
|
case 4742:
|
|
2056
2191
|
vendorName = '(eWeLink)';
|
|
2057
2192
|
break;
|
|
2193
|
+
case 65521:
|
|
2194
|
+
vendorName = '(PythonMatterServer)';
|
|
2195
|
+
break;
|
|
2058
2196
|
default:
|
|
2059
2197
|
vendorName = '(unknown)';
|
|
2060
2198
|
break;
|
|
@@ -2082,16 +2220,17 @@ export class Matterbridge extends EventEmitter {
|
|
|
2082
2220
|
const softwareVersionString = await context.get('softwareVersionString', '1.0.0'); // Home app = Firmware Revision
|
|
2083
2221
|
const hardwareVersion = await context.get('hardwareVersion', 1);
|
|
2084
2222
|
const hardwareVersionString = await context.get('hardwareVersionString', '1.0.0');
|
|
2085
|
-
this.log.debug(`Creating matter commissioning server for plugin ${plg}${pluginName}${db} with deviceName ${deviceName} deviceType ${deviceType}(0x${deviceType.toString(16).padStart(4, '0')})`);
|
|
2223
|
+
this.log.debug(`Creating matter commissioning server for plugin ${plg}${pluginName}${db} with deviceName '${deviceName}' deviceType ${deviceType}(0x${deviceType.toString(16).padStart(4, '0')})`);
|
|
2086
2224
|
this.log.debug(`Creating matter commissioning server for plugin ${plg}${pluginName}${db} with uniqueId ${uniqueId} serialNumber ${serialNumber}`);
|
|
2087
2225
|
this.log.debug(`Creating matter commissioning server for plugin ${plg}${pluginName}${db} with softwareVersion ${softwareVersion} softwareVersionString ${softwareVersionString}`);
|
|
2088
2226
|
this.log.debug(`Creating matter commissioning server for plugin ${plg}${pluginName}${db} with hardwareVersion ${hardwareVersion} hardwareVersionString ${hardwareVersionString}`);
|
|
2227
|
+
this.log.debug(`Creating matter commissioning server for plugin ${plg}${pluginName}${db} with nodeLabel '${productName}' port ${this.port} passcode ${this.passcode} discriminator ${this.discriminator}`);
|
|
2089
2228
|
const commissioningServer = new CommissioningServer({
|
|
2090
2229
|
port: this.port++,
|
|
2091
2230
|
// listeningAddressIpv4
|
|
2092
2231
|
// listeningAddressIpv6
|
|
2093
|
-
passcode:
|
|
2094
|
-
discriminator:
|
|
2232
|
+
passcode: this.passcode,
|
|
2233
|
+
discriminator: this.discriminator,
|
|
2095
2234
|
deviceName,
|
|
2096
2235
|
deviceType,
|
|
2097
2236
|
basicInformation: {
|
|
@@ -2110,9 +2249,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
2110
2249
|
reachable: true,
|
|
2111
2250
|
},
|
|
2112
2251
|
activeSessionsChangedCallback: (fabricIndex) => {
|
|
2113
|
-
const
|
|
2252
|
+
const sessionInformations = commissioningServer.getActiveSessionInformation(fabricIndex);
|
|
2114
2253
|
let connected = false;
|
|
2115
|
-
|
|
2254
|
+
sessionInformations.forEach((session) => {
|
|
2116
2255
|
this.log.info(`*Active session changed on fabric ${zb}${fabricIndex}${nf} id ${zb}${session.fabric?.fabricId}${nf} vendor ${zb}${session.fabric?.rootVendorId}${nf} ${this.getVendorIdName(session.fabric?.rootVendorId)} ${session.fabric?.label} for ${plg}${pluginName}${nf}`, debugStringify(session));
|
|
2117
2256
|
if (session.isPeerActive === true && session.secure === true && session.numberOfActiveSubscriptions >= 1) {
|
|
2118
2257
|
this.log.info(`*Controller ${zb}${session.fabric?.rootVendorId}${nf} ${this.getVendorIdName(session.fabric?.rootVendorId)} ${session.fabric?.label} connected to ${plg}${pluginName}${nf} on session ${session.name}`);
|
|
@@ -2123,12 +2262,14 @@ export class Matterbridge extends EventEmitter {
|
|
|
2123
2262
|
if (this.bridgeMode === 'bridge') {
|
|
2124
2263
|
this.matterbridgePaired = true;
|
|
2125
2264
|
this.matterbridgeConnected = true;
|
|
2265
|
+
this.matterbridgeSessionInformations = this.sanitizeSessionInformation(sessionInformations);
|
|
2126
2266
|
}
|
|
2127
2267
|
if (this.bridgeMode === 'childbridge') {
|
|
2128
2268
|
const plugin = this.findPlugin(pluginName);
|
|
2129
2269
|
if (plugin) {
|
|
2130
2270
|
plugin.paired = true;
|
|
2131
2271
|
plugin.connected = true;
|
|
2272
|
+
plugin.sessionInformations = this.sanitizeSessionInformation(sessionInformations);
|
|
2132
2273
|
}
|
|
2133
2274
|
}
|
|
2134
2275
|
setTimeout(() => {
|
|
@@ -2171,7 +2312,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
2171
2312
|
await commissioningServer.factoryReset();
|
|
2172
2313
|
if (pluginName === 'Matterbridge') {
|
|
2173
2314
|
await this.matterbridgeContext?.clearAll();
|
|
2174
|
-
this.
|
|
2315
|
+
this.matterbridgeFabricInformations = [];
|
|
2316
|
+
this.matterbridgeSessionInformations = [];
|
|
2175
2317
|
this.matterbridgePaired = false;
|
|
2176
2318
|
this.matterbridgeConnected = false;
|
|
2177
2319
|
}
|
|
@@ -2179,17 +2321,36 @@ export class Matterbridge extends EventEmitter {
|
|
|
2179
2321
|
for (const plugin of this.registeredPlugins) {
|
|
2180
2322
|
if (plugin.name === pluginName) {
|
|
2181
2323
|
await plugin.platform?.onShutdown('Commissioning removed by the controller');
|
|
2182
|
-
plugin.
|
|
2324
|
+
plugin.fabricInformations = [];
|
|
2325
|
+
plugin.sessionInformations = [];
|
|
2183
2326
|
plugin.paired = false;
|
|
2184
2327
|
plugin.connected = false;
|
|
2185
2328
|
await plugin.storageContext?.clearAll();
|
|
2186
2329
|
}
|
|
2187
2330
|
}
|
|
2188
2331
|
}
|
|
2189
|
-
this.log.warn(`*Restart to activate the pairing for ${plg}${pluginName}${wr}
|
|
2332
|
+
this.log.warn(`*Restart to activate the pairing for ${plg}${pluginName}${wr}.`);
|
|
2333
|
+
}
|
|
2334
|
+
else {
|
|
2335
|
+
const fabricInfo = commissioningServer.getCommissionedFabricInformation();
|
|
2336
|
+
if (pluginName === 'Matterbridge') {
|
|
2337
|
+
this.matterbridgeFabricInformations = this.sanitizeFabricInformations(fabricInfo);
|
|
2338
|
+
this.matterbridgePaired = true;
|
|
2339
|
+
}
|
|
2340
|
+
else {
|
|
2341
|
+
const plugin = this.findPlugin(pluginName);
|
|
2342
|
+
if (plugin) {
|
|
2343
|
+
plugin.fabricInformations = this.sanitizeFabricInformations(fabricInfo);
|
|
2344
|
+
plugin.paired = true;
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2190
2347
|
}
|
|
2191
2348
|
},
|
|
2192
2349
|
});
|
|
2350
|
+
if (this.passcode !== undefined)
|
|
2351
|
+
this.passcode++;
|
|
2352
|
+
if (this.discriminator !== undefined)
|
|
2353
|
+
this.discriminator++;
|
|
2193
2354
|
commissioningServer.addCommandHandler('testEventTrigger', async ({ request: { enableKey, eventTrigger } }) => this.log.info(`testEventTrigger called on GeneralDiagnostic cluster: ${enableKey} ${eventTrigger}`));
|
|
2194
2355
|
return commissioningServer;
|
|
2195
2356
|
}
|
|
@@ -2537,7 +2698,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
2537
2698
|
configured: plugin.configured,
|
|
2538
2699
|
paired: plugin.paired,
|
|
2539
2700
|
connected: plugin.connected,
|
|
2540
|
-
|
|
2701
|
+
fabricInformations: plugin.fabricInformations,
|
|
2702
|
+
sessionInformations: plugin.sessionInformations,
|
|
2541
2703
|
registeredDevices: plugin.registeredDevices,
|
|
2542
2704
|
addedDevices: plugin.addedDevices,
|
|
2543
2705
|
qrPairingCode: plugin.qrPairingCode,
|
|
@@ -2761,43 +2923,6 @@ export class Matterbridge extends EventEmitter {
|
|
|
2761
2923
|
this.webSocketServer.on('error', (ws, error) => {
|
|
2762
2924
|
this.log.error(`WebSocketServer error: ${error}`);
|
|
2763
2925
|
});
|
|
2764
|
-
/*
|
|
2765
|
-
// Create a WebSocket server
|
|
2766
|
-
const wssPort = 8284;
|
|
2767
|
-
const wssHost = `ws://${this.systemInformation.ipv4Address}:${wssPort}`;
|
|
2768
|
-
this.webSocketServer = new WebSocketServer({ port: wssPort, host: this.systemInformation.ipv4Address });
|
|
2769
|
-
this.log.debug(`WebSocket server created on ${UNDERLINE}${wssHost}${UNDERLINEOFF}${rs}`);
|
|
2770
|
-
|
|
2771
|
-
this.webSocketServer.on('listening', () => {
|
|
2772
|
-
this.log.info(`WebSocketServer is listening on ${UNDERLINE}${wssHost}${UNDERLINEOFF}${rs}`);
|
|
2773
|
-
return;
|
|
2774
|
-
});
|
|
2775
|
-
*/
|
|
2776
|
-
/*
|
|
2777
|
-
// Serve React build directory
|
|
2778
|
-
this.expressApp = express();
|
|
2779
|
-
this.expressApp.use(express.static(path.join(this.rootDirectory, 'frontend/build')));
|
|
2780
|
-
|
|
2781
|
-
// Listen on HTTP
|
|
2782
|
-
this.expressServer = this.expressApp.listen(port, () => {
|
|
2783
|
-
this.log.info(`The frontend is listening on ${UNDERLINE}http://${this.systemInformation.ipv4Address}:${port}${UNDERLINEOFF}${rs}`);
|
|
2784
|
-
this.log.debug(`The frontend is listening on ${UNDERLINE}http://[${this.systemInformation.ipv6Address}]:${port}${UNDERLINEOFF}${rs}`);
|
|
2785
|
-
});
|
|
2786
|
-
|
|
2787
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2788
|
-
this.expressServer.on('error', (error: any) => {
|
|
2789
|
-
this.log.error(`Frontend error listening on ${UNDERLINE}http://${this.systemInformation.ipv4Address}:${port}${UNDERLINEOFF}${rs}`);
|
|
2790
|
-
switch (error.code) {
|
|
2791
|
-
case 'EACCES':
|
|
2792
|
-
this.log.error(`Port ${port} requires elevated privileges`);
|
|
2793
|
-
break;
|
|
2794
|
-
case 'EADDRINUSE':
|
|
2795
|
-
this.log.error(`Port ${port} is already in use`);
|
|
2796
|
-
break;
|
|
2797
|
-
}
|
|
2798
|
-
process.exit(1);
|
|
2799
|
-
});
|
|
2800
|
-
*/
|
|
2801
2926
|
// Endpoint to validate login code
|
|
2802
2927
|
this.expressApp.post('/api/login', express.json(), async (req, res) => {
|
|
2803
2928
|
const { password } = req.body;
|
|
@@ -2846,7 +2971,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
2846
2971
|
this.matterbridgeInformation.debugEnabled = this.debugEnabled;
|
|
2847
2972
|
this.matterbridgeInformation.matterbridgePaired = this.matterbridgePaired;
|
|
2848
2973
|
this.matterbridgeInformation.matterbridgeConnected = this.matterbridgeConnected;
|
|
2849
|
-
|
|
2974
|
+
this.matterbridgeInformation.matterbridgeFabricInformations = this.matterbridgeFabricInformations;
|
|
2975
|
+
this.matterbridgeInformation.matterbridgeSessionInformations = this.matterbridgeSessionInformations;
|
|
2850
2976
|
const response = { wssHost, qrPairingCode, manualPairingCode, systemInformation: this.systemInformation, matterbridgeInformation: this.matterbridgeInformation };
|
|
2851
2977
|
// this.log.debug('Response:', debugStringify(response));
|
|
2852
2978
|
res.json(response);
|