matterbridge 1.3.9 → 1.3.11

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.
@@ -79,12 +79,14 @@ export class Matterbridge extends EventEmitter {
79
79
  globalModulesDirectory: '',
80
80
  matterbridgeVersion: '',
81
81
  matterbridgeLatestVersion: '',
82
- matterbridgeFabricInfo: [],
82
+ matterbridgeFabricInformations: [],
83
+ matterbridgeSessionInformations: [],
83
84
  matterbridgePaired: false,
84
85
  matterbridgeConnected: false,
85
86
  bridgeMode: '',
86
87
  restartMode: '',
87
88
  debugEnabled: false,
89
+ matterLoggerLevel: Level.INFO,
88
90
  };
89
91
  homeDirectory = '';
90
92
  rootDirectory = '';
@@ -93,9 +95,10 @@ export class Matterbridge extends EventEmitter {
93
95
  globalModulesDirectory = '';
94
96
  matterbridgeVersion = '';
95
97
  matterbridgeLatestVersion = '';
96
- matterbridgeFabricInfo = [];
98
+ matterbridgeFabricInformations = [];
97
99
  matterbridgePaired = false;
98
100
  matterbridgeConnected = false;
101
+ matterbridgeSessionInformations = [];
99
102
  checkUpdateInterval; // = 24 * 60 * 60 * 1000; // 24 hours
100
103
  bridgeMode = '';
101
104
  restartMode = '';
@@ -113,7 +116,7 @@ export class Matterbridge extends EventEmitter {
113
116
  nodeStorage;
114
117
  nodeContext;
115
118
  expressApp;
116
- expressServer;
119
+ // private expressServer: Server | undefined;
117
120
  httpServer;
118
121
  httpsServer;
119
122
  webSocketServer;
@@ -147,6 +150,14 @@ export class Matterbridge extends EventEmitter {
147
150
  }
148
151
  return Matterbridge.instance;
149
152
  }
153
+ /**
154
+ * Call shutdownProcess.
155
+ * @deprecated This method is deprecated and is only used for jest.
156
+ *
157
+ */
158
+ async destroyInstance() {
159
+ await this.shutdownProcess();
160
+ }
150
161
  /**
151
162
  * Initializes the Matterbridge instance as extension for zigbee2mqtt.
152
163
  * @deprecated This method is deprecated and will be removed in a future version.
@@ -273,7 +284,7 @@ export class Matterbridge extends EventEmitter {
273
284
  - reset: remove the commissioning for Matterbridge (bridge mode). Shutdown Matterbridge before using it!
274
285
  - factoryreset: remove all commissioning information and reset all internal storages. Shutdown Matterbridge before using it!
275
286
  - list: list the registered plugins
276
- - loginterfaces: log the network interfaces
287
+ - loginterfaces: log the network interfaces (usefull for finding the name of the interface to use with -mdnsinterface option)
277
288
  - logstorage: log the node storage
278
289
  - ssl: enable SSL for the frontend and WebSockerServer (certificates in .matterbridge/certs directory cert.pem, key.pem and ca.pem (optional))
279
290
  - add [plugin path]: register the plugin from the given absolute or relative path
@@ -290,11 +301,11 @@ export class Matterbridge extends EventEmitter {
290
301
  }
291
302
  // Set the interface to use for the matter server mdnsInterface
292
303
  this.mdnsInterface = getParameter('mdnsinterface');
293
- // Set the first port to use for the commissioning server
304
+ // Set the first port to use for the commissioning server (will be incremented in childbridge mode)
294
305
  this.port = getIntParameter('port') ?? 5540;
295
- // Set the first passcode to use for the commissioning server
306
+ // Set the first passcode to use for the commissioning server (will be incremented in childbridge mode)
296
307
  this.passcode = getIntParameter('passcode');
297
- // Set the first discriminator to use for the commissioning server
308
+ // Set the first discriminator to use for the commissioning server (will be incremented in childbridge mode)
298
309
  this.discriminator = getIntParameter('discriminator');
299
310
  // Set the restart mode
300
311
  if (hasParameter('service'))
@@ -316,6 +327,27 @@ export class Matterbridge extends EventEmitter {
316
327
  // Get the plugins from node storage and create the plugin node storage contexts
317
328
  this.registeredPlugins = await this.nodeContext.get('plugins', []);
318
329
  for (const plugin of this.registeredPlugins) {
330
+ const packageJson = await this.parsePlugin(plugin);
331
+ if (packageJson) {
332
+ // Update the plugin information
333
+ plugin.name = packageJson.name;
334
+ plugin.version = packageJson.version;
335
+ plugin.description = packageJson.description;
336
+ plugin.author = packageJson.author;
337
+ }
338
+ else {
339
+ this.log.info(`Error parsing plugin ${plg}${plugin.name}${nf}. Trying to reinstall it from npm.`);
340
+ try {
341
+ await this.spawnCommand('npm', ['install', '-g', plugin.name]);
342
+ this.log.info(`Plugin ${plg}${plugin.name}${nf} reinstalled.`);
343
+ plugin.error = false;
344
+ }
345
+ catch (error) {
346
+ plugin.error = true;
347
+ plugin.enabled = false;
348
+ this.log.error(`Error installing plugin ${plg}${plugin.name}${er}. The plugin is disabled.`);
349
+ }
350
+ }
319
351
  this.log.debug(`Creating node storage context for plugin ${plugin.name}`);
320
352
  plugin.nodeContext = await this.nodeStorage.createStorage(plugin.name);
321
353
  await plugin.nodeContext.set('name', plugin.name);
@@ -328,7 +360,7 @@ export class Matterbridge extends EventEmitter {
328
360
  // Log system info and create .matterbridge directory
329
361
  await this.logNodeAndSystemInfo();
330
362
  this.log.info(`Matterbridge version ${this.matterbridgeVersion} mode ${hasParameter('bridge') ? 'bridge' : ''}${hasParameter('childbridge') ? 'childbridge' : ''}${hasParameter('controller') ? 'controller' : ''} ` +
331
- `${this.restartMode !== '' ? 'restart mode ' + this.restartMode + ' ' : ''}running on ${this.systemInformation.osType} ${this.systemInformation.osRelease} ${this.systemInformation.osPlatform} ${this.systemInformation.osArch}`);
363
+ `${this.restartMode !== '' ? 'restart mode ' + this.restartMode + ' ' : ''}running on ${this.systemInformation.osType} ${this.systemInformation.osRelease} ${this.systemInformation.osPlatform} ${this.systemInformation.osArch} `);
332
364
  // Check node version and throw error
333
365
  requireMinNodeVersion(18);
334
366
  // Register SIGINT SIGTERM signal handlers
@@ -364,12 +396,12 @@ export class Matterbridge extends EventEmitter {
364
396
  }
365
397
  Logger.format = Format.ANSI;
366
398
  // Parse command line
367
- this.parseCommandLine();
399
+ await this.parseCommandLine();
368
400
  }
369
401
  /**
370
402
  * Parses the command line arguments and performs the corresponding actions.
371
403
  * @private
372
- * @returns {Promise<void>} A promise that resolves when the command line arguments have been processed.
404
+ * @returns {Promise<void>} A promise that resolves when the command line arguments have been processed, or the process exits.
373
405
  */
374
406
  async parseCommandLine() {
375
407
  if (hasParameter('list')) {
@@ -477,7 +509,8 @@ export class Matterbridge extends EventEmitter {
477
509
  process.exit(0);
478
510
  }
479
511
  // Initialize frontend
480
- await this.initializeFrontend(getIntParameter('frontend'));
512
+ if (getIntParameter('frontend') !== 0 || getIntParameter('frontend') === undefined)
513
+ await this.initializeFrontend(getIntParameter('frontend'));
481
514
  // Check each 60 minutes the latest versions
482
515
  this.checkUpdateInterval = setInterval(() => {
483
516
  this.getMatterbridgeLatestVersion();
@@ -488,7 +521,7 @@ export class Matterbridge extends EventEmitter {
488
521
  if (hasParameter('test')) {
489
522
  this.bridgeMode = 'childbridge';
490
523
  MatterbridgeDevice.bridgeMode = 'childbridge';
491
- await this.testStartMatterBridge(); // No await do it asyncronously
524
+ await this.testStartMatterBridge();
492
525
  return;
493
526
  }
494
527
  if (hasParameter('controller')) {
@@ -527,6 +560,14 @@ export class Matterbridge extends EventEmitter {
527
560
  for (const plugin of this.registeredPlugins) {
528
561
  plugin.configJson = await this.loadPluginConfig(plugin);
529
562
  plugin.schemaJson = await this.loadPluginSchema(plugin);
563
+ // Check if the plugin is available
564
+ if (!(await this.resolvePluginName(plugin.path))) {
565
+ this.log.error(`Plugin ${plg}${plugin.name}${er} not found. Disabling it.`);
566
+ plugin.enabled = false;
567
+ plugin.error = true;
568
+ continue;
569
+ }
570
+ // Check if the plugin has a new version
530
571
  this.getPluginLatestVersion(plugin);
531
572
  if (!plugin.enabled) {
532
573
  this.log.info(`Plugin ${plg}${plugin.name}${nf} not enabled`);
@@ -560,6 +601,14 @@ export class Matterbridge extends EventEmitter {
560
601
  for (const plugin of this.registeredPlugins) {
561
602
  plugin.configJson = await this.loadPluginConfig(plugin);
562
603
  plugin.schemaJson = await this.loadPluginSchema(plugin);
604
+ // Check if the plugin is available
605
+ if (!(await this.resolvePluginName(plugin.path))) {
606
+ this.log.error(`Plugin ${plg}${plugin.name}${er} not found. Disabling it.`);
607
+ plugin.enabled = false;
608
+ plugin.error = true;
609
+ continue;
610
+ }
611
+ // Check if the plugin has a new version
563
612
  this.getPluginLatestVersion(plugin);
564
613
  if (!plugin.enabled) {
565
614
  this.log.info(`Plugin ${plg}${plugin.name}${nf} not enabled`);
@@ -743,6 +792,7 @@ export class Matterbridge extends EventEmitter {
743
792
  * When either of these signals are received, the cleanup method is called with an appropriate message.
744
793
  */
745
794
  async registerSignalHandlers() {
795
+ this.log.debug(`Registering SIGINT and SIGTERM signal handlers...`);
746
796
  process.once('SIGINT', async () => {
747
797
  await this.cleanup('SIGINT received, cleaning up...');
748
798
  });
@@ -806,11 +856,14 @@ export class Matterbridge extends EventEmitter {
806
856
  if (!this.hasCleanupStarted) {
807
857
  this.hasCleanupStarted = true;
808
858
  this.log.info(message);
809
- process.removeAllListeners('SIGINT');
810
- process.removeAllListeners('SIGTERM');
859
+ // Remove all listeners from the process
860
+ process.removeAllListeners();
811
861
  this.log.debug('All listeners removed');
812
- this.checkUpdateInterval && clearInterval(this.checkUpdateInterval);
862
+ // Clear the update interval
863
+ if (this.checkUpdateInterval)
864
+ clearInterval(this.checkUpdateInterval);
813
865
  this.checkUpdateInterval = undefined;
866
+ this.log.debug('Update interval cleared');
814
867
  // Calling the shutdown method of each plugin
815
868
  for (const plugin of this.registeredPlugins) {
816
869
  if (!plugin.enabled || plugin.error)
@@ -868,12 +921,14 @@ export class Matterbridge extends EventEmitter {
868
921
  }
869
922
  */
870
923
  // Close the express server
924
+ /*
871
925
  if (this.expressServer) {
872
- this.expressServer.close();
873
- this.expressServer.removeAllListeners();
874
- this.expressServer = undefined;
875
- this.log.debug('Express server closed successfully');
926
+ this.expressServer.close();
927
+ this.expressServer.removeAllListeners();
928
+ this.expressServer = undefined;
929
+ this.log.debug('Express server closed successfully');
876
930
  }
931
+ */
877
932
  // Close the http server
878
933
  if (this.httpServer) {
879
934
  this.httpServer.close();
@@ -912,7 +967,7 @@ export class Matterbridge extends EventEmitter {
912
967
  });
913
968
  this.webSocketServer = undefined;
914
969
  }
915
- setTimeout(async () => {
970
+ const cleanupTimeout1 = setTimeout(async () => {
916
971
  // Closing matter
917
972
  await this.stopMatter();
918
973
  // Closing storage
@@ -943,7 +998,7 @@ export class Matterbridge extends EventEmitter {
943
998
  this.registeredPlugins = [];
944
999
  this.registeredDevices = [];
945
1000
  this.log.info('Waiting for matter to deliver last messages...');
946
- setTimeout(async () => {
1001
+ const cleanupTimeout2 = setTimeout(async () => {
947
1002
  if (restart) {
948
1003
  if (message === 'updating...') {
949
1004
  this.log.info('Cleanup completed. Updating...');
@@ -977,7 +1032,9 @@ export class Matterbridge extends EventEmitter {
977
1032
  this.emit('shutdown');
978
1033
  }
979
1034
  }, 2 * 1000);
1035
+ cleanupTimeout2.unref();
980
1036
  }, 3 * 1000);
1037
+ cleanupTimeout1.unref();
981
1038
  }
982
1039
  }
983
1040
  /**
@@ -1460,6 +1517,23 @@ export class Matterbridge extends EventEmitter {
1460
1517
  return Promise.resolve();
1461
1518
  }
1462
1519
  }
1520
+ /**
1521
+ * Loads and parse the plugin package.json and returns it.
1522
+ * @param plugin - The plugin to load the package from.
1523
+ * @returns A Promise that resolves to the package.json object or undefined if the package.json could not be loaded.
1524
+ */
1525
+ async parsePlugin(plugin) {
1526
+ this.log.debug(`Parsing package.json of plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
1527
+ try {
1528
+ const packageJson = JSON.parse(await fs.readFile(plugin.path, 'utf8'));
1529
+ return packageJson;
1530
+ }
1531
+ catch (err) {
1532
+ this.log.error(`Failed to parse plugin ${plg}${plugin.name}${er} package.json: ${err}`);
1533
+ plugin.error = true;
1534
+ return undefined;
1535
+ }
1536
+ }
1463
1537
  /**
1464
1538
  * Loads a plugin and returns the corresponding MatterbridgePlatform instance.
1465
1539
  * @param plugin - The plugin to load.
@@ -1944,12 +2018,21 @@ export class Matterbridge extends EventEmitter {
1944
2018
  const QrCode = new QrCodeSchema();
1945
2019
  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` +
1946
2020
  `${QrCode.encode(qrPairingCode)}\n${plg}${pluginName}${nf}\n\nqrPairingCode: ${qrPairingCode}\n\nManual pairing code: ${manualPairingCode}\n`);
2021
+ if (pluginName === 'Matterbridge') {
2022
+ this.matterbridgeFabricInformations = [];
2023
+ this.matterbridgeSessionInformations = [];
2024
+ this.matterbridgePaired = false;
2025
+ this.matterbridgeConnected = false;
2026
+ }
1947
2027
  if (pluginName !== 'Matterbridge') {
1948
2028
  const plugin = this.findPlugin(pluginName);
1949
2029
  if (plugin) {
1950
2030
  plugin.qrPairingCode = qrPairingCode;
1951
2031
  plugin.manualPairingCode = manualPairingCode;
2032
+ plugin.fabricInformations = [];
2033
+ plugin.sessionInformations = [];
1952
2034
  plugin.paired = false;
2035
+ plugin.connected = false;
1953
2036
  }
1954
2037
  }
1955
2038
  await this.nodeContext?.set('plugins', await this.getBaseRegisteredPlugins());
@@ -1963,19 +2046,71 @@ export class Matterbridge extends EventEmitter {
1963
2046
  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}`);
1964
2047
  });
1965
2048
  if (pluginName === 'Matterbridge') {
1966
- this.matterbridgeFabricInfo = fabricInfo;
2049
+ this.matterbridgeFabricInformations = this.sanitizeFabricInformations(fabricInfo);
2050
+ this.matterbridgeSessionInformations = [];
1967
2051
  this.matterbridgePaired = true;
1968
2052
  }
1969
2053
  if (pluginName !== 'Matterbridge') {
1970
2054
  const plugin = this.findPlugin(pluginName);
1971
2055
  if (plugin) {
1972
- plugin.fabricInfo = fabricInfo;
2056
+ plugin.fabricInformations = this.sanitizeFabricInformations(fabricInfo);
2057
+ plugin.sessionInformations = [];
1973
2058
  plugin.paired = true;
1974
2059
  }
1975
2060
  }
1976
2061
  await this.nodeContext?.set('plugins', await this.getBaseRegisteredPlugins());
1977
2062
  }
1978
2063
  }
2064
+ /**
2065
+ * Sanitizes the fabric information by converting bigint properties to string cause res..
2066
+ *
2067
+ * @param fabricInfo - The array of exposed fabric information objects.
2068
+ * @returns An array of sanitized exposed fabric information objects.
2069
+ */
2070
+ sanitizeFabricInformations(fabricInfo) {
2071
+ return fabricInfo.map((info) => {
2072
+ return {
2073
+ fabricIndex: info.fabricIndex,
2074
+ fabricId: info.fabricId.toString(),
2075
+ nodeId: info.nodeId.toString(),
2076
+ rootNodeId: info.rootNodeId.toString(),
2077
+ rootVendorId: info.rootVendorId,
2078
+ rootVendorName: this.getVendorIdName(info.rootVendorId),
2079
+ label: info.label,
2080
+ };
2081
+ });
2082
+ }
2083
+ /**
2084
+ * Sanitizes the session information by converting bigint properties to string.
2085
+ *
2086
+ * @param sessionInfo - The array of session information objects.
2087
+ * @returns An array of sanitized session information objects.
2088
+ */
2089
+ sanitizeSessionInformation(sessionInfo) {
2090
+ return sessionInfo.map((info) => {
2091
+ return {
2092
+ name: info.name,
2093
+ nodeId: info.nodeId.toString(),
2094
+ peerNodeId: info.peerNodeId.toString(),
2095
+ fabric: info.fabric
2096
+ ? {
2097
+ fabricIndex: info.fabric.fabricIndex,
2098
+ fabricId: info.fabric.fabricId.toString(),
2099
+ nodeId: info.fabric.nodeId.toString(),
2100
+ rootNodeId: info.fabric.rootNodeId.toString(),
2101
+ rootVendorId: info.fabric.rootVendorId,
2102
+ rootVendorName: this.getVendorIdName(info.fabric.rootVendorId),
2103
+ label: info.fabric.label,
2104
+ }
2105
+ : undefined,
2106
+ isPeerActive: info.isPeerActive,
2107
+ secure: info.secure,
2108
+ lastInteractionTimestamp: info.lastInteractionTimestamp,
2109
+ lastActiveTimestamp: info.lastActiveTimestamp,
2110
+ numberOfActiveSubscriptions: info.numberOfActiveSubscriptions,
2111
+ };
2112
+ });
2113
+ }
1979
2114
  /**
1980
2115
  * Finds a plugin by its name.
1981
2116
  *
@@ -2062,6 +2197,9 @@ export class Matterbridge extends EventEmitter {
2062
2197
  case 4742:
2063
2198
  vendorName = '(eWeLink)';
2064
2199
  break;
2200
+ case 65521:
2201
+ vendorName = '(PythonMatterServer)';
2202
+ break;
2065
2203
  default:
2066
2204
  vendorName = '(unknown)';
2067
2205
  break;
@@ -2118,9 +2256,9 @@ export class Matterbridge extends EventEmitter {
2118
2256
  reachable: true,
2119
2257
  },
2120
2258
  activeSessionsChangedCallback: (fabricIndex) => {
2121
- const info = commissioningServer.getActiveSessionInformation(fabricIndex);
2259
+ const sessionInformations = commissioningServer.getActiveSessionInformation(fabricIndex);
2122
2260
  let connected = false;
2123
- info.forEach((session) => {
2261
+ sessionInformations.forEach((session) => {
2124
2262
  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));
2125
2263
  if (session.isPeerActive === true && session.secure === true && session.numberOfActiveSubscriptions >= 1) {
2126
2264
  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}`);
@@ -2131,12 +2269,14 @@ export class Matterbridge extends EventEmitter {
2131
2269
  if (this.bridgeMode === 'bridge') {
2132
2270
  this.matterbridgePaired = true;
2133
2271
  this.matterbridgeConnected = true;
2272
+ this.matterbridgeSessionInformations = this.sanitizeSessionInformation(sessionInformations);
2134
2273
  }
2135
2274
  if (this.bridgeMode === 'childbridge') {
2136
2275
  const plugin = this.findPlugin(pluginName);
2137
2276
  if (plugin) {
2138
2277
  plugin.paired = true;
2139
2278
  plugin.connected = true;
2279
+ plugin.sessionInformations = this.sanitizeSessionInformation(sessionInformations);
2140
2280
  }
2141
2281
  }
2142
2282
  setTimeout(() => {
@@ -2179,7 +2319,8 @@ export class Matterbridge extends EventEmitter {
2179
2319
  await commissioningServer.factoryReset();
2180
2320
  if (pluginName === 'Matterbridge') {
2181
2321
  await this.matterbridgeContext?.clearAll();
2182
- this.matterbridgeFabricInfo = [];
2322
+ this.matterbridgeFabricInformations = [];
2323
+ this.matterbridgeSessionInformations = [];
2183
2324
  this.matterbridgePaired = false;
2184
2325
  this.matterbridgeConnected = false;
2185
2326
  }
@@ -2187,14 +2328,29 @@ export class Matterbridge extends EventEmitter {
2187
2328
  for (const plugin of this.registeredPlugins) {
2188
2329
  if (plugin.name === pluginName) {
2189
2330
  await plugin.platform?.onShutdown('Commissioning removed by the controller');
2190
- plugin.fabricInfo = [];
2331
+ plugin.fabricInformations = [];
2332
+ plugin.sessionInformations = [];
2191
2333
  plugin.paired = false;
2192
2334
  plugin.connected = false;
2193
2335
  await plugin.storageContext?.clearAll();
2194
2336
  }
2195
2337
  }
2196
2338
  }
2197
- this.log.warn(`*Restart to activate the pairing for ${plg}${pluginName}${wr}`);
2339
+ this.log.warn(`*Restart to activate the pairing for ${plg}${pluginName}${wr}.`);
2340
+ }
2341
+ else {
2342
+ const fabricInfo = commissioningServer.getCommissionedFabricInformation();
2343
+ if (pluginName === 'Matterbridge') {
2344
+ this.matterbridgeFabricInformations = this.sanitizeFabricInformations(fabricInfo);
2345
+ this.matterbridgePaired = true;
2346
+ }
2347
+ else {
2348
+ const plugin = this.findPlugin(pluginName);
2349
+ if (plugin) {
2350
+ plugin.fabricInformations = this.sanitizeFabricInformations(fabricInfo);
2351
+ plugin.paired = true;
2352
+ }
2353
+ }
2198
2354
  }
2199
2355
  },
2200
2356
  });
@@ -2549,7 +2705,8 @@ export class Matterbridge extends EventEmitter {
2549
2705
  configured: plugin.configured,
2550
2706
  paired: plugin.paired,
2551
2707
  connected: plugin.connected,
2552
- // fabricInfo: plugin.fabricInfo,
2708
+ fabricInformations: plugin.fabricInformations,
2709
+ sessionInformations: plugin.sessionInformations,
2553
2710
  registeredDevices: plugin.registeredDevices,
2554
2711
  addedDevices: plugin.addedDevices,
2555
2712
  qrPairingCode: plugin.qrPairingCode,
@@ -2773,43 +2930,6 @@ export class Matterbridge extends EventEmitter {
2773
2930
  this.webSocketServer.on('error', (ws, error) => {
2774
2931
  this.log.error(`WebSocketServer error: ${error}`);
2775
2932
  });
2776
- /*
2777
- // Create a WebSocket server
2778
- const wssPort = 8284;
2779
- const wssHost = `ws://${this.systemInformation.ipv4Address}:${wssPort}`;
2780
- this.webSocketServer = new WebSocketServer({ port: wssPort, host: this.systemInformation.ipv4Address });
2781
- this.log.debug(`WebSocket server created on ${UNDERLINE}${wssHost}${UNDERLINEOFF}${rs}`);
2782
-
2783
- this.webSocketServer.on('listening', () => {
2784
- this.log.info(`WebSocketServer is listening on ${UNDERLINE}${wssHost}${UNDERLINEOFF}${rs}`);
2785
- return;
2786
- });
2787
- */
2788
- /*
2789
- // Serve React build directory
2790
- this.expressApp = express();
2791
- this.expressApp.use(express.static(path.join(this.rootDirectory, 'frontend/build')));
2792
-
2793
- // Listen on HTTP
2794
- this.expressServer = this.expressApp.listen(port, () => {
2795
- this.log.info(`The frontend is listening on ${UNDERLINE}http://${this.systemInformation.ipv4Address}:${port}${UNDERLINEOFF}${rs}`);
2796
- this.log.debug(`The frontend is listening on ${UNDERLINE}http://[${this.systemInformation.ipv6Address}]:${port}${UNDERLINEOFF}${rs}`);
2797
- });
2798
-
2799
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2800
- this.expressServer.on('error', (error: any) => {
2801
- this.log.error(`Frontend error listening on ${UNDERLINE}http://${this.systemInformation.ipv4Address}:${port}${UNDERLINEOFF}${rs}`);
2802
- switch (error.code) {
2803
- case 'EACCES':
2804
- this.log.error(`Port ${port} requires elevated privileges`);
2805
- break;
2806
- case 'EADDRINUSE':
2807
- this.log.error(`Port ${port} is already in use`);
2808
- break;
2809
- }
2810
- process.exit(1);
2811
- });
2812
- */
2813
2933
  // Endpoint to validate login code
2814
2934
  this.expressApp.post('/api/login', express.json(), async (req, res) => {
2815
2935
  const { password } = req.body;
@@ -2856,9 +2976,11 @@ export class Matterbridge extends EventEmitter {
2856
2976
  this.matterbridgeInformation.bridgeMode = this.bridgeMode;
2857
2977
  this.matterbridgeInformation.restartMode = this.restartMode;
2858
2978
  this.matterbridgeInformation.debugEnabled = this.debugEnabled;
2979
+ this.matterbridgeInformation.matterLoggerLevel = Logger.defaultLogLevel;
2859
2980
  this.matterbridgeInformation.matterbridgePaired = this.matterbridgePaired;
2860
2981
  this.matterbridgeInformation.matterbridgeConnected = this.matterbridgeConnected;
2861
- // this.matterbridgeInformation.matterbridgeFabricInfo = this.matterbridgeFabricInfo;
2982
+ this.matterbridgeInformation.matterbridgeFabricInformations = this.matterbridgeFabricInformations;
2983
+ this.matterbridgeInformation.matterbridgeSessionInformations = this.matterbridgeSessionInformations;
2862
2984
  const response = { wssHost, qrPairingCode, manualPairingCode, systemInformation: this.systemInformation, matterbridgeInformation: this.matterbridgeInformation };
2863
2985
  // this.log.debug('Response:', debugStringify(response));
2864
2986
  res.json(response);
@@ -2989,42 +3111,39 @@ export class Matterbridge extends EventEmitter {
2989
3111
  this.log.debug('setpassword', param, password);
2990
3112
  await this.nodeContext?.set('password', password);
2991
3113
  }
2992
- // Handle the command debugLevel from Settings
2993
- if (command === 'setloglevel') {
2994
- this.log.debug('setloglevel:', param);
3114
+ // Handle the command setmbloglevel from Settings
3115
+ if (command === 'setmbloglevel') {
3116
+ this.log.debug('Matterbridge log level:', param);
2995
3117
  if (param === 'Debug') {
2996
3118
  this.log.setLogDebug(true);
2997
3119
  this.debugEnabled = true;
2998
- Logger.defaultLogLevel = Level.DEBUG;
2999
3120
  }
3000
3121
  else if (param === 'Info') {
3001
3122
  this.log.setLogDebug(false);
3002
3123
  this.debugEnabled = false;
3124
+ }
3125
+ }
3126
+ // Handle the command setmbloglevel from Settings
3127
+ if (command === 'setmjloglevel') {
3128
+ this.log.debug('Matter.js log level::', param);
3129
+ if (param === 'Debug') {
3130
+ Logger.defaultLogLevel = Level.DEBUG;
3131
+ }
3132
+ else if (param === 'Info') {
3003
3133
  Logger.defaultLogLevel = Level.INFO;
3004
3134
  }
3005
3135
  else if (param === 'Notice') {
3006
- this.log.setLogDebug(false);
3007
- this.debugEnabled = false;
3008
3136
  Logger.defaultLogLevel = Level.NOTICE;
3009
3137
  }
3010
3138
  else if (param === 'Warn') {
3011
- this.log.setLogDebug(false);
3012
- this.debugEnabled = false;
3013
3139
  Logger.defaultLogLevel = Level.WARN;
3014
3140
  }
3015
3141
  else if (param === 'Error') {
3016
- this.log.setLogDebug(false);
3017
- this.debugEnabled = false;
3018
3142
  Logger.defaultLogLevel = Level.ERROR;
3019
3143
  }
3020
3144
  else if (param === 'Fatal') {
3021
- this.log.setLogDebug(false);
3022
- this.debugEnabled = false;
3023
3145
  Logger.defaultLogLevel = Level.FATAL;
3024
3146
  }
3025
- this.registeredPlugins.forEach((plugin) => {
3026
- plugin.platform?.log.setLogDebug(this.debugEnabled);
3027
- });
3028
3147
  }
3029
3148
  // Handle the command unregister from Settings
3030
3149
  if (command === 'unregister') {