matterbridge 3.1.2-dev-20250706-6c6481e → 3.1.2-dev-20250708-167e3ae

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,16 +8,17 @@ 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.2] - 2025-07-??
11
+ ## [3.1.2] - 2025-07-06
12
12
 
13
13
  ### Development Breaking Changes
14
14
 
15
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.
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. Refer to the [documentation](README-DEV.md) for details on using mode.
17
+ - [RoboticVacuumCleaner]: The signature of the constructor has changed to add the mode property. Mode `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. Refer to the [documentation](README-DEV.md) for details on using mode.
17
18
 
18
19
  ### Added
19
20
 
20
- - [test]: Improved test units on Frontend class and all Matterbridge classes (coverage 94%).
21
+ - [test]: Improved test units on Frontend class (coverage 97%).
21
22
 
22
23
  ### Changed
23
24
 
package/README-DEV.md CHANGED
@@ -272,7 +272,7 @@ 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], { id: 'EntryDoor', mode: 'server' })
275
+ const device = new MatterbridgeEndpoint([contactSensor, powerSource], { id: 'EntryDoor' })
276
276
  .createDefaultIdentifyClusterServer()
277
277
  .createDefaultBasicInformationClusterServer('My entry door', '0123456789')
278
278
  .createDefaultBooleanStateClusterServer(true)
@@ -282,14 +282,22 @@ 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
-
289
285
  All device types are defined in src\matterbridgeDeviceTypes.ts and taken from the 'Matter-1.4-Device-Library-Specification.pdf'.
290
286
 
291
287
  All default cluster helpers are available as methods of MatterbridgeEndpoint.
292
288
 
289
+ ## MatterbridgeEndpointOptions
290
+
291
+ ```typescript
292
+ const robot = new RoboticVacuumCleaner('Robot Vacuum', 'RVC1238777820', 'server');
293
+ ```
294
+
295
+ In the above example we create a Rvc device type with its own server node.
296
+
297
+ 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.
298
+
299
+ 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.
300
+
293
301
  # Contribution Guidelines
294
302
 
295
303
  Thank you for your interest in contributing to my project!
package/dist/frontend.js CHANGED
@@ -622,7 +622,7 @@ export class Frontend extends EventEmitter {
622
622
  }
623
623
  }
624
624
  getMatterDataFromDevice(device) {
625
- if (device.mode === 'server' && device.serverNode && device.serverContext) {
625
+ if (device.mode === 'server' && device.serverNode) {
626
626
  return {
627
627
  commissioned: device.serverNode.state.commissioning.commissioned,
628
628
  qrPairingCode: device.serverNode.state.commissioning.pairingCodes.qrPairingCode,
@@ -1514,6 +1514,7 @@ export class Frontend extends EventEmitter {
1514
1514
  if (!restartRequired)
1515
1515
  this.wssSendRefreshRequired('pluginsRestart');
1516
1516
  this.wssSendRestartRequired(false);
1517
+ client.send(JSON.stringify({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true }));
1517
1518
  }
1518
1519
  else {
1519
1520
  this.log.error(`SelectDevice: select ${select} not supported`);
@@ -1560,6 +1561,7 @@ export class Frontend extends EventEmitter {
1560
1561
  if (!restartRequired)
1561
1562
  this.wssSendRefreshRequired('pluginsRestart');
1562
1563
  this.wssSendRestartRequired(false);
1564
+ client.send(JSON.stringify({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true }));
1563
1565
  }
1564
1566
  else {
1565
1567
  this.log.error(`SelectDevice: select ${select} not supported`);
@@ -1054,7 +1054,6 @@ export class Matterbridge extends EventEmitter {
1054
1054
  if (device.mode === 'server' && device.serverNode) {
1055
1055
  await this.stopServerNode(device.serverNode);
1056
1056
  device.serverNode = undefined;
1057
- device.serverContext = undefined;
1058
1057
  }
1059
1058
  }
1060
1059
  this.log.notice('Stopped matter server nodes');
@@ -1153,8 +1152,8 @@ export class Matterbridge extends EventEmitter {
1153
1152
  async createDeviceServerNode(plugin, device) {
1154
1153
  if (device.mode === 'server' && !device.serverNode && device.deviceType && device.deviceName && device.vendorId && device.vendorName && device.productId && device.productName) {
1155
1154
  this.log.debug(`Creating device ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} server node...`);
1156
- device.serverContext = await this.createServerNodeContext(device.deviceName.replace(/[ .]/g, ''), device.deviceName, DeviceTypeId(device.deviceType), device.vendorId, device.vendorName, device.productId, device.productName);
1157
- device.serverNode = await this.createServerNode(device.serverContext, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
1155
+ const context = await this.createServerNodeContext(device.deviceName.replace(/[ .]/g, ''), device.deviceName, DeviceTypeId(device.deviceType), device.vendorId, device.vendorName, device.productId, device.productName);
1156
+ device.serverNode = await this.createServerNode(context, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
1158
1157
  this.log.debug(`Adding ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} to server node...`);
1159
1158
  await device.serverNode.add(device);
1160
1159
  this.log.debug(`Added ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} to server node`);
@@ -1911,8 +1910,11 @@ export class Matterbridge extends EventEmitter {
1911
1910
  case 5264:
1912
1911
  vendorName = '(Shelly)';
1913
1912
  break;
1913
+ case 0x1488:
1914
+ vendorName = '(ShortcutLabsFlic)';
1915
+ break;
1914
1916
  case 65521:
1915
- vendorName = '(MatterServer)';
1917
+ vendorName = '(MatterTest)';
1916
1918
  break;
1917
1919
  }
1918
1920
  return vendorName;
@@ -1,4 +1,4 @@
1
- import { Endpoint, Lifecycle, MutableEndpoint, NamedHandler, SupportedBehaviors, UINT16_MAX, UINT32_MAX, VendorId, } from '@matter/main';
1
+ import { Endpoint, Lifecycle, MutableEndpoint, NamedHandler, SupportedBehaviors, UINT16_MAX, UINT32_MAX, VendorId } from '@matter/main';
2
2
  import { getClusterNameById, MeasurementType } from '@matter/main/types';
3
3
  import { Descriptor } from '@matter/main/clusters/descriptor';
4
4
  import { PowerSource } from '@matter/main/clusters/power-source';
@@ -68,7 +68,6 @@ export class MatterbridgeEndpoint extends Endpoint {
68
68
  static bridgeMode = '';
69
69
  static logLevel = "info";
70
70
  mode = undefined;
71
- serverContext;
72
71
  serverNode;
73
72
  log;
74
73
  plugin = undefined;
@@ -409,47 +408,47 @@ export class MatterbridgeEndpoint extends Endpoint {
409
408
  }
410
409
  createDefaultPowerSourceWiredClusterServer(wiredCurrentType = PowerSource.WiredCurrentType.Ac) {
411
410
  this.behaviors.require(PowerSourceServer.with(PowerSource.Feature.Wired), {
412
- wiredCurrentType,
413
- description: wiredCurrentType === PowerSource.WiredCurrentType.Ac ? 'AC Power' : 'DC Power',
414
411
  status: PowerSource.PowerSourceStatus.Active,
415
412
  order: 0,
413
+ description: wiredCurrentType === PowerSource.WiredCurrentType.Ac ? 'AC Power' : 'DC Power',
416
414
  endpointList: [],
415
+ wiredCurrentType,
417
416
  });
418
417
  return this;
419
418
  }
420
- createDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500, batReplacementDescription = 'Battery type', batQuantity = 1) {
419
+ createDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500, batReplacementDescription = 'Battery type', batQuantity = 1, batReplaceability = PowerSource.BatReplaceability.UserReplaceable) {
421
420
  this.behaviors.require(PowerSourceServer.with(PowerSource.Feature.Battery, PowerSource.Feature.Replaceable), {
422
421
  status: PowerSource.PowerSourceStatus.Active,
423
422
  order: 0,
424
423
  description: 'Primary battery',
424
+ endpointList: [],
425
425
  batVoltage,
426
426
  batPercentRemaining: Math.min(Math.max(batPercentRemaining * 2, 0), 200),
427
427
  batChargeLevel,
428
428
  batReplacementNeeded: false,
429
- batReplaceability: PowerSource.BatReplaceability.UserReplaceable,
429
+ batReplaceability,
430
430
  activeBatFaults: undefined,
431
431
  batReplacementDescription,
432
432
  batQuantity,
433
- endpointList: [],
434
433
  });
435
434
  return this;
436
435
  }
437
- createDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500) {
436
+ createDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500, batReplaceability = PowerSource.BatReplaceability.Unspecified) {
438
437
  this.behaviors.require(PowerSourceServer.with(PowerSource.Feature.Battery, PowerSource.Feature.Rechargeable), {
439
438
  status: PowerSource.PowerSourceStatus.Active,
440
439
  order: 0,
441
440
  description: 'Primary battery',
441
+ endpointList: [],
442
442
  batVoltage,
443
443
  batPercentRemaining: Math.min(Math.max(batPercentRemaining * 2, 0), 200),
444
444
  batTimeRemaining: null,
445
445
  batChargeLevel,
446
446
  batReplacementNeeded: false,
447
- batReplaceability: PowerSource.BatReplaceability.Unspecified,
447
+ batReplaceability,
448
448
  batPresent: true,
449
449
  activeBatFaults: [],
450
450
  batChargeState: PowerSource.BatChargeState.IsNotCharging,
451
451
  batFunctionalWhileCharging: true,
452
- endpointList: [],
453
452
  });
454
453
  return this;
455
454
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.1.2-dev-20250706-6c6481e",
3
+ "version": "3.1.2-dev-20250708-167e3ae",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "3.1.2-dev-20250706-6c6481e",
9
+ "version": "3.1.2-dev-20250708-167e3ae",
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.2-dev-20250706-6c6481e",
3
+ "version": "3.1.2-dev-20250708-167e3ae",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",