matterbridge 3.0.0-edge.10 → 3.0.0-edge.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.
package/CHANGELOG.md CHANGED
@@ -53,18 +53,25 @@ Modified clusters:
53
53
  - [endpoint]: Added createDefaultActivatedCarbonFilterMonitoringClusterServer().
54
54
  - [deviceTypes]: Added Robotic device type.
55
55
  - [deviceTypes]: Added Appliances device types.
56
+ - [frontend]: Added the matterbridge aggregator serialNumber in the QRDiv.
56
57
 
57
58
  ### Changed
58
59
 
59
- - [package]: Update express to 5.1.0.
60
- - [package]: Update dependencies.
61
- - [deviceTypes]: Updated device types to Matter 1.4
60
+ - [package]: Updated package.
61
+ - [package]: Updated express to v5.1.0.
62
+ - [package]: Updated dependencies.
63
+ - [package]: Added tsconfig.jest.json with "isolatedModules": true for ts-jest.
64
+ - [deviceTypes]: Updated device types to Matter 1.4.
65
+ - [clusters]: Updated cluster helpers to Matter 1.4.
62
66
  - [matter.js]: Update to 0.13.0-alpha.0-20250405-7fc7db48.
63
67
  - [matter.js]: Update to 0.13.0-alpha.0-20250408-c916c7e8.
64
68
  - [matter.js]: Update to 0.13.0-alpha.0-20250412-5fad64e7b.
65
69
  - [matter.js]: Update to 0.13.0-alpha.0-20250413-d5a27700d.
66
70
  - [matter.js]: Update to 0.13.0-alpha.0-20250415-475996bb5.
67
71
  - [matter.js]: Update to 0.13.0-alpha.0-20250418-8cfc0b832.
72
+ - [matter.js]: Update to 0.13.0-alpha.0-20250420-9f45e4f77.
73
+ - [help]: Updated cli help screen.
74
+ - [logger]: Improved frontend logger cleaning.
68
75
 
69
76
  ### Fixed
70
77
 
package/README-DEV.md CHANGED
@@ -80,6 +80,10 @@ Matterbridge must be linked to the plugin in development only.
80
80
  "dev:link": "npm link matterbridge",
81
81
  '''
82
82
  }
83
+
84
+ On the machine you use for development you should also have matterbridge installed globally or built locally and linked (npm link from the package root).
85
+
86
+ Dev and edge branches of matterbridge are not suitable for developemnt cause they are published for production without types. If you want to develop a plugin using the dev or edge branch of matterbridge, you have to clone the dev or edge branch, build locally and link (npm run deepCleanBuild).
83
87
  ```
84
88
 
85
89
  # \***\*\*\*\*\***
package/README-DOCKER.md CHANGED
@@ -141,6 +141,15 @@ docker restart matterbridge
141
141
  docker logs matterbridge
142
142
  ```
143
143
 
144
+ ### Shows the logs for a time interval
145
+
146
+ ```
147
+ docker logs \
148
+ --since "2025-04-19T00:00:00" \
149
+ --until "2025-04-19T00:02:00" \
150
+ matterbridge
151
+ ```
152
+
144
153
  ### Shows the logs real time (tail)
145
154
 
146
155
  ```
package/dist/cli.js CHANGED
@@ -189,5 +189,5 @@ process.title = 'matterbridge';
189
189
  main().catch((error) => {
190
190
  const errorMessage = error instanceof Error ? error.message : error;
191
191
  const errorInspect = inspect(error, { depth: 10 });
192
- log.error(`Matterbridge.loadInstance() failed with error: ${errorMessage}\n${errorInspect}`);
192
+ log.error(`Matterbridge.loadInstance() failed with error: ${errorMessage}\nstack: ${errorInspect}`);
193
193
  });
package/dist/frontend.js CHANGED
@@ -1502,6 +1502,7 @@ export class Frontend {
1502
1502
  message = message.replace(/[\t\n]/g, '');
1503
1503
  message = message.replace(/[\x00-\x1F\x7F]/g, '');
1504
1504
  message = message.replace(/\\"/g, '"');
1505
+ message = message.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
1505
1506
  const maxContinuousLength = 100;
1506
1507
  const keepStartLength = 20;
1507
1508
  const keepEndLength = 20;
@@ -51,6 +51,7 @@ export class Matterbridge extends EventEmitter {
51
51
  globalModulesDirectory: '',
52
52
  matterbridgeVersion: '',
53
53
  matterbridgeLatestVersion: '',
54
+ matterbridgeSerialNumber: '',
54
55
  matterbridgeQrPairingCode: undefined,
55
56
  matterbridgeManualPairingCode: undefined,
56
57
  matterbridgeFabricInformations: [],
@@ -491,6 +492,13 @@ export class Matterbridge extends EventEmitter {
491
492
  - nosudo: force not to use sudo to install or update packages if the internal logic fails
492
493
  - norestore: force not to automatically restore the matterbridge node storage and the matter storage from backup if it is corrupted
493
494
  - ssl: enable SSL for the frontend and WebSockerServer (certificates in .matterbridge/certs directory cert.pem, key.pem and ca.pem (optional))
495
+ - vendorId: override the default vendorId 0xfff1
496
+ - vendorName: override the default vendorName "Matterbridge"
497
+ - productId: override the default productId 0x8000
498
+ - productName: override the default productName "Matterbridge aggregator"
499
+ - service: enable the service mode (used in the systemctl configuration file)
500
+ - docker: enable the docker mode (used in the Dockerfile to build the docker image)
501
+ - homedir: override the home directory (default: os.homedir())
494
502
  - add [plugin path]: register the plugin from the given absolute or relative path
495
503
  - add [plugin name]: register the globally installed plugin with the given name
496
504
  - remove [plugin path]: remove the plugin from the given absolute or relative path
@@ -687,11 +695,15 @@ export class Matterbridge extends EventEmitter {
687
695
  process.removeAllListeners('uncaughtException');
688
696
  process.removeAllListeners('unhandledRejection');
689
697
  this.exceptionHandler = async (error) => {
690
- this.log.error('Unhandled Exception detected at:', error.stack || error, rs);
698
+ const errorMessage = error instanceof Error ? error.message : error;
699
+ const errorInspect = inspect(error, { depth: 10 });
700
+ this.log.error(`Unhandled Exception detected: ${errorMessage}\nstack: ${errorInspect}}`);
691
701
  };
692
702
  process.on('uncaughtException', this.exceptionHandler);
693
703
  this.rejectionHandler = async (reason, promise) => {
694
- this.log.error('Unhandled Rejection detected at:', promise, 'reason:', reason instanceof Error ? reason.stack : reason, rs);
704
+ const errorMessage = reason instanceof Error ? reason.message : reason;
705
+ const errorInspect = inspect(reason, { depth: 10 });
706
+ this.log.error(`Unhandled Rejection detected: ${promise}\nreason: ${errorMessage}\nstack: ${errorInspect}`);
695
707
  };
696
708
  process.on('unhandledRejection', this.rejectionHandler);
697
709
  this.log.debug(`Registering SIGINT and SIGTERM signal handlers...`);
@@ -1165,6 +1177,7 @@ export class Matterbridge extends EventEmitter {
1165
1177
  plugin.device = device;
1166
1178
  plugin.storageContext = await this.createServerNodeContext(plugin.name, device.deviceName, DeviceTypeId(device.deviceType), device.vendorId, device.vendorName, device.productId, device.productName);
1167
1179
  plugin.serverNode = await this.createServerNode(plugin.storageContext, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
1180
+ plugin.serialNumber = await plugin.storageContext.get('serialNumber', '');
1168
1181
  this.log.debug(`Adding ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} to ${plg}${plugin.name}${db} server node`);
1169
1182
  await plugin.serverNode.add(device);
1170
1183
  if (start)
@@ -1177,6 +1190,7 @@ export class Matterbridge extends EventEmitter {
1177
1190
  plugin.storageContext = await this.createServerNodeContext(plugin.name, 'Matterbridge', bridge.code, this.aggregatorVendorId, 'Matterbridge', this.aggregatorProductId, plugin.description);
1178
1191
  plugin.serverNode = await this.createServerNode(plugin.storageContext, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
1179
1192
  plugin.aggregatorNode = await this.createAggregatorNode(plugin.storageContext);
1193
+ plugin.serialNumber = await plugin.storageContext.get('serialNumber', '');
1180
1194
  await plugin.serverNode.add(plugin.aggregatorNode);
1181
1195
  if (start)
1182
1196
  await this.startServerNode(plugin.serverNode);
@@ -1358,6 +1372,7 @@ export class Matterbridge extends EventEmitter {
1358
1372
  this.matterStorageManager = await this.matterStorageService.open('Matterbridge');
1359
1373
  this.log.info('Matter node storage manager "Matterbridge" created');
1360
1374
  this.matterbridgeContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', bridge.code, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName);
1375
+ this.matterbridgeInformation.matterbridgeSerialNumber = await this.matterbridgeContext.get('serialNumber', '');
1361
1376
  this.log.info('Matter node storage started');
1362
1377
  await this.backupMatterStorage(path.join(this.matterbridgeDirectory, this.matterStorageName), path.join(this.matterbridgeDirectory, this.matterStorageName + '.backup'));
1363
1378
  }
@@ -1368,7 +1383,7 @@ export class Matterbridge extends EventEmitter {
1368
1383
  }
1369
1384
  async stopMatterStorage() {
1370
1385
  this.log.info('Closing matter node storage...');
1371
- this.matterStorageManager?.close();
1386
+ await this.matterStorageManager?.close();
1372
1387
  this.matterStorageService = undefined;
1373
1388
  this.matterStorageManager = undefined;
1374
1389
  this.matterbridgeContext = undefined;
@@ -1661,10 +1676,9 @@ export class Matterbridge extends EventEmitter {
1661
1676
  await this.aggregatorNode?.add(device);
1662
1677
  }
1663
1678
  catch (error) {
1664
- const errorMessage = error instanceof Error ? error.message : '';
1665
- const errorStack = error instanceof Error ? error.stack : '';
1666
- const errorDebug = inspect(error, { depth: 10 });
1667
- this.log.error(`Error adding bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) for plugin ${plg}${pluginName}${er}: ${error} ${errorMessage} ${errorStack} ${errorDebug}`);
1679
+ const errorMessage = error instanceof Error ? error.message : error;
1680
+ const errorInspect = inspect(error, { depth: 10 });
1681
+ this.log.error(`Error adding bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) for plugin ${plg}${pluginName}${er}: ${errorMessage}\nstack: ${errorInspect}`);
1668
1682
  return;
1669
1683
  }
1670
1684
  }
@@ -1675,10 +1689,9 @@ export class Matterbridge extends EventEmitter {
1675
1689
  await this.createAccessoryPlugin(plugin, device);
1676
1690
  }
1677
1691
  catch (error) {
1678
- const errorMessage = error instanceof Error ? error.message : '';
1679
- const errorStack = error instanceof Error ? error.stack : '';
1680
- const errorDebug = inspect(error, { depth: 10 });
1681
- this.log.error(`Error creating endpoint ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) for AccessoryPlatform plugin ${plg}${pluginName}${er} server node: ${error} ${errorMessage} ${errorStack} ${errorDebug}`);
1692
+ const errorMessage = error instanceof Error ? error.message : error;
1693
+ const errorInspect = inspect(error, { depth: 10 });
1694
+ this.log.error(`Error creating endpoint ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) for AccessoryPlatform plugin ${plg}${pluginName}${er} server node: ${errorMessage}\nstack: ${errorInspect}`);
1682
1695
  return;
1683
1696
  }
1684
1697
  }
@@ -1691,10 +1704,9 @@ export class Matterbridge extends EventEmitter {
1691
1704
  await plugin.aggregatorNode?.add(device);
1692
1705
  }
1693
1706
  catch (error) {
1694
- const errorMessage = error instanceof Error ? error.message : '';
1695
- const errorStack = error instanceof Error ? error.stack : '';
1696
- const errorDebug = inspect(error, { depth: 10 });
1697
- this.log.error(`Error adding bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) for DynamicPlatform plugin ${plg}${pluginName}${er} aggregator node: ${error} ${errorMessage} ${errorStack} ${errorDebug}`);
1707
+ const errorMessage = error instanceof Error ? error.message : error;
1708
+ const errorInspect = inspect(error, { depth: 10 });
1709
+ this.log.error(`Error adding bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) for DynamicPlatform plugin ${plg}${pluginName}${er} aggregator node: ${errorMessage}\nstack: ${errorInspect}`);
1698
1710
  return;
1699
1711
  }
1700
1712
  }
@@ -782,18 +782,24 @@ export class MatterbridgeEndpoint extends Endpoint {
782
782
  return this;
783
783
  }
784
784
  createDefaultHepaFilterMonitoringClusterServer(changeIndication = ResourceMonitoring.ChangeIndication.Ok, inPlaceIndicator = undefined, lastChangedTime = undefined) {
785
- this.behaviors.require(HepaFilterMonitoringServer, {
785
+ this.behaviors.require(HepaFilterMonitoringServer.with(ResourceMonitoring.Feature.Condition, ResourceMonitoring.Feature.ReplacementProductList), {
786
+ condition: 100,
787
+ degradationDirection: ResourceMonitoring.DegradationDirection.Down,
786
788
  changeIndication,
787
789
  inPlaceIndicator,
788
790
  lastChangedTime,
791
+ replacementProductList: [],
789
792
  });
790
793
  return this;
791
794
  }
792
795
  createDefaultActivatedCarbonFilterMonitoringClusterServer(changeIndication = ResourceMonitoring.ChangeIndication.Ok, inPlaceIndicator = undefined, lastChangedTime = undefined) {
793
- this.behaviors.require(ActivatedCarbonFilterMonitoringServer, {
796
+ this.behaviors.require(ActivatedCarbonFilterMonitoringServer.with(ResourceMonitoring.Feature.Condition, ResourceMonitoring.Feature.ReplacementProductList), {
797
+ condition: 100,
798
+ degradationDirection: ResourceMonitoring.DegradationDirection.Down,
794
799
  changeIndication,
795
800
  inPlaceIndicator,
796
801
  lastChangedTime,
802
+ replacementProductList: [],
797
803
  });
798
804
  return this;
799
805
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.ea7910e9.css",
4
- "main.js": "./static/js/main.ff47208e.js",
4
+ "main.js": "./static/js/main.eb438c68.js",
5
5
  "static/js/453.d855a71b.chunk.js": "./static/js/453.d855a71b.chunk.js",
6
6
  "static/media/roboto-latin-700-normal.woff2": "./static/media/roboto-latin-700-normal.c4d6cab43bec89049809.woff2",
7
7
  "static/media/roboto-latin-500-normal.woff2": "./static/media/roboto-latin-500-normal.599f66a60bdf974e578e.woff2",
@@ -77,11 +77,11 @@
77
77
  "static/media/roboto-greek-ext-300-normal.woff": "./static/media/roboto-greek-ext-300-normal.60729cafbded24073dfb.woff",
78
78
  "index.html": "./index.html",
79
79
  "main.ea7910e9.css.map": "./static/css/main.ea7910e9.css.map",
80
- "main.ff47208e.js.map": "./static/js/main.ff47208e.js.map",
80
+ "main.eb438c68.js.map": "./static/js/main.eb438c68.js.map",
81
81
  "453.d855a71b.chunk.js.map": "./static/js/453.d855a71b.chunk.js.map"
82
82
  },
83
83
  "entrypoints": [
84
84
  "static/css/main.ea7910e9.css",
85
- "static/js/main.ff47208e.js"
85
+ "static/js/main.eb438c68.js"
86
86
  ]
87
87
  }
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.ff47208e.js"></script><link href="./static/css/main.ea7910e9.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.eb438c68.js"></script><link href="./static/css/main.ea7910e9.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>