matterbridge 1.6.8-dev.7 → 1.6.8-dev.8

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
@@ -13,11 +13,11 @@ It is also available the official Matterbridge Home Assistant plugin https://git
13
13
 
14
14
  Tamer (https://github.com/tammeryousef1006) has created the Matterbridge Discord group: https://discord.gg/QX58CDe6hd.
15
15
 
16
- ## [1.6.8-dev.7] - 2024-12-19
16
+ ## [1.6.8-dev.8] - 2024-12-19
17
17
 
18
18
  ### Added
19
19
 
20
- - [storage]: Added conversion from old matter storage to the new api format with fabrics, resumptionRecords, network, commissioning, operationalCredentials, acl and parts number.
20
+ - [storage]: Added conversion from old matter storage to the new api format with fabrics, resumptionRecords, network, commissioning, operationalCredentials, acl and parts number. The conversion is triggered every time you shutdown or restart matterbridge till the new storage has been used with matterbridge edge.
21
21
  - [package]: Update README.md and README-SERVICE.md to include instructions for using SSL on port 443.
22
22
 
23
23
  ### Changed
@@ -990,7 +990,7 @@ export class Matterbridge extends EventEmitter {
990
990
  });
991
991
  this.webSocketServer = undefined;
992
992
  }
993
- if (hasParameter('convert') && this.edge === false && this.matterbridgeContext && ['updating...', 'restarting...', 'shutting down...'].includes(message)) {
993
+ if (!hasParameter('nostorageconversion') && this.edge === false && this.matterbridgeContext && ['updating...', 'restarting...', 'shutting down...'].includes(message)) {
994
994
  await this.convertStorage(this.matterbridgeContext, 'Mattebridge');
995
995
  }
996
996
  await this.stopMatterServer();
@@ -1549,128 +1549,134 @@ export class Matterbridge extends EventEmitter {
1549
1549
  await this.matterbridgeContext.set('discriminator', this.discriminator);
1550
1550
  }
1551
1551
  async convertStorage(context, pluginName) {
1552
- const storageService = Environment.default.get(StorageService);
1553
- Environment.default.vars.set('path.root', path.join(this.matterbridgeDirectory, 'matterstorage' + (this.profile ? '.' + this.profile : '')));
1554
- const nodeStorage = await storageService.open('Matterbridge');
1555
- if ((await nodeStorage.createContext('persist').get('converted', false)) === true) {
1556
- this.log.info(`Matter node storage already converted to Matterbridge edge for ${plg}${pluginName}${nf}`);
1557
- return;
1558
- }
1559
- else {
1560
- this.log.notice(`Converting matter node storage to Matterbridge edge for ${plg}${pluginName}${nt}...`);
1561
- }
1562
- const fabricManagerContext = context.createContext('FabricManager');
1563
- const fabrics = (await fabricManagerContext.get('fabrics', []));
1564
- const nextFabricIndex = await fabricManagerContext.get('nextFabricIndex', 1);
1565
- const eventHandlerContext = context.createContext('EventHandler');
1566
- const sessionManagerContext = context.createContext('SessionManager');
1567
- const endpointStructureContext = context.createContext('EndpointStructure');
1568
- const generalCommissioningContext = context.createContext('Cluster-0-48');
1569
- const basicInformationContext = context.createContext('Cluster-0-40');
1570
- const fabricInfo = {};
1571
- const fabricInfoArray = [];
1572
- const nocArray = [];
1573
- const trcArray = [];
1574
- const aclArray = [];
1575
- this.log.info(`Found ${CYAN}${fabrics.length}${nf} fabrics (nextFabricIndex ${CYAN}${nextFabricIndex}${nf}) for ${plg}${pluginName}${nf}:`);
1576
- for (const fabric of fabrics) {
1577
- this.log.info(`- fabricIndex ${CYAN}${fabric.fabricIndex}${nf} fabricId ${CYAN}${fabric.fabricId}${nf} nodeId ${CYAN}${fabric.nodeId}${nf} rootNodeId ${CYAN}${fabric.rootNodeId}${nf} rootVendorId ${CYAN}${fabric.rootVendorId}${nf} label ${CYAN}${fabric.label}${nf}`);
1578
- fabricInfo[fabric.fabricIndex] = {
1579
- fabricIndex: fabric.fabricIndex,
1580
- fabricId: fabric.fabricId,
1581
- nodeId: fabric.nodeId,
1582
- rootNodeId: fabric.rootNodeId,
1583
- rootVendorId: fabric.rootVendorId,
1584
- label: fabric.label,
1585
- };
1586
- fabricInfoArray.push({
1587
- fabricIndex: fabric.fabricIndex,
1588
- fabricId: fabric.fabricId,
1589
- nodeId: fabric.nodeId,
1590
- vendorId: fabric.rootVendorId,
1591
- rootPublicKey: fabric.rootPublicKey,
1592
- label: fabric.label,
1593
- });
1594
- nocArray.push({ noc: fabric.operationalCert, icac: null, fabricIndex: fabric.fabricIndex });
1595
- trcArray.push('{\"__object__\":\"Uint8Array\",\"__value__\":\"' + Buffer.from(fabric.rootCert).toString('hex') + '\"}');
1596
- this.log.info(`- updating ACL for fabricIndex ${fabric.fabricIndex}:`, fabric.scopedClusterData);
1597
- const acl = fabric.scopedClusterData.get(0x1f)?.get('acl');
1598
- if (acl && acl.value.length > 0) {
1599
- aclArray.push(acl.value[0]);
1600
- this.log.info(`- ACL updated to ${debugStringify(acl.value)}${nf} for fabricIndex ${CYAN}${fabric.fabricIndex}${nf}`);
1552
+ try {
1553
+ const storageService = Environment.default.get(StorageService);
1554
+ Environment.default.vars.set('path.root', path.join(this.matterbridgeDirectory, 'matterstorage' + (this.profile ? '.' + this.profile : '')));
1555
+ const nodeStorage = await storageService.open('Matterbridge');
1556
+ if ((await nodeStorage.createContext('root').createContext('generalDiagnostics').get('rebootCount', 0)) > 0) {
1557
+ this.log.info(`Matter node storage already converted to Matterbridge edge for ${plg}${pluginName}${nf}`);
1558
+ return;
1601
1559
  }
1602
1560
  else {
1603
- const defaultAcl = { fabricIndex: fabric.fabricIndex, privilege: 5, authMode: 2, subjects: [fabric.rootNodeId], targets: null };
1604
- aclArray.push(defaultAcl);
1605
- this.log.info(`- ACL updated to default ${debugStringify(defaultAcl)}${nf} for fabricIndex ${CYAN}${fabric.fabricIndex}${nf}`);
1606
- }
1607
- }
1608
- await nodeStorage.createContext('fabrics').set('fabrics', fabrics);
1609
- await nodeStorage.createContext('fabrics').set('nextFabricIndex', nextFabricIndex);
1610
- await nodeStorage.createContext('sessions').set('resumptionRecords', await sessionManagerContext.get('resumptionRecords', []));
1611
- await nodeStorage.createContext('events').set('lastEventNumber', await eventHandlerContext.get('lastEventNumber', 1));
1612
- await nodeStorage.createContext('root').set('__number__', 0);
1613
- await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').set('__number__', 1);
1614
- await nodeStorage.createContext('root').createContext('commissioning').set('enabled', true);
1615
- await nodeStorage.createContext('root').createContext('commissioning').set('commissioned', true);
1616
- await nodeStorage.createContext('root').createContext('commissioning').set('fabrics', fabricInfo);
1617
- await nodeStorage.createContext('root').createContext('operationalCredentials').set('commissionedFabrics', fabricInfoArray.length);
1618
- await nodeStorage.createContext('root').createContext('operationalCredentials').set('fabrics', fabricInfoArray);
1619
- await nodeStorage.createContext('root').createContext('operationalCredentials').set('nocs', nocArray);
1620
- await nodeStorage.createContext('root').createContext('operationalCredentials').set('trustedRootCertificates', trcArray);
1621
- await nodeStorage.createContext('root').createContext('accessControl').set('acl', aclArray);
1622
- await nodeStorage
1623
- .createContext('root')
1624
- .createContext('generalCommissioning')
1625
- .set('breadcrumb', await generalCommissioningContext.get('breadcrumb', BigInt(0)));
1626
- await nodeStorage
1627
- .createContext('root')
1628
- .createContext('basicInformation')
1629
- .set('location', await basicInformationContext.get('location', 'XX'));
1630
- await nodeStorage.createContext('root').createContext('network').set('ble', false);
1631
- await nodeStorage.createContext('root').createContext('network').set('operationalPort', 5540);
1632
- await nodeStorage.createContext('root').createContext('productDescription').set('productId', 0x8000);
1633
- await nodeStorage.createContext('root').createContext('productDescription').set('vendorId', 0xfff1);
1634
- for (const key of await endpointStructureContext.keys()) {
1635
- if (key === 'nextEndpointId') {
1636
- await nodeStorage.createContext('root').set('__nextNumber__', await endpointStructureContext.get(key));
1637
- continue;
1561
+ this.log.notice(`Converting matter node storage to Matterbridge edge for ${plg}${pluginName}${nt}...`);
1562
+ }
1563
+ const fabricManagerContext = context.createContext('FabricManager');
1564
+ const fabrics = (await fabricManagerContext.get('fabrics', []));
1565
+ const nextFabricIndex = await fabricManagerContext.get('nextFabricIndex', 1);
1566
+ const eventHandlerContext = context.createContext('EventHandler');
1567
+ const sessionManagerContext = context.createContext('SessionManager');
1568
+ const endpointStructureContext = context.createContext('EndpointStructure');
1569
+ const generalCommissioningContext = context.createContext('Cluster-0-48');
1570
+ const basicInformationContext = context.createContext('Cluster-0-40');
1571
+ const fabricInfo = {};
1572
+ const fabricInfoArray = [];
1573
+ const nocArray = [];
1574
+ const trcArray = [];
1575
+ const aclArray = [];
1576
+ this.log.info(`Found ${CYAN}${fabrics.length}${nf} fabrics (nextFabricIndex ${CYAN}${nextFabricIndex}${nf}) for ${plg}${pluginName}${nf}:`);
1577
+ for (const fabric of fabrics) {
1578
+ this.log.info(`- fabricIndex ${CYAN}${fabric.fabricIndex}${nf} fabricId ${CYAN}${fabric.fabricId}${nf} nodeId ${CYAN}${fabric.nodeId}${nf} rootNodeId ${CYAN}${fabric.rootNodeId}${nf} rootVendorId ${CYAN}${fabric.rootVendorId}${nf} label ${CYAN}${fabric.label}${nf}`);
1579
+ fabricInfo[fabric.fabricIndex] = {
1580
+ fabricIndex: fabric.fabricIndex,
1581
+ fabricId: fabric.fabricId,
1582
+ nodeId: fabric.nodeId,
1583
+ rootNodeId: fabric.rootNodeId,
1584
+ rootVendorId: fabric.rootVendorId,
1585
+ label: fabric.label,
1586
+ };
1587
+ fabricInfoArray.push({
1588
+ fabricIndex: fabric.fabricIndex,
1589
+ fabricId: fabric.fabricId,
1590
+ nodeId: fabric.nodeId,
1591
+ vendorId: fabric.rootVendorId,
1592
+ rootPublicKey: fabric.rootPublicKey,
1593
+ label: fabric.label,
1594
+ });
1595
+ nocArray.push({ noc: fabric.operationalCert, icac: null, fabricIndex: fabric.fabricIndex });
1596
+ trcArray.push('{\"__object__\":\"Uint8Array\",\"__value__\":\"' + Buffer.from(fabric.rootCert).toString('hex') + '\"}');
1597
+ this.log.info(`- updating ACL for fabricIndex ${fabric.fabricIndex}:`, fabric.scopedClusterData);
1598
+ const acl = fabric.scopedClusterData.get(0x1f)?.get('acl');
1599
+ if (acl && acl.value.length > 0) {
1600
+ aclArray.push(acl.value[0]);
1601
+ this.log.info(`- ACL updated to ${debugStringify(acl.value)}${nf} for fabricIndex ${CYAN}${fabric.fabricIndex}${nf}`);
1602
+ }
1603
+ else {
1604
+ const defaultAcl = { fabricIndex: fabric.fabricIndex, privilege: 5, authMode: 2, subjects: [fabric.rootNodeId], targets: null };
1605
+ aclArray.push(defaultAcl);
1606
+ this.log.info(`- ACL updated to default ${debugStringify(defaultAcl)}${nf} for fabricIndex ${CYAN}${fabric.fabricIndex}${nf}`);
1607
+ }
1608
+ }
1609
+ await nodeStorage.createContext('fabrics').set('fabrics', fabrics);
1610
+ await nodeStorage.createContext('fabrics').set('nextFabricIndex', nextFabricIndex);
1611
+ await nodeStorage.createContext('sessions').set('resumptionRecords', await sessionManagerContext.get('resumptionRecords', []));
1612
+ await nodeStorage.createContext('events').set('lastEventNumber', await eventHandlerContext.get('lastEventNumber', 1));
1613
+ await nodeStorage.createContext('root').set('__number__', 0);
1614
+ await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').set('__number__', 1);
1615
+ await nodeStorage.createContext('root').createContext('commissioning').set('enabled', true);
1616
+ await nodeStorage.createContext('root').createContext('commissioning').set('commissioned', true);
1617
+ await nodeStorage.createContext('root').createContext('commissioning').set('fabrics', fabricInfo);
1618
+ await nodeStorage.createContext('root').createContext('operationalCredentials').set('commissionedFabrics', fabricInfoArray.length);
1619
+ await nodeStorage.createContext('root').createContext('operationalCredentials').set('fabrics', fabricInfoArray);
1620
+ await nodeStorage.createContext('root').createContext('operationalCredentials').set('nocs', nocArray);
1621
+ await nodeStorage.createContext('root').createContext('operationalCredentials').set('trustedRootCertificates', trcArray);
1622
+ await nodeStorage.createContext('root').createContext('accessControl').set('acl', aclArray);
1623
+ await nodeStorage
1624
+ .createContext('root')
1625
+ .createContext('generalCommissioning')
1626
+ .set('breadcrumb', await generalCommissioningContext.get('breadcrumb', BigInt(0)));
1627
+ await nodeStorage
1628
+ .createContext('root')
1629
+ .createContext('basicInformation')
1630
+ .set('location', await basicInformationContext.get('location', 'XX'));
1631
+ await nodeStorage.createContext('root').createContext('network').set('ble', false);
1632
+ await nodeStorage.createContext('root').createContext('network').set('operationalPort', 5540);
1633
+ await nodeStorage.createContext('root').createContext('productDescription').set('productId', 0x8000);
1634
+ await nodeStorage.createContext('root').createContext('productDescription').set('vendorId', 0xfff1);
1635
+ for (const key of await endpointStructureContext.keys()) {
1636
+ if (key === 'nextEndpointId') {
1637
+ await nodeStorage.createContext('root').set('__nextNumber__', await endpointStructureContext.get(key));
1638
+ continue;
1639
+ }
1640
+ const parts = key.split('-');
1641
+ const number = await endpointStructureContext.get(key);
1642
+ if (parts.length === 2) {
1643
+ this.log.debug(`Converting Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.__number__:${number}`);
1644
+ await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').set('__number__', number);
1645
+ }
1646
+ else if (parts.length === 3 && parts[2].startsWith('custom_')) {
1647
+ this.log.debug(`Converting Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.parts.${parts[2].replace('custom_', '')}.__number__:${number}`);
1648
+ await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').createContext('parts').createContext(parts[2].replace('custom_', '')).set('__number__', number);
1649
+ }
1650
+ else if (parts.length === 3 && parts[2].startsWith('unique_')) {
1651
+ const device = this.devices.get(parts[2].replace('unique_', ''));
1652
+ if (device && device.deviceName && device.maybeNumber) {
1653
+ this.log.debug(`Converting Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.parts.${device.deviceName.replace(/[ .]/g, '')}.__number__:${device.maybeNumber}`);
1654
+ await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').createContext('parts').createContext(device.deviceName.replace(/[ .]/g, '')).set('__number__', device.maybeNumber);
1655
+ }
1656
+ }
1638
1657
  }
1639
- const parts = key.split('-');
1640
- const number = await endpointStructureContext.get(key);
1641
- if (parts.length === 2) {
1642
- this.log.debug(`Converting Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.__number__:${number}`);
1643
- await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').set('__number__', number);
1644
- }
1645
- else if (parts.length === 3 && parts[2].startsWith('custom_')) {
1646
- this.log.debug(`Converting Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.parts.${parts[2].replace('custom_', '')}.__number__:${number}`);
1647
- await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').createContext('parts').createContext(parts[2].replace('custom_', '')).set('__number__', number);
1648
- }
1649
- else if (parts.length === 3 && parts[2].startsWith('unique_')) {
1650
- const device = this.devices.get(parts[2].replace('unique_', ''));
1651
- if (device && device.deviceName && device.maybeNumber) {
1652
- this.log.debug(`Converting Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.parts.${device.deviceName.replace(/[ .]/g, '')}.__number__:${device.maybeNumber}`);
1653
- await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').createContext('parts').createContext(device.deviceName.replace(/[ .]/g, '')).set('__number__', device.maybeNumber);
1654
- }
1655
- }
1656
- }
1657
- await nodeStorage.createContext('persist').set('converted', true);
1658
- await nodeStorage.createContext('persist').set('deviceName', await context.get('deviceName'));
1659
- await nodeStorage.createContext('persist').set('deviceType', await context.get('deviceType'));
1660
- await nodeStorage.createContext('persist').set('vendorId', await context.get('vendorId'));
1661
- await nodeStorage.createContext('persist').set('vendorName', await context.get('vendorName'));
1662
- await nodeStorage.createContext('persist').set('productId', await context.get('productId'));
1663
- await nodeStorage.createContext('persist').set('productName', await context.get('productName'));
1664
- await nodeStorage.createContext('persist').set('nodeLabel', await context.get('nodeLabel'));
1665
- await nodeStorage.createContext('persist').set('productLabel', await context.get('productLabel'));
1666
- await nodeStorage.createContext('persist').set('serialNumber', 'SN' + (await context.get('serialNumber')));
1667
- await nodeStorage.createContext('persist').set('uniqueId', await context.get('uniqueId'));
1668
- await nodeStorage.createContext('persist').set('softwareVersion', await context.get('softwareVersion'));
1669
- await nodeStorage.createContext('persist').set('softwareVersionString', await context.get('softwareVersionString'));
1670
- await nodeStorage.createContext('persist').set('hardwareVersion', await context.get('hardwareVersion'));
1671
- await nodeStorage.createContext('persist').set('hardwareVersionString', await context.get('hardwareVersionString'));
1672
- await context.set('converted', true);
1673
- this.log.notice(`Matter storage converted to Matterbridge edge for ${plg}${pluginName}${nt}`);
1658
+ await nodeStorage.createContext('persist').set('converted', true);
1659
+ await nodeStorage.createContext('persist').set('deviceName', await context.get('deviceName'));
1660
+ await nodeStorage.createContext('persist').set('deviceType', await context.get('deviceType'));
1661
+ await nodeStorage.createContext('persist').set('vendorId', await context.get('vendorId'));
1662
+ await nodeStorage.createContext('persist').set('vendorName', await context.get('vendorName'));
1663
+ await nodeStorage.createContext('persist').set('productId', await context.get('productId'));
1664
+ await nodeStorage.createContext('persist').set('productName', await context.get('productName'));
1665
+ await nodeStorage.createContext('persist').set('nodeLabel', await context.get('nodeLabel'));
1666
+ await nodeStorage.createContext('persist').set('productLabel', await context.get('productLabel'));
1667
+ await nodeStorage.createContext('persist').set('serialNumber', 'SN' + (await context.get('serialNumber')));
1668
+ await nodeStorage.createContext('persist').set('uniqueId', await context.get('uniqueId'));
1669
+ await nodeStorage.createContext('persist').set('softwareVersion', await context.get('softwareVersion'));
1670
+ await nodeStorage.createContext('persist').set('softwareVersionString', await context.get('softwareVersionString'));
1671
+ await nodeStorage.createContext('persist').set('hardwareVersion', await context.get('hardwareVersion'));
1672
+ await nodeStorage.createContext('persist').set('hardwareVersionString', await context.get('hardwareVersionString'));
1673
+ await context.set('converted', true);
1674
+ this.log.notice(`Matter storage converted to Matterbridge edge for ${plg}${pluginName}${nt}`);
1675
+ this.log.notice(`If you want to try out matterbridge edge (beta) add -edge to the command line.`);
1676
+ }
1677
+ catch (error) {
1678
+ this.log.error(`convertStorage error converting matter storage to Matterbridge edge for ${plg}${pluginName}${er}:`, error);
1679
+ }
1674
1680
  }
1675
1681
  async backupMatterStorage(storageName, backupName) {
1676
1682
  try {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "1.6.8-dev.7",
3
+ "version": "1.6.8-dev.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "1.6.8-dev.7",
9
+ "version": "1.6.8-dev.8",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.11.9",
@@ -1503,9 +1503,9 @@
1503
1503
  }
1504
1504
  },
1505
1505
  "node_modules/readable-stream": {
1506
- "version": "4.5.2",
1507
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
1508
- "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
1506
+ "version": "4.6.0",
1507
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.6.0.tgz",
1508
+ "integrity": "sha512-cbAdYt0VcnpN2Bekq7PU+k363ZRsPwJoEEJOEtSJQlJXzwaxt3FIo/uL+KeDSGIjJqtkwyge4KQgD2S2kd+CQw==",
1509
1509
  "license": "MIT",
1510
1510
  "dependencies": {
1511
1511
  "abort-controller": "^3.0.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "1.6.8-dev.7",
3
+ "version": "1.6.8-dev.8",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",