@matterbridge/core 3.5.6-dev-20260222-9aca698 → 3.5.6-dev-20260223-7c65d78

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.
@@ -255,7 +255,7 @@ export async function createMatterbridgeEnvironment(name) {
255
255
  matterbridge = await Matterbridge.loadInstance(false);
256
256
  expect(matterbridge).toBeDefined();
257
257
  expect(matterbridge).toBeInstanceOf(Matterbridge);
258
- matterbridge.matterbridgeVersion = '3.5.5';
258
+ matterbridge.matterbridgeVersion = '3.5.6';
259
259
  matterbridge.bridgeMode = 'bridge';
260
260
  matterbridge.rootDirectory = path.join('jest', name);
261
261
  matterbridge.homeDirectory = path.join('jest', name);
@@ -102,6 +102,11 @@ export declare class Matterbridge extends EventEmitter<MatterbridgeEvents> {
102
102
  aggregatorDeviceType: DeviceTypeId;
103
103
  aggregatorSerialNumber: string | undefined;
104
104
  aggregatorUniqueId: string | undefined;
105
+ controllerNode: ServerNode<ServerNode.RootEndpoint> | undefined;
106
+ controllerVendorId: VendorId;
107
+ controllerVendorName: string;
108
+ controllerProductId: number;
109
+ controllerProductName: string;
105
110
  advertisingNodes: Map<string, number>;
106
111
  private readonly server;
107
112
  private readonly verbose;
@@ -21,6 +21,7 @@ import { NodeStorageManager } from 'node-persist-manager';
21
21
  import { DeviceManager } from './deviceManager.js';
22
22
  import { Frontend } from './frontend.js';
23
23
  import { addVirtualDevice, addVirtualDevices } from './helpers.js';
24
+ import { ManualPairingCodeCodec } from './matter/types.js';
24
25
  import { bridge } from './matterbridgeDeviceTypes.js';
25
26
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
26
27
  import { PluginManager } from './pluginManager.js';
@@ -121,6 +122,11 @@ export class Matterbridge extends EventEmitter {
121
122
  aggregatorDeviceType = DeviceTypeId(getIntParameter('deviceType') ?? bridge.code);
122
123
  aggregatorSerialNumber = getParameter('serialNumber');
123
124
  aggregatorUniqueId = getParameter('uniqueId');
125
+ controllerNode;
126
+ controllerVendorId = VendorId(getIntParameter('vendorId') ?? 0xfff1);
127
+ controllerVendorName = getParameter('vendorName') ?? 'Matterbridge';
128
+ controllerProductId = getIntParameter('productId') ?? 0x8000;
129
+ controllerProductName = getParameter('productName') ?? 'Matterbridge controller';
124
130
  advertisingNodes = new Map();
125
131
  server;
126
132
  verbose = hasParameter('verbose');
@@ -534,6 +540,7 @@ export class Matterbridge extends EventEmitter {
534
540
  await this.plugins.loadFromStorage();
535
541
  this.devices.logLevel = this.log.logLevel;
536
542
  for (const plugin of this.plugins) {
543
+ this.log.debug(`Parsing plugin ${plg}${plugin.name}${db} from path ${CYAN}${plugin.path}${db} with version ${CYAN}${plugin.version}${db} and type ${CYAN}${plugin.type}${db}.`);
537
544
  if (!fs.existsSync(plugin.path) &&
538
545
  !hasParameter('add') &&
539
546
  !hasParameter('remove') &&
@@ -1121,6 +1128,12 @@ export class Matterbridge extends EventEmitter {
1121
1128
  }
1122
1129
  }
1123
1130
  this.log.notice('Stopped matter server nodes');
1131
+ if (this.controllerNode) {
1132
+ this.log.notice(`Stopping matter controller...`);
1133
+ await this.stopServerNode(this.controllerNode);
1134
+ this.controllerNode = undefined;
1135
+ this.log.notice('Stopped matter controller');
1136
+ }
1124
1137
  if (message === 'shutting down with reset...') {
1125
1138
  this.log.info('Resetting Matterbridge commissioning information...');
1126
1139
  await this.matterStorageManager?.createContext('events')?.clearAll();
@@ -1455,6 +1468,95 @@ export class Matterbridge extends EventEmitter {
1455
1468
  }, Number(process.env['MATTERBRIDGE_START_MATTER_INTERVAL_MS']) || this.startMatterIntervalMs);
1456
1469
  }
1457
1470
  async startController() {
1471
+ if (!this.matterStorageManager) {
1472
+ this.log.error('No storage manager initialized');
1473
+ await this.cleanup('No storage manager initialized');
1474
+ return;
1475
+ }
1476
+ if (!this.matterStorageService) {
1477
+ this.log.error('No storage service initialized');
1478
+ await this.cleanup('No storage service initialized');
1479
+ return;
1480
+ }
1481
+ this.matterStorageManager = await this.matterStorageService.open('MatterbridgeController');
1482
+ this.log.info('Matter node storage manager "MatterbridgeController" created');
1483
+ this.log.info('Creating context controllerContext...');
1484
+ this.controllerContext = this.matterStorageManager.createContext('controllerContext');
1485
+ if (!this.controllerContext) {
1486
+ this.log.error('No storage context controllerContext initialized');
1487
+ await this.cleanup('No storage context controllerContext initialized');
1488
+ return;
1489
+ }
1490
+ const { randomBytes } = await import('node:crypto');
1491
+ const storeId = 'MatterbridgeController';
1492
+ const random = randomBytes(8).toString('hex');
1493
+ await this.controllerContext.set('storeId', storeId);
1494
+ await this.controllerContext.set('vendorId', this.controllerVendorId);
1495
+ await this.controllerContext.set('vendorName', this.controllerVendorName.slice(0, 32));
1496
+ await this.controllerContext.set('productId', this.controllerProductId);
1497
+ await this.controllerContext.set('productName', this.controllerProductName.slice(0, 32));
1498
+ await this.controllerContext.set('productLabel', this.controllerProductName.slice(0, 32));
1499
+ await this.controllerContext.set('nodeLabel', storeId.slice(0, 32));
1500
+ await this.controllerContext.set('serialNumber', await this.controllerContext.get('serialNumber', 'SN' + random));
1501
+ await this.controllerContext.set('uniqueId', await this.controllerContext.get('uniqueId', 'UI' + random));
1502
+ await this.controllerContext.set('softwareVersion', isValidNumber(parseVersionString(this.matterbridgeVersion), 0, UINT32_MAX) ? parseVersionString(this.matterbridgeVersion) : 1);
1503
+ await this.controllerContext.set('softwareVersionString', isValidString(this.matterbridgeVersion, 5, 64) ? this.matterbridgeVersion : '1.0.0');
1504
+ await this.controllerContext.set('hardwareVersion', isValidNumber(parseVersionString(this.systemInformation.osRelease), 0, UINT16_MAX) ? parseVersionString(this.systemInformation.osRelease) : 1);
1505
+ await this.controllerContext.set('hardwareVersionString', isValidString(this.systemInformation.osRelease, 5, 64) ? this.systemInformation.osRelease : '1.0.0');
1506
+ this.log.info('Creating matter commissioning controller...');
1507
+ this.controllerNode = await ServerNode.create({
1508
+ id: storeId,
1509
+ environment: this.environment,
1510
+ network: {
1511
+ listeningAddressIpv4: this.ipv4Address,
1512
+ listeningAddressIpv6: this.ipv6Address,
1513
+ port: this.port,
1514
+ },
1515
+ basicInformation: {
1516
+ nodeLabel: await this.controllerContext.get('nodeLabel'),
1517
+ vendorId: VendorId(await this.controllerContext.get('vendorId')),
1518
+ vendorName: await this.controllerContext.get('vendorName'),
1519
+ productId: await this.controllerContext.get('productId'),
1520
+ productName: await this.controllerContext.get('productName'),
1521
+ productLabel: await this.controllerContext.get('productLabel'),
1522
+ serialNumber: await this.controllerContext.get('serialNumber'),
1523
+ uniqueId: await this.controllerContext.get('uniqueId'),
1524
+ softwareVersion: await this.controllerContext.get('softwareVersion'),
1525
+ softwareVersionString: await this.controllerContext.get('softwareVersionString'),
1526
+ hardwareVersion: await this.controllerContext.get('hardwareVersion'),
1527
+ hardwareVersionString: await this.controllerContext.get('hardwareVersionString'),
1528
+ reachable: true,
1529
+ },
1530
+ });
1531
+ this.log.info(`Starting matter commissioning controller: ${this.controllerNode.peers.size} peer nodes...`);
1532
+ if (hasParameter('pair')) {
1533
+ let options;
1534
+ if (hasParameter('pairingcode')) {
1535
+ const pairingCode = getParameter('pairingcode');
1536
+ this.log.info(`Pairing device with pairingcode: ${pairingCode}`);
1537
+ const pairingData = ManualPairingCodeCodec.decode(pairingCode);
1538
+ this.log.info(`Data extracted from pairing code: ${Logger.toJSON(pairingData)}`);
1539
+ options = { id: 'device', pairingCode };
1540
+ }
1541
+ else {
1542
+ const discriminator = getIntParameter('discriminator');
1543
+ const passcode = getIntParameter('passcode') ?? 0;
1544
+ options = { id: 'device', discriminator, passcode };
1545
+ }
1546
+ this.log.info('Commissioning with options:', options);
1547
+ const nodeId = this.controllerNode.peers.commission(options);
1548
+ this.log.info(`Commissioning successfully done with nodeId: ${nodeId}`);
1549
+ }
1550
+ if (hasParameter('unpairall')) {
1551
+ this.log.info('Matter commissioning controller decommissioning all nodes...');
1552
+ const nodeIds = this.controllerNode.peers;
1553
+ for (const nodeId of nodeIds) {
1554
+ this.log.info('Matter commissioning controller decommissioning node:', nodeId.id);
1555
+ await nodeId.decommission();
1556
+ }
1557
+ this.log.info('Matter commissioning controller decommissioned all nodes');
1558
+ return;
1559
+ }
1458
1560
  }
1459
1561
  async startMatterStorage() {
1460
1562
  this.log.info(`Starting matter node storage...`);
@@ -1651,7 +1753,7 @@ export class Matterbridge extends EventEmitter {
1651
1753
  id: serverNode.id,
1652
1754
  online: serverNode.lifecycle.isOnline,
1653
1755
  commissioned: serverNode.state.commissioning.commissioned,
1654
- advertising: advertiseTime > Date.now() - 15 * 60 * 1000,
1756
+ advertising: true,
1655
1757
  advertiseTime,
1656
1758
  windowStatus: serverNode.state.administratorCommissioning.windowStatus,
1657
1759
  qrPairingCode: serverNode.state.commissioning.pairingCodes.qrPairingCode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matterbridge/core",
3
- "version": "3.5.6-dev-20260222-9aca698",
3
+ "version": "3.5.6-dev-20260223-7c65d78",
4
4
  "description": "Matterbridge core library",
5
5
  "author": "https://github.com/Luligu",
6
6
  "homepage": "https://matterbridge.io/",
@@ -121,11 +121,11 @@
121
121
  "CHANGELOG.md"
122
122
  ],
123
123
  "dependencies": {
124
- "@matter/main": "0.16.8",
125
- "@matterbridge/dgram": "3.5.6-dev-20260222-9aca698",
126
- "@matterbridge/thread": "3.5.6-dev-20260222-9aca698",
127
- "@matterbridge/types": "3.5.6-dev-20260222-9aca698",
128
- "@matterbridge/utils": "3.5.6-dev-20260222-9aca698",
124
+ "@matter/main": "0.16.10",
125
+ "@matterbridge/dgram": "3.5.6-dev-20260223-7c65d78",
126
+ "@matterbridge/thread": "3.5.6-dev-20260223-7c65d78",
127
+ "@matterbridge/types": "3.5.6-dev-20260223-7c65d78",
128
+ "@matterbridge/utils": "3.5.6-dev-20260223-7c65d78",
129
129
  "archiver": "7.0.1",
130
130
  "express": "5.2.1",
131
131
  "glob": "13.0.6",