matterbridge 1.6.8-dev.10 → 1.6.8-dev.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
@@ -13,12 +13,13 @@ 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.10] - 2024-12-21
16
+ ## [1.6.8-dev.11] - 2024-12-23
17
17
 
18
18
  ### Added
19
19
 
20
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
  - [storage]: Added conversion for child endpoint numbers.
22
+ - [storage]: Added conversion for childbridge mode too.
22
23
  - [package]: Update README.md and README-SERVICE.md to include instructions for using SSL on port 443.
23
24
  - [platform]: Added checkEndpointNumbers() to detect endpoint numbers changes.
24
25
 
@@ -464,7 +464,13 @@ export class Matterbridge extends EventEmitter {
464
464
  await fs.unlink(path.join(this.matterbridgeDirectory, this.matterStorageName));
465
465
  }
466
466
  catch (err) {
467
- this.log.error(`Error deleting storage: ${err}`);
467
+ this.log.error(`Error deleting matter storage: ${err}`);
468
+ }
469
+ try {
470
+ await fs.rm(path.join(this.matterbridgeDirectory, this.nodeStorageName.replace('storage', 'matterstorage')), { recursive: true });
471
+ }
472
+ catch (err) {
473
+ this.log.error(`Error removing matter storage directory: ${err}`);
468
474
  }
469
475
  try {
470
476
  await fs.rm(path.join(this.matterbridgeDirectory, this.nodeStorageName), { recursive: true });
@@ -963,6 +969,18 @@ export class Matterbridge extends EventEmitter {
963
969
  this.log.debug(`Plugin ${plg}${plugin.name}${db} reachability timeout cleared`);
964
970
  }
965
971
  }
972
+ if (!hasParameter('nostorageconversion') && this.edge === false && this.matterbridgeContext && ['updating...', 'restarting...', 'shutting down...'].includes(message)) {
973
+ if (this.bridgeMode === 'bridge') {
974
+ await this.convertStorage(this.matterbridgeContext, 'Matterbridge');
975
+ }
976
+ else if (this.bridgeMode === 'childbridge') {
977
+ for (const plugin of this.plugins) {
978
+ if (plugin.storageContext) {
979
+ await this.convertStorage(plugin.storageContext, plugin.name);
980
+ }
981
+ }
982
+ }
983
+ }
966
984
  if (this.httpServer) {
967
985
  this.httpServer.close();
968
986
  this.httpServer.removeAllListeners();
@@ -996,9 +1014,6 @@ export class Matterbridge extends EventEmitter {
996
1014
  });
997
1015
  this.webSocketServer = undefined;
998
1016
  }
999
- if (!hasParameter('nostorageconversion') && this.edge === false && this.matterbridgeContext && ['updating...', 'restarting...', 'shutting down...'].includes(message)) {
1000
- await this.convertStorage(this.matterbridgeContext, 'Mattebridge');
1001
- }
1002
1017
  await this.stopMatterServer();
1003
1018
  await this.stopMatterStorage();
1004
1019
  try {
@@ -1555,10 +1570,12 @@ export class Matterbridge extends EventEmitter {
1555
1570
  await this.matterbridgeContext.set('discriminator', this.discriminator);
1556
1571
  }
1557
1572
  async convertStorage(context, pluginName) {
1573
+ if (this.edge !== false)
1574
+ return;
1558
1575
  try {
1559
1576
  const storageService = Environment.default.get(StorageService);
1560
1577
  Environment.default.vars.set('path.root', path.join(this.matterbridgeDirectory, 'matterstorage' + (this.profile ? '.' + this.profile : '')));
1561
- const nodeStorage = await storageService.open('Matterbridge');
1578
+ const nodeStorage = await storageService.open(pluginName);
1562
1579
  if ((await nodeStorage.createContext('root').createContext('generalDiagnostics').get('rebootCount', -1)) >= 0) {
1563
1580
  this.log.info(`Matter node storage already converted to Matterbridge edge for ${plg}${pluginName}${nf}`);
1564
1581
  return;
@@ -1603,7 +1620,7 @@ export class Matterbridge extends EventEmitter {
1603
1620
  label: fabric.label,
1604
1621
  });
1605
1622
  nocArray.push({ noc: fabric.operationalCert, icac: null, fabricIndex: fabric.fabricIndex });
1606
- trcArray.push('{\"__object__\":\"Uint8Array\",\"__value__\":\"' + Buffer.from(fabric.rootCert).toString('hex') + '\"}');
1623
+ trcArray.push(fabric.rootCert);
1607
1624
  this.log.info(`- updating ACL for fabricIndex ${fabric.fabricIndex}:`, fabric.scopedClusterData);
1608
1625
  const acl = fabric.scopedClusterData.get(0x1f)?.get('acl');
1609
1626
  if (acl && acl.value.length > 0) {
@@ -1621,7 +1638,6 @@ export class Matterbridge extends EventEmitter {
1621
1638
  await nodeStorage.createContext('sessions').set('resumptionRecords', await sessionManagerContext.get('resumptionRecords', []));
1622
1639
  await nodeStorage.createContext('events').set('lastEventNumber', await eventHandlerContext.get('lastEventNumber', 1));
1623
1640
  await nodeStorage.createContext('root').set('__number__', 0);
1624
- await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').set('__number__', 1);
1625
1641
  await nodeStorage.createContext('root').createContext('commissioning').set('enabled', true);
1626
1642
  await nodeStorage.createContext('root').createContext('commissioning').set('commissioned', true);
1627
1643
  await nodeStorage.createContext('root').createContext('commissioning').set('fabrics', fabricInfo);
@@ -1639,9 +1655,20 @@ export class Matterbridge extends EventEmitter {
1639
1655
  .createContext('basicInformation')
1640
1656
  .set('location', await basicInformationContext.get('location', 'XX'));
1641
1657
  await nodeStorage.createContext('root').createContext('network').set('ble', false);
1642
- await nodeStorage.createContext('root').createContext('network').set('operationalPort', 5540);
1643
- await nodeStorage.createContext('root').createContext('productDescription').set('productId', 0x8000);
1644
- await nodeStorage.createContext('root').createContext('productDescription').set('vendorId', 0xfff1);
1658
+ await nodeStorage
1659
+ .createContext('root')
1660
+ .createContext('network')
1661
+ .set('operationalPort', await context.get('port', 5540));
1662
+ await nodeStorage
1663
+ .createContext('root')
1664
+ .createContext('productDescription')
1665
+ .set('productId', await context.get('productId', 0x8000));
1666
+ await nodeStorage
1667
+ .createContext('root')
1668
+ .createContext('productDescription')
1669
+ .set('vendorId', await context.get('vendorId', 0xfff1));
1670
+ const rootDeviceName = (await context.get('deviceName', '')).replace(/[ .]/g, '');
1671
+ this.log.info(`Converting ${pluginName}.EndpointStructure to root.parts.${rootDeviceName}...`);
1645
1672
  for (const key of await endpointStructureContext.keys()) {
1646
1673
  if (key === 'nextEndpointId') {
1647
1674
  await nodeStorage.createContext('root').set('__nextNumber__', await endpointStructureContext.get(key));
@@ -1650,14 +1677,14 @@ export class Matterbridge extends EventEmitter {
1650
1677
  const parts = key.split('-');
1651
1678
  const number = await endpointStructureContext.get(key);
1652
1679
  if (parts.length === 2) {
1653
- this.log.debug(`Converting bridge Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.__number__:${CYAN}${number}${db}`);
1654
- await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').set('__number__', number);
1680
+ this.log.debug(`Converting bridge Matterbridge.EndpointStructure:${key}:${number} to root.parts.${rootDeviceName}.__number__:${CYAN}${number}${db}`);
1681
+ await nodeStorage.createContext('root').createContext('parts').createContext(rootDeviceName).set('__number__', number);
1655
1682
  }
1656
1683
  else if (parts.length === 3 && parts[2].startsWith('unique_')) {
1657
1684
  const device = this.devices.get(parts[2].replace('unique_', ''));
1658
1685
  if (device && device.deviceName && device.maybeNumber) {
1659
- this.log.debug(`Converting unique Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.parts.${device.deviceName.replace(/[ .]/g, '')}.__number__:${CYAN}${device.maybeNumber}${db}`);
1660
- await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').createContext('parts').createContext(device.deviceName.replace(/[ .]/g, '')).set('__number__', device.maybeNumber);
1686
+ this.log.debug(`Converting unique Matterbridge.EndpointStructure:${key}:${number} to root.parts.${rootDeviceName}.parts.${device.deviceName.replace(/[ .]/g, '')}.__number__:${CYAN}${device.maybeNumber}${db}`);
1687
+ await nodeStorage.createContext('root').createContext('parts').createContext(rootDeviceName).createContext('parts').createContext(device.deviceName.replace(/[ .]/g, '')).set('__number__', device.maybeNumber);
1661
1688
  }
1662
1689
  }
1663
1690
  else if (parts.length === 4 && parts[2].startsWith('unique_') && parts[3].startsWith('custom_')) {
@@ -1665,11 +1692,11 @@ export class Matterbridge extends EventEmitter {
1665
1692
  if (device && device.deviceName && device.maybeNumber) {
1666
1693
  const childEndpointName = parts[3].replace('custom_', '');
1667
1694
  const childEndpoint = device.getChildEndpointByName(childEndpointName);
1668
- this.log.debug(`Converting unique Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.parts.${device.deviceName.replace(/[ .]/g, '')}.parts.${parts[3].replace('custom_', '').replace(/[ .]/g, '')}.__number__:${CYAN}${childEndpoint?.number}${db}`);
1695
+ this.log.debug(`Converting unique Matterbridge.EndpointStructure:${key}:${number} to root.parts.${rootDeviceName}.parts.${device.deviceName.replace(/[ .]/g, '')}.parts.${parts[3].replace('custom_', '').replace(/[ .]/g, '')}.__number__:${CYAN}${childEndpoint?.number}${db}`);
1669
1696
  await nodeStorage
1670
1697
  .createContext('root')
1671
1698
  .createContext('parts')
1672
- .createContext('Matterbridge')
1699
+ .createContext(rootDeviceName)
1673
1700
  .createContext('parts')
1674
1701
  .createContext(device.deviceName.replace(/[ .]/g, ''))
1675
1702
  .createContext('parts')
@@ -1678,15 +1705,15 @@ export class Matterbridge extends EventEmitter {
1678
1705
  }
1679
1706
  }
1680
1707
  else if (parts.length === 3 && parts[2].startsWith('custom_')) {
1681
- this.log.debug(`Converting custom Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.parts.${parts[2].replace('custom_', '').replace(/[ .]/g, '')}.__number__:${CYAN}${number}${db}`);
1682
- await nodeStorage.createContext('root').createContext('parts').createContext('Matterbridge').createContext('parts').createContext(parts[2].replace('custom_', '').replace(/[ .]/g, '')).set('__number__', number);
1708
+ this.log.debug(`Converting custom Matterbridge.EndpointStructure:${key}:${number} to root.parts.${rootDeviceName}.parts.${parts[2].replace('custom_', '').replace(/[ .]/g, '')}.__number__:${CYAN}${number}${db}`);
1709
+ await nodeStorage.createContext('root').createContext('parts').createContext(rootDeviceName).createContext('parts').createContext(parts[2].replace('custom_', '').replace(/[ .]/g, '')).set('__number__', number);
1683
1710
  }
1684
1711
  else if (parts.length === 4 && parts[2].startsWith('custom_') && parts[3].startsWith('custom_')) {
1685
- this.log.debug(`Converting custom Matterbridge.EndpointStructure:${key}:${number} to root.parts.Matterbridge.parts.${parts[2].replace('custom_', '').replace(/[ .]/g, '')}.parts.${parts[3].replace('custom_', '').replace(/[ .]/g, '')}.__number__:${CYAN}${number}${db}`);
1712
+ this.log.debug(`Converting custom Matterbridge.EndpointStructure:${key}:${number} to root.parts.${rootDeviceName}.parts.${parts[2].replace('custom_', '').replace(/[ .]/g, '')}.parts.${parts[3].replace('custom_', '').replace(/[ .]/g, '')}.__number__:${CYAN}${number}${db}`);
1686
1713
  await nodeStorage
1687
1714
  .createContext('root')
1688
1715
  .createContext('parts')
1689
- .createContext('Matterbridge')
1716
+ .createContext(rootDeviceName)
1690
1717
  .createContext('parts')
1691
1718
  .createContext(parts[2].replace('custom_', '').replace(/[ .]/g, ''))
1692
1719
  .createContext('parts')
@@ -1712,6 +1739,7 @@ export class Matterbridge extends EventEmitter {
1712
1739
  await context.set('converted', true);
1713
1740
  this.log.notice(`Matter storage converted to Matterbridge edge for ${plg}${pluginName}${nt}`);
1714
1741
  this.log.notice(`If you want to try out matterbridge edge (beta) add -edge to the command line.`);
1742
+ this.log.notice(`All fabrics have been converted to the new storage format.`);
1715
1743
  }
1716
1744
  catch (error) {
1717
1745
  this.log.error(`convertStorage error converting matter storage to Matterbridge edge for ${plg}${pluginName}${er}:`, error);
@@ -144,8 +144,10 @@ export class MatterbridgePlatform {
144
144
  const separator = '|.|';
145
145
  const endpointMap = new Map(await context.get('endpointMap', []));
146
146
  for (const device of this.matterbridge.getDevices().filter((d) => d.plugin === this.name)) {
147
- if (device.uniqueId === undefined || device.maybeNumber === undefined)
147
+ if (device.uniqueId === undefined || device.maybeNumber === undefined) {
148
+ this.log.debug(`Not checking device ${device.deviceName} without uniqueId or maybeNumber`);
148
149
  continue;
150
+ }
149
151
  if (endpointMap.has(device.uniqueId) && endpointMap.get(device.uniqueId) !== device.maybeNumber) {
150
152
  this.log.warn(`Endpoint number for device ${CYAN}${device.uniqueId}${wr} changed from ${CYAN}${endpointMap.get(device.uniqueId)}${wr} to ${CYAN}${device.maybeNumber}${wr}`);
151
153
  endpointMap.set(device.uniqueId, device.maybeNumber);
@@ -168,6 +170,7 @@ export class MatterbridgePlatform {
168
170
  }
169
171
  }
170
172
  await context.set('endpointMap', Array.from(endpointMap.entries()));
173
+ this.log.debug('Endpoint numbers check completed.');
171
174
  return endpointMap.size;
172
175
  }
173
176
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "1.6.8-dev.10",
3
+ "version": "1.6.8-dev.11",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "1.6.8-dev.10",
9
+ "version": "1.6.8-dev.11",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.11.9",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "1.6.8-dev.10",
3
+ "version": "1.6.8-dev.11",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",