matterbridge 3.1.1-dev-20250704-aff5fcb → 3.1.2-dev-20250705-7da1eac

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
@@ -8,7 +8,24 @@ If you like this project and find it useful, please consider giving it a star on
8
8
  <img src="bmc-button.svg" alt="Buy me a coffee" width="120">
9
9
  </a>
10
10
 
11
- ## [3.1.1] - 2025-07-08
11
+ ## [3.1.2] - 2025-07-??
12
+
13
+ ### Development Breaking Changes
14
+
15
+ - [exports]: The single devices (i.e. Rvc, Evse etc...) are only exported from `matterbridge/devices`. Please update your imports to use the new export path. Refer to the [documentation](README-DEV.md) for details on imports.
16
+ - [MatterbridgeEndpoint]: Added the mode property: `server` will make the device indipendent from its plugin. It has its own server node: QRCode, Fabrics and Sessions are visible in the Devices section of the Home page. This is a workaround for the Rvc Apple issue. With mode=server the Rvc (like any other device) can be paired directly to the controller like a native not bridged Matter device.
17
+
18
+ ### Added
19
+
20
+ ### Changed
21
+
22
+ - [package]: Updated dependencies.
23
+
24
+ <a href="https://www.buymeacoffee.com/luligugithub">
25
+ <img src="bmc-button.svg" alt="Buy me a coffee" width="80">
26
+ </a>
27
+
28
+ ## [3.1.1] - 2025-07-04
12
29
 
13
30
  ### Development Breaking Changes
14
31
 
@@ -22,14 +39,15 @@ If you like this project and find it useful, please consider giving it a star on
22
39
  - [SolarPower]: Added SolarPower class and Jest test (working on Home Assistant and SmartThings). Thanks Ludovic BOUÉ.
23
40
  - [BatteryStorage]: Added BatteryStorage class and Jest test (working on Home Assistant and SmartThings). Thanks Ludovic BOUÉ.
24
41
  - [HeatPump]: Added HeatPump class and Jest test (working on Home Assistant and SmartThings).
42
+ - [test]: Improved test units on Frontend class and all Matterbridge classes (coverage 93%).
25
43
 
26
44
  ### Changed
27
45
 
28
46
  - [package]: Updated dependencies.
47
+ - [matter.js]: Bumped `matter.js` to 0.15.1 (https://github.com/project-chip/matter.js/discussions/2220). Great job matter.js!
29
48
  - [frontend]: Added all esa devices.
30
49
  - [frontend]: New default values: devices on the home page and icon view on the devices page.
31
- - [matter.js]: Bumped `matter.js` to 0.15.1 (https://github.com/project-chip/matter.js/discussions/2220). Great job matter.js!
32
- - [imports]: Added more dynamic imports to Matterbridge and Frontend classes.
50
+ - [imports]: Added dynamic imports to Matterbridge and Frontend classes.
33
51
 
34
52
  <a href="https://www.buymeacoffee.com/luligugithub">
35
53
  <img src="bmc-button.svg" alt="Buy me a coffee" width="80">
package/README-DEV.md CHANGED
@@ -272,9 +272,9 @@ You create a Matter device with a new instance of MatterbridgeEndpoint(definitio
272
272
  - @param {boolean} [debug] - Debug flag.
273
273
 
274
274
  ```typescript
275
- const device = new MatterbridgeEndpoint([contactSensor, powerSource], { uniqueStorageKey: 'Eve door', mode: 'matter' }, this.config.debug as boolean)
275
+ const device = new MatterbridgeEndpoint([contactSensor, powerSource], { id: 'EntryDoor', mode: 'server' })
276
276
  .createDefaultIdentifyClusterServer()
277
- .createDefaultBasicInformationClusterServer('My contact sensor', '0123456789')
277
+ .createDefaultBasicInformationClusterServer('My entry door', '0123456789')
278
278
  .createDefaultBooleanStateClusterServer(true)
279
279
  .createDefaultPowerSourceReplaceableBatteryClusterServer(75)
280
280
  .addRequiredClusterServers(); // Always better to call it at the end of the chain to add all the not already created but required clusters.
@@ -282,6 +282,10 @@ You create a Matter device with a new instance of MatterbridgeEndpoint(definitio
282
282
 
283
283
  In the above example we create a contact sensor device type with also a power source device type feature replaceble battery.
284
284
 
285
+ The mode=`server` property of MatterbridgeEndpointOptions, allows to create an independent (not bridged) Matter device with its server node. In this case the bridge mode is not relevant.
286
+
287
+ The mode=`matter` property of MatterbridgeEndpointOptions, allows to create a (not bridged) Matter device that is added to the Matterbridge server node alongside the aggregator.
288
+
285
289
  All device types are defined in src\matterbridgeDeviceTypes.ts and taken from the 'Matter-1.4-Device-Library-Specification.pdf'.
286
290
 
287
291
  All default cluster helpers are available as methods of MatterbridgeEndpoint.
package/README.md CHANGED
@@ -520,27 +520,13 @@ As of version 18.4.x, the Robot is supported by the Home app only as a single, n
520
520
 
521
521
  If a Robot is present alongside other devices in the bridge, the entire bridge becomes unstable in the Home app.
522
522
 
523
- ## Home Assistant
524
-
525
- So far is the only controller supporting some Matter 1.2, 1.3 and 1.4 device type:
526
-
527
- - airQualitySensor code 0x002c (Matter 1.2)
528
- - smokesmokeCoAlarm code 0x0076 (Matter 1.2)
529
- - waterFreezeDetector code 0x0041 (Matter 1.3 with only BooleanState cluster)
530
- - waterLeakDetector code 0x0043 (Matter 1.3 with only BooleanState cluster)
531
- - rainSensor code 0x0044 (Matter 1.3 with only BooleanState cluster)
532
- - deviceEnergyManagement code 0x050d (Matter 1.3 with only DeviceEnergyManagementMode cluster)
533
-
534
- Electrical measurements:
523
+ A workaround has been released in Matterbridge 3.1.1. Ask the plugin authors to update the code.
535
524
 
536
- - electrical measurements from EveHistoryCluster (used in old Matterbridge plugins)
537
- - electricalSensor code 0x0510 with clusters: ElectricalPowerMeasurement and ElectricalEnergyMeasurement
538
-
539
- Other supported cluster:
525
+ ## Home Assistant
540
526
 
541
- - modeSelect code 0x27 with ModeSelect cluster
527
+ So far is the only controller supporting all Matter 1.2, 1.3 and 1.4 device type.
542
528
 
543
- ## Home Assistant issues (Matter Server for HA is still in Beta)
529
+ ## Home Assistant issues
544
530
 
545
531
  - If HA doesn't show all devices, reload the Matter Server Integration or reboot HA
546
532
  - Home Assistant doesn't seem to always react when a device is removed from the bridge: they remain in HA unavailable forever...
@@ -565,8 +551,7 @@ There is no support for these Matter device types:
565
551
  - pressure sensor
566
552
  - flow sensor
567
553
 
568
- In the zigbee2mqtt and shelly plugins select the option to expose
569
- the switch devices like light or outlet cause they don't show up like switch
554
+ In the zigbee2mqtt and shelly plugins select the option to expose the switch devices like light or outlet cause they don't show up like switch
570
555
  (Matterbridge uses a switch device type without client cluster).
571
556
 
572
557
  ## SmartThings
@@ -575,11 +560,6 @@ Tested by Tamer Salah
575
560
 
576
561
  No issues reported so far.
577
562
 
578
- Supports also:
579
-
580
- - air Quality Sensor (Matter 1.2)
581
- - smoke Co Alarm
582
-
583
563
  ## eWeLink
584
564
 
585
565
  Tested by Tamer Salah
package/dist/cli.js CHANGED
@@ -1,16 +1,14 @@
1
1
  import os from 'node:os';
2
- import { EventEmitter } from 'node:events';
3
2
  import { inspect } from 'node:util';
4
3
  import { AnsiLogger, BRIGHT, CYAN, db, YELLOW } from 'node-ansi-logger';
5
4
  import { getIntParameter, hasParameter } from './utils/export.js';
6
5
  import { Matterbridge } from './matterbridge.js';
7
- export const cliEmitter = new EventEmitter();
6
+ import { cliEmitter, lastCpuUsage, setLastCpuUsage } from './cliEmitter.js';
8
7
  export let instance;
9
8
  let session;
10
9
  let snapshotInterval;
11
10
  let memoryCheckInterval;
12
11
  let prevCpus;
13
- export let lastCpuUsage = 0;
14
12
  let peakCpu = 0;
15
13
  let peakRss = 0;
16
14
  const log = new AnsiLogger({ logName: 'Cli', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
@@ -82,7 +80,7 @@ async function startCpuMemoryCheck() {
82
80
  }
83
81
  else {
84
82
  cpuUsageLog = cpuUsage.toFixed(2);
85
- lastCpuUsage = cpuUsage;
83
+ setLastCpuUsage(cpuUsage);
86
84
  if (lastCpuUsage > peakCpu)
87
85
  peakCpu = lastCpuUsage;
88
86
  cliEmitter.emit('cpu', lastCpuUsage);
@@ -0,0 +1,6 @@
1
+ import { EventEmitter } from 'node:events';
2
+ export const cliEmitter = new EventEmitter();
3
+ export let lastCpuUsage = 0;
4
+ export function setLastCpuUsage(val) {
5
+ lastCpuUsage = val;
6
+ }
@@ -11,8 +11,8 @@ import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
11
11
  import { powerSource, roboticVacuumCleaner } from '../matterbridgeDeviceTypes.js';
12
12
  import { MatterbridgeServer, MatterbridgeServiceAreaServer } from '../matterbridgeBehaviors.js';
13
13
  export class RoboticVacuumCleaner extends MatterbridgeEndpoint {
14
- constructor(name, serial, currentRunMode, supportedRunModes, currentCleanMode, supportedCleanModes, currentPhase = null, phaseList = null, operationalState, operationalStateList, supportedAreas, selectedAreas, currentArea) {
15
- super([roboticVacuumCleaner, powerSource], { uniqueStorageKey: `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}` }, true);
14
+ constructor(name, serial, mode = undefined, currentRunMode, supportedRunModes, currentCleanMode, supportedCleanModes, currentPhase = null, phaseList = null, operationalState, operationalStateList, supportedAreas, selectedAreas, currentArea) {
15
+ super([roboticVacuumCleaner, powerSource], { uniqueStorageKey: `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`, mode }, true);
16
16
  this.createDefaultIdentifyClusterServer()
17
17
  .createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Robot Vacuum Cleaner')
18
18
  .createDefaultPowerSourceRechargeableBatteryClusterServer(80, PowerSource.BatChargeLevel.Ok, 5900)
package/dist/frontend.js CHANGED
@@ -13,6 +13,7 @@ import { BridgedDeviceBasicInformation, PowerSource } from '@matter/main/cluster
13
13
  import { createZip, isValidArray, isValidNumber, isValidObject, isValidString, isValidBoolean, withTimeout, hasParameter } from './utils/export.js';
14
14
  import { plg } from './matterbridgeTypes.js';
15
15
  import { capitalizeFirstLetter } from './matterbridgeEndpointHelpers.js';
16
+ import { cliEmitter, lastCpuUsage } from './cliEmitter.js';
16
17
  export const WS_ID_LOG = 0;
17
18
  export const WS_ID_REFRESH_NEEDED = 1;
18
19
  export const WS_ID_RESTART_NEEDED = 2;
@@ -51,7 +52,14 @@ export class Frontend extends EventEmitter {
51
52
  this.expressApp = express();
52
53
  this.expressApp.use(express.static(path.join(this.matterbridge.rootDirectory, 'frontend/build')));
53
54
  if (!hasParameter('ssl')) {
54
- this.httpServer = createServer(this.expressApp);
55
+ try {
56
+ this.httpServer = createServer(this.expressApp);
57
+ }
58
+ catch (error) {
59
+ this.log.error(`Failed to create HTTP server: ${error}`);
60
+ this.emit('server_error', error);
61
+ return;
62
+ }
55
63
  if (hasParameter('ingress')) {
56
64
  this.httpServer.listen(this.port, '0.0.0.0', () => {
57
65
  this.log.info(`The frontend http server is listening on ${UNDERLINE}http://0.0.0.0:${this.port}${UNDERLINEOFF}${rs}`);
@@ -90,6 +98,7 @@ export class Frontend extends EventEmitter {
90
98
  }
91
99
  catch (error) {
92
100
  this.log.error(`Error reading certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pem')}: ${error}`);
101
+ this.emit('server_error', error);
93
102
  return;
94
103
  }
95
104
  let key;
@@ -99,6 +108,7 @@ export class Frontend extends EventEmitter {
99
108
  }
100
109
  catch (error) {
101
110
  this.log.error(`Error reading key file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/key.pem')}: ${error}`);
111
+ this.emit('server_error', error);
102
112
  return;
103
113
  }
104
114
  let ca;
@@ -110,7 +120,14 @@ export class Frontend extends EventEmitter {
110
120
  this.log.info(`CA certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/ca.pem')} not loaded: ${error}`);
111
121
  }
112
122
  const serverOptions = { cert, key, ca };
113
- this.httpsServer = https.createServer(serverOptions, this.expressApp);
123
+ try {
124
+ this.httpsServer = https.createServer(serverOptions, this.expressApp);
125
+ }
126
+ catch (error) {
127
+ this.log.error(`Failed to create HTTPS server: ${error}`);
128
+ this.emit('server_error', error);
129
+ return;
130
+ }
114
131
  if (hasParameter('ingress')) {
115
132
  this.httpsServer.listen(this.port, '0.0.0.0', () => {
116
133
  this.log.info(`The frontend https server is listening on ${UNDERLINE}https://0.0.0.0:${this.port}${UNDERLINEOFF}${rs}`);
@@ -187,7 +204,6 @@ export class Frontend extends EventEmitter {
187
204
  this.webSocketServer.on('error', (ws, error) => {
188
205
  this.log.error(`WebSocketServer error: ${error}`);
189
206
  });
190
- const { cliEmitter } = await import('./cli.js');
191
207
  cliEmitter.removeAllListeners();
192
208
  cliEmitter.on('uptime', (systemUptime, processUptime) => {
193
209
  this.wssSendUptimeUpdate(systemUptime, processUptime);
@@ -463,6 +479,7 @@ export class Frontend extends EventEmitter {
463
479
  this.log.debug('Frontend app closed successfully');
464
480
  }
465
481
  if (this.webSocketServer) {
482
+ this.log.debug('Closing WebSocket server...');
466
483
  this.webSocketServer.clients.forEach((client) => {
467
484
  if (client.readyState === WebSocket.OPEN) {
468
485
  client.close();
@@ -483,6 +500,7 @@ export class Frontend extends EventEmitter {
483
500
  this.webSocketServer = undefined;
484
501
  }
485
502
  if (this.httpServer) {
503
+ this.log.debug('Closing http server...');
486
504
  await withTimeout(new Promise((resolve) => {
487
505
  this.httpServer?.close((error) => {
488
506
  if (error) {
@@ -499,6 +517,7 @@ export class Frontend extends EventEmitter {
499
517
  this.log.debug('Frontend http server closed successfully');
500
518
  }
501
519
  if (this.httpsServer) {
520
+ this.log.debug('Closing https server...');
502
521
  await withTimeout(new Promise((resolve) => {
503
522
  this.httpsServer?.close((error) => {
504
523
  if (error) {
@@ -543,7 +562,6 @@ export class Frontend extends EventEmitter {
543
562
  return `${seconds} second${seconds !== 1 ? 's' : ''}`;
544
563
  };
545
564
  async getApiSettings() {
546
- const { lastCpuUsage } = await import('./cli.js');
547
565
  this.matterbridge.systemInformation.totalMemory = this.formatMemoryUsage(os.totalmem());
548
566
  this.matterbridge.systemInformation.freeMemory = this.formatMemoryUsage(os.freemem());
549
567
  this.matterbridge.systemInformation.systemUptime = this.formatOsUpTime(os.uptime());
package/dist/index.js CHANGED
@@ -11,14 +11,6 @@ export * from './matterbridgePlatform.js';
11
11
  export * from './matterbridgeAccessoryPlatform.js';
12
12
  export * from './matterbridgeDynamicPlatform.js';
13
13
  export { addVirtualDevice } from './helpers.js';
14
- export * from './devices/roboticVacuumCleaner.js';
15
- export * from './devices/laundryWasher.js';
16
- export * from './devices/laundryDryer.js';
17
- export * from './devices/waterHeater.js';
18
- export * from './devices/evse.js';
19
- export * from './devices/solarPower.js';
20
- export * from './devices/batteryStorage.js';
21
- export * from './devices/heatPump.js';
22
14
  const log = new AnsiLogger({ logName: 'Main', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
23
15
  async function main() {
24
16
  log.debug('***Matterbridge.loadInstance() called');
@@ -241,8 +241,6 @@ export class PluginManager extends EventEmitter {
241
241
  plugin.help = this.getHelp(packageJson);
242
242
  plugin.changelog = this.getChangelog(packageJson);
243
243
  plugin.funding = this.getFunding(packageJson);
244
- if (!plugin.path)
245
- this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no path`);
246
244
  if (!plugin.type)
247
245
  this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
248
246
  const checkForProjectChipPackages = (dependencies) => {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.1.1-dev-20250704-aff5fcb",
3
+ "version": "3.1.2-dev-20250705-7da1eac",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "3.1.1-dev-20250704-aff5fcb",
9
+ "version": "3.1.2-dev-20250705-7da1eac",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.15.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.1.1-dev-20250704-aff5fcb",
3
+ "version": "3.1.2-dev-20250705-7da1eac",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",