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 +2 -1
- package/dist/matterbridge.js +48 -20
- package/dist/matterbridgePlatform.js +4 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
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.
|
|
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
|
|
package/dist/matterbridge.js
CHANGED
|
@@ -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(
|
|
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(
|
|
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
|
|
1643
|
-
|
|
1644
|
-
|
|
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.
|
|
1654
|
-
await nodeStorage.createContext('root').createContext('parts').createContext(
|
|
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.
|
|
1660
|
-
await nodeStorage.createContext('root').createContext('parts').createContext(
|
|
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.
|
|
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(
|
|
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.
|
|
1682
|
-
await nodeStorage.createContext('root').createContext('parts').createContext(
|
|
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.
|
|
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(
|
|
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
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge",
|
|
3
|
-
"version": "1.6.8-dev.
|
|
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.
|
|
9
|
+
"version": "1.6.8-dev.11",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@matter/main": "0.11.9",
|