matterbridge 1.2.11 → 1.2.13
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 +33 -1
- package/README.md +31 -26
- package/dist/BridgedDeviceBasicInformationCluster.d.ts +223 -0
- package/dist/BridgedDeviceBasicInformationCluster.d.ts.map +1 -0
- package/dist/BridgedDeviceBasicInformationCluster.js +176 -0
- package/dist/BridgedDeviceBasicInformationCluster.js.map +1 -0
- package/dist/cli.js +10 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/matterbridge.d.ts +12 -0
- package/dist/matterbridge.d.ts.map +1 -1
- package/dist/matterbridge.js +232 -44
- package/dist/matterbridge.js.map +1 -1
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +1 -1
- package/dist/matterbridgeAccessoryPlatform.js.map +1 -1
- package/dist/matterbridgeDevice.d.ts +71 -6
- package/dist/matterbridgeDevice.d.ts.map +1 -1
- package/dist/matterbridgeDevice.js +50 -2
- package/dist/matterbridgeDevice.js.map +1 -1
- package/dist/matterbridgePlatform.d.ts +1 -0
- package/dist/matterbridgePlatform.d.ts.map +1 -1
- package/dist/matterbridgePlatform.js +1 -0
- package/dist/matterbridgePlatform.js.map +1 -1
- package/frontend/build/asset-manifest.json +6 -6
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/css/main.979e07d2.css +2 -0
- package/frontend/build/static/css/main.979e07d2.css.map +1 -0
- package/frontend/build/static/js/{main.60e6f24a.js → main.742e4290.js} +3 -3
- package/frontend/build/static/js/main.742e4290.js.map +1 -0
- package/package.json +2 -2
- package/frontend/build/static/css/main.1880392b.css +0 -2
- package/frontend/build/static/css/main.1880392b.css.map +0 -1
- package/frontend/build/static/js/main.60e6f24a.js.map +0 -1
- /package/frontend/build/static/js/{main.60e6f24a.js.LICENSE.txt → main.742e4290.js.LICENSE.txt} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matterbridge.d.ts","sourceRoot":"","sources":["../src/matterbridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;AAEH,OAAO,EAAE,kBAAkB,EAAgC,MAAM,yBAAyB,CAAC;AAS3F,OAAO,YAAY,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"matterbridge.d.ts","sourceRoot":"","sources":["../src/matterbridge.ts"],"names":[],"mappings":"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"}
|
package/dist/matterbridge.js
CHANGED
|
@@ -32,10 +32,9 @@ import express from 'express';
|
|
|
32
32
|
import os from 'os';
|
|
33
33
|
import path from 'path';
|
|
34
34
|
import WebSocket, { WebSocketServer } from 'ws';
|
|
35
|
+
import { BridgedDeviceBasicInformation, BridgedDeviceBasicInformationCluster } from './BridgedDeviceBasicInformationCluster.js';
|
|
35
36
|
import { CommissioningController, CommissioningServer, MatterServer } from '@project-chip/matter-node.js';
|
|
36
|
-
import { BasicInformationCluster, BooleanStateCluster,
|
|
37
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
38
|
-
BridgedDeviceBasicInformation, BridgedDeviceBasicInformationCluster, ClusterServer, GeneralCommissioning, PowerSourceCluster, ThreadNetworkDiagnosticsCluster, getClusterNameById, } from '@project-chip/matter-node.js/cluster';
|
|
37
|
+
import { BasicInformationCluster, BooleanStateCluster, ClusterServer, FixedLabelCluster, GeneralCommissioning, GeneralDiagnostics, GeneralDiagnosticsCluster, PowerSourceCluster, ThreadNetworkDiagnosticsCluster, getClusterNameById, } from '@project-chip/matter-node.js/cluster';
|
|
39
38
|
import { DeviceTypeId, VendorId } from '@project-chip/matter-node.js/datatype';
|
|
40
39
|
import { Aggregator, DeviceTypes, NodeStateInformation } from '@project-chip/matter-node.js/device';
|
|
41
40
|
import { Format, Level, Logger } from '@project-chip/matter-node.js/log';
|
|
@@ -190,7 +189,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
190
189
|
await this.showCommissioningQRCode(this.commissioningServer, this.matterbridgeContext, this.nodeContext, 'Matterbridge');
|
|
191
190
|
// Set reachability to true and trigger event after 60 seconds
|
|
192
191
|
setTimeout(() => {
|
|
193
|
-
this.log.info(
|
|
192
|
+
this.log.info(`Setting reachability to true for ${plg}Matterbridge${db}`);
|
|
194
193
|
if (this.commissioningServer)
|
|
195
194
|
this.setCommissioningServerReachability(this.commissioningServer, true);
|
|
196
195
|
if (this.matterAggregator)
|
|
@@ -367,7 +366,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
367
366
|
// Delete matter storage file
|
|
368
367
|
await fs.unlink(path.join(this.matterbridgeDirectory, 'matterbridge.json'));
|
|
369
368
|
// Delete node storage directory with its subdirectories
|
|
370
|
-
await fs.
|
|
369
|
+
await fs.rm(path.join(this.matterbridgeDirectory, 'storage'), { recursive: true });
|
|
371
370
|
this.log.info('Factory reset done! Remove all paired devices from the controllers.');
|
|
372
371
|
this.emit('shutdown');
|
|
373
372
|
process.exit(0);
|
|
@@ -611,6 +610,31 @@ export class Matterbridge extends EventEmitter {
|
|
|
611
610
|
await this.cleanup('shutting down...', false);
|
|
612
611
|
this.hasCleanupStarted = false;
|
|
613
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* Shut down the process and reset.
|
|
615
|
+
*/
|
|
616
|
+
async unregisterAndShutdownProcess() {
|
|
617
|
+
this.log.info('Unregistering all devices and shutting down...');
|
|
618
|
+
for (const plugin of this.registeredPlugins.filter((plugin) => plugin.enabled && !plugin.error)) {
|
|
619
|
+
await this.removeAllBridgedDevices(plugin.name);
|
|
620
|
+
}
|
|
621
|
+
await this.cleanup('unregistered all devices and shutting down...', false);
|
|
622
|
+
this.hasCleanupStarted = false;
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Shut down the process and reset.
|
|
626
|
+
*/
|
|
627
|
+
async shutdownProcessAndReset() {
|
|
628
|
+
await this.cleanup('shutting down with reset...', false);
|
|
629
|
+
this.hasCleanupStarted = false;
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Shut down the process and factory reset.
|
|
633
|
+
*/
|
|
634
|
+
async shutdownProcessAndFactoryReset() {
|
|
635
|
+
await this.cleanup('shutting down with factory reset...', false);
|
|
636
|
+
this.hasCleanupStarted = false;
|
|
637
|
+
}
|
|
614
638
|
/**
|
|
615
639
|
* Cleans up the Matterbridge instance.
|
|
616
640
|
* @param message - The cleanup message.
|
|
@@ -628,11 +652,11 @@ export class Matterbridge extends EventEmitter {
|
|
|
628
652
|
for (const plugin of this.registeredPlugins) {
|
|
629
653
|
if (!plugin.enabled || plugin.error)
|
|
630
654
|
continue;
|
|
631
|
-
this.log.info(
|
|
655
|
+
this.log.info(`Shutting down plugin ${plg}${plugin.name}${nf}`);
|
|
632
656
|
if (plugin.platform) {
|
|
633
657
|
try {
|
|
634
658
|
await plugin.platform.onShutdown('Matterbridge is closing: ' + message);
|
|
635
|
-
await this.savePluginConfig(plugin);
|
|
659
|
+
// await this.savePluginConfig(plugin);
|
|
636
660
|
}
|
|
637
661
|
catch (error) {
|
|
638
662
|
this.log.error(`Plugin ${plg}${plugin.name}${er} shutting down error: ${error}`);
|
|
@@ -710,7 +734,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
710
734
|
});
|
|
711
735
|
this.webSocketServer = undefined;
|
|
712
736
|
}
|
|
713
|
-
|
|
737
|
+
setTimeout(async () => {
|
|
714
738
|
// Closing matter
|
|
715
739
|
await this.stopMatter();
|
|
716
740
|
// Closing storage
|
|
@@ -740,7 +764,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
740
764
|
this.registeredPlugins = [];
|
|
741
765
|
this.registeredDevices = [];
|
|
742
766
|
this.log.info('Waiting for matter to deliver last messages...');
|
|
743
|
-
|
|
767
|
+
setTimeout(async () => {
|
|
744
768
|
if (restart) {
|
|
745
769
|
if (message === 'updating...') {
|
|
746
770
|
this.log.info('Cleanup completed. Updating...');
|
|
@@ -754,14 +778,27 @@ export class Matterbridge extends EventEmitter {
|
|
|
754
778
|
}
|
|
755
779
|
}
|
|
756
780
|
else {
|
|
781
|
+
if (message === 'shutting down with reset...') {
|
|
782
|
+
// Delete matter storage file
|
|
783
|
+
this.log.info('Resetting Matterbridge commissioning information...');
|
|
784
|
+
await fs.unlink(path.join(this.matterbridgeDirectory, 'matterbridge.json'));
|
|
785
|
+
this.log.info('Reset done! Remove all paired devices from the controllers.');
|
|
786
|
+
}
|
|
787
|
+
if (message === 'shutting down with factory reset...') {
|
|
788
|
+
// Delete matter storage file
|
|
789
|
+
this.log.info('Resetting Matterbridge commissioning information...');
|
|
790
|
+
await fs.unlink(path.join(this.matterbridgeDirectory, 'matterbridge.json'));
|
|
791
|
+
// Delete node storage directory with its subdirectories
|
|
792
|
+
this.log.info('Resetting Matterbridge storage...');
|
|
793
|
+
await fs.rm(path.join(this.matterbridgeDirectory, 'storage'), { recursive: true });
|
|
794
|
+
this.log.info('Factory reset done! Remove all paired devices from the controllers.');
|
|
795
|
+
}
|
|
757
796
|
this.log.info('Cleanup completed. Shutting down...');
|
|
758
797
|
Matterbridge.instance = undefined;
|
|
759
798
|
this.emit('shutdown');
|
|
760
799
|
}
|
|
761
800
|
}, 2 * 1000);
|
|
762
|
-
//cleanupTimeout2.unref();
|
|
763
801
|
}, 3 * 1000);
|
|
764
|
-
//cleanupTimeout1.unref();
|
|
765
802
|
}
|
|
766
803
|
}
|
|
767
804
|
/**
|
|
@@ -911,7 +948,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
911
948
|
async removeAllBridgedDevices(pluginName) {
|
|
912
949
|
const plugin = this.findPlugin(pluginName);
|
|
913
950
|
if (this.bridgeMode === 'childbridge' && plugin?.type === 'AccessoryPlatform') {
|
|
914
|
-
this.log.info(`Removing devices for plugin ${plg}${pluginName}${nf}
|
|
951
|
+
this.log.info(`Removing devices for plugin ${plg}${pluginName}${nf} type AccessoryPlatform is not supported in childbridge mode`);
|
|
915
952
|
return;
|
|
916
953
|
}
|
|
917
954
|
const devicesToRemove = [];
|
|
@@ -1230,6 +1267,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1230
1267
|
.then(() => {
|
|
1231
1268
|
plugin.configured = true;
|
|
1232
1269
|
this.log.info(`Configured plugin ${plg}${plugin.name}${db} type ${typ}${plugin.type}${db}`);
|
|
1270
|
+
this.savePluginConfig(plugin);
|
|
1233
1271
|
return Promise.resolve();
|
|
1234
1272
|
})
|
|
1235
1273
|
.catch((err) => {
|
|
@@ -1261,7 +1299,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1261
1299
|
this.log.error(`Plugin ${plg}${plugin.name}${er} already loaded`);
|
|
1262
1300
|
return Promise.resolve(plugin.platform);
|
|
1263
1301
|
}
|
|
1264
|
-
this.log.info(`Loading plugin ${plg}${plugin.name}${
|
|
1302
|
+
this.log.info(`Loading plugin ${plg}${plugin.name}${nf} type ${typ}${plugin.type}${nf}`);
|
|
1265
1303
|
try {
|
|
1266
1304
|
// Load the package.json of the plugin
|
|
1267
1305
|
const packageJson = JSON.parse(await fs.readFile(plugin.path, 'utf8'));
|
|
@@ -1280,6 +1318,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1280
1318
|
const platform = pluginInstance.default(this, log, config);
|
|
1281
1319
|
platform.name = packageJson.name;
|
|
1282
1320
|
platform.config = config;
|
|
1321
|
+
platform.version = packageJson.version;
|
|
1283
1322
|
plugin.name = packageJson.name;
|
|
1284
1323
|
plugin.description = packageJson.description;
|
|
1285
1324
|
plugin.version = packageJson.version;
|
|
@@ -1290,7 +1329,19 @@ export class Matterbridge extends EventEmitter {
|
|
|
1290
1329
|
plugin.registeredDevices = 0;
|
|
1291
1330
|
plugin.addedDevices = 0;
|
|
1292
1331
|
await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
|
|
1293
|
-
this.
|
|
1332
|
+
this.getLatestVersion(plugin.name)
|
|
1333
|
+
.then(async (latestVersion) => {
|
|
1334
|
+
plugin.latestVersion = latestVersion;
|
|
1335
|
+
await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
|
|
1336
|
+
if (plugin.version !== latestVersion)
|
|
1337
|
+
this.log.warn(`The plugin ${plg}${plugin.name}${wr} is out of date. Current version: ${plugin.version}, Latest version: ${latestVersion}`);
|
|
1338
|
+
else
|
|
1339
|
+
this.log.info(`The plugin ${plg}${plugin.name}${nf} is up to date. Current version: ${plugin.version}, Latest version: ${latestVersion}`);
|
|
1340
|
+
})
|
|
1341
|
+
.catch((error) => {
|
|
1342
|
+
this.log.error(`Error getting ${plugin.name} latest version: ${error}`);
|
|
1343
|
+
});
|
|
1344
|
+
this.log.info(`Loaded plugin ${plg}${plugin.name}${nf} type ${typ}${platform.type} ${db}(entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
|
|
1294
1345
|
if (start)
|
|
1295
1346
|
this.startPlugin(plugin, message); // No await do it asyncronously
|
|
1296
1347
|
return Promise.resolve(platform);
|
|
@@ -1532,9 +1583,10 @@ export class Matterbridge extends EventEmitter {
|
|
|
1532
1583
|
await this.startMatterServer();
|
|
1533
1584
|
this.log.info('Matter server started');
|
|
1534
1585
|
await this.showCommissioningQRCode(this.commissioningServer, this.matterbridgeContext, this.nodeContext, 'Matterbridge');
|
|
1586
|
+
// logEndpoint(this.commissioningServer.getRootEndpoint());
|
|
1535
1587
|
//if (hasParameter('advertise')) await this.commissioningServer.advertise();
|
|
1536
1588
|
setTimeout(() => {
|
|
1537
|
-
this.log.info(
|
|
1589
|
+
this.log.info(`Setting reachability to true for ${plg}Matterbridge${db}`);
|
|
1538
1590
|
if (this.commissioningServer)
|
|
1539
1591
|
this.setCommissioningServerReachability(this.commissioningServer, true);
|
|
1540
1592
|
if (this.matterAggregator)
|
|
@@ -1637,7 +1689,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1637
1689
|
}
|
|
1638
1690
|
await this.showCommissioningQRCode(plugin.commissioningServer, plugin.storageContext, plugin.nodeContext, plugin.name);
|
|
1639
1691
|
// Setting reachability to true
|
|
1640
|
-
this.log.info(
|
|
1692
|
+
this.log.info(`Setting reachability to true for ${plg}${plugin.name}${db}`);
|
|
1641
1693
|
if (plugin.commissioningServer)
|
|
1642
1694
|
this.setCommissioningServerReachability(plugin.commissioningServer, true);
|
|
1643
1695
|
if (plugin.type === 'AccessoryPlatform' && plugin.device)
|
|
@@ -1737,14 +1789,14 @@ export class Matterbridge extends EventEmitter {
|
|
|
1737
1789
|
if (!commissioningServer || !storageContext || !pluginName)
|
|
1738
1790
|
return;
|
|
1739
1791
|
if (!commissioningServer.isCommissioned()) {
|
|
1740
|
-
this.log.info(`***The commissioning server on port ${commissioningServer.getPort()} for ${plg}${pluginName}${nf} is not commissioned. Pair it scanning the QR code ...`);
|
|
1741
1792
|
const { qrPairingCode, manualPairingCode } = commissioningServer.getPairingCode();
|
|
1742
1793
|
await storageContext.set('qrPairingCode', qrPairingCode);
|
|
1743
1794
|
await storageContext.set('manualPairingCode', manualPairingCode);
|
|
1744
1795
|
await nodeContext.set('qrPairingCode', qrPairingCode);
|
|
1745
1796
|
await nodeContext.set('manualPairingCode', manualPairingCode);
|
|
1746
1797
|
const QrCode = new QrCodeSchema();
|
|
1747
|
-
this.log.info(
|
|
1798
|
+
this.log.info(`***The commissioning server on port ${commissioningServer.getPort()} for ${plg}${pluginName}${nf} is not commissioned. Pair it scanning the QR code:\n\n` +
|
|
1799
|
+
`${QrCode.encode(qrPairingCode)}\n${plg}${pluginName}${nf}\n\nqrPairingCode: ${qrPairingCode}\n\nManual pairing code: ${manualPairingCode}\n`);
|
|
1748
1800
|
if (pluginName !== 'Matterbridge') {
|
|
1749
1801
|
const plugin = this.findPlugin(pluginName);
|
|
1750
1802
|
if (plugin) {
|
|
@@ -1756,7 +1808,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1756
1808
|
await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
|
|
1757
1809
|
}
|
|
1758
1810
|
else {
|
|
1759
|
-
this.log.info(
|
|
1811
|
+
this.log.info(`*The commissioning server on port ${commissioningServer.getPort()} for ${plg}${pluginName}${nf} is already commissioned . Waiting for controllers to connect ...`);
|
|
1760
1812
|
if (pluginName !== 'Matterbridge') {
|
|
1761
1813
|
const plugin = this.findPlugin(pluginName);
|
|
1762
1814
|
if (plugin) {
|
|
@@ -1805,7 +1857,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1805
1857
|
if (basicInformationCluster && basicInformationCluster.triggerReachableChangedEvent)
|
|
1806
1858
|
basicInformationCluster.triggerReachableChangedEvent({ reachableNewValue: reachable });
|
|
1807
1859
|
matterAggregator.getBridgedDevices().forEach((device) => {
|
|
1808
|
-
this.log.debug(
|
|
1860
|
+
this.log.debug(`Setting reachability to true for bridged device: ${dev}${device.name}${nf}`);
|
|
1809
1861
|
device.getClusterServer(BridgedDeviceBasicInformationCluster)?.setReachableAttribute(reachable);
|
|
1810
1862
|
device.getClusterServer(BridgedDeviceBasicInformationCluster)?.triggerReachableChangedEvent({ reachableNewValue: reachable });
|
|
1811
1863
|
});
|
|
@@ -1831,6 +1883,38 @@ export class Matterbridge extends EventEmitter {
|
|
|
1831
1883
|
* @returns {CommissioningServer} The created commissioning server.
|
|
1832
1884
|
*/
|
|
1833
1885
|
async createCommisioningServer(context, pluginName) {
|
|
1886
|
+
const getVendorIdName = (vendorId) => {
|
|
1887
|
+
if (!vendorId)
|
|
1888
|
+
return '';
|
|
1889
|
+
let vendorName = '';
|
|
1890
|
+
switch (vendorId) {
|
|
1891
|
+
case 4937:
|
|
1892
|
+
vendorName = '(AppleHome)';
|
|
1893
|
+
break;
|
|
1894
|
+
case 4996:
|
|
1895
|
+
vendorName = '(AppleKeyChain)';
|
|
1896
|
+
break;
|
|
1897
|
+
case 4362:
|
|
1898
|
+
vendorName = '(SmartThings)';
|
|
1899
|
+
break;
|
|
1900
|
+
case 4939:
|
|
1901
|
+
vendorName = '(HomeAssistant)';
|
|
1902
|
+
break;
|
|
1903
|
+
case 24582:
|
|
1904
|
+
vendorName = '(GoogleHome)';
|
|
1905
|
+
break;
|
|
1906
|
+
case 4701:
|
|
1907
|
+
vendorName = '(Tuya)';
|
|
1908
|
+
break;
|
|
1909
|
+
case 4742:
|
|
1910
|
+
vendorName = '(eWeLink)';
|
|
1911
|
+
break;
|
|
1912
|
+
default:
|
|
1913
|
+
vendorName = '(unknown)';
|
|
1914
|
+
break;
|
|
1915
|
+
}
|
|
1916
|
+
return vendorName;
|
|
1917
|
+
};
|
|
1834
1918
|
this.log.debug(`Creating matter commissioning server for plugin ${plg}${pluginName}${db}`);
|
|
1835
1919
|
const deviceName = await context.get('deviceName');
|
|
1836
1920
|
const deviceType = await context.get('deviceType');
|
|
@@ -1873,16 +1957,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
1873
1957
|
const info = commissioningServer.getActiveSessionInformation(fabricIndex);
|
|
1874
1958
|
let connected = false;
|
|
1875
1959
|
info.forEach((session) => {
|
|
1876
|
-
this.log.info(
|
|
1960
|
+
this.log.info(`*Active session changed on fabric ${fabricIndex} ${session.fabric?.rootVendorId}${getVendorIdName(session.fabric?.rootVendorId)}/${session.fabric?.label} for ${plg}${pluginName}${nf}`, debugStringify(session));
|
|
1877
1961
|
if (session.isPeerActive === true && session.secure === true && session.numberOfActiveSubscriptions >= 1) {
|
|
1878
|
-
|
|
1879
|
-
if (session.fabric?.rootVendorId === 4937)
|
|
1880
|
-
controllerName = 'AppleHome';
|
|
1881
|
-
if (session.fabric?.rootVendorId === 4362)
|
|
1882
|
-
controllerName = 'SmartThings';
|
|
1883
|
-
if (session.fabric?.rootVendorId === 4939)
|
|
1884
|
-
controllerName = 'HomeAssistant';
|
|
1885
|
-
this.log.info(`***Controller ${session.fabric?.rootVendorId}${controllerName !== '' ? '(' + controllerName + ')' : ''}/${session.fabric?.label} connected to ${plg}${pluginName}${nf} on session ${session.name}`);
|
|
1962
|
+
this.log.info(`*Controller ${session.fabric?.rootVendorId}${getVendorIdName(session.fabric?.rootVendorId)}/${session.fabric?.label} connected to ${plg}${pluginName}${nf} on session ${session.name}`);
|
|
1886
1963
|
connected = true;
|
|
1887
1964
|
}
|
|
1888
1965
|
});
|
|
@@ -1938,15 +2015,15 @@ export class Matterbridge extends EventEmitter {
|
|
|
1938
2015
|
}
|
|
1939
2016
|
Logger.defaultLogLevel = this.debugEnabled ? Level.DEBUG : Level.INFO;
|
|
1940
2017
|
}
|
|
1941
|
-
//logEndpoint(commissioningServer.getRootEndpoint());
|
|
2018
|
+
// logEndpoint(commissioningServer.getRootEndpoint());
|
|
1942
2019
|
}, 2000);
|
|
1943
2020
|
}
|
|
1944
2021
|
},
|
|
1945
2022
|
commissioningChangedCallback: async (fabricIndex) => {
|
|
1946
2023
|
const info = commissioningServer.getCommissionedFabricInformation(fabricIndex);
|
|
1947
|
-
this.log.debug(
|
|
2024
|
+
this.log.debug(`*Commissioning changed on fabric ${fabricIndex} for ${plg}${pluginName}${nf}`, debugStringify(info));
|
|
1948
2025
|
if (info.length === 0) {
|
|
1949
|
-
this.log.warn(
|
|
2026
|
+
this.log.warn(`*Commissioning removed from fabric ${fabricIndex} for ${plg}${pluginName}${wr}. Resetting the commissioning server ...`);
|
|
1950
2027
|
await commissioningServer.factoryReset();
|
|
1951
2028
|
if (pluginName === 'Matterbridge') {
|
|
1952
2029
|
await this.matterbridgeContext?.clearAll();
|
|
@@ -1961,10 +2038,27 @@ export class Matterbridge extends EventEmitter {
|
|
|
1961
2038
|
}
|
|
1962
2039
|
}
|
|
1963
2040
|
}
|
|
1964
|
-
this.log.warn(
|
|
2041
|
+
this.log.warn(`*Restart to activate the pairing for ${plg}${pluginName}${wr}`);
|
|
1965
2042
|
}
|
|
1966
2043
|
},
|
|
1967
2044
|
});
|
|
2045
|
+
const gdcCluster = commissioningServer.getRootClusterServer(GeneralDiagnosticsCluster);
|
|
2046
|
+
if (gdcCluster) {
|
|
2047
|
+
gdcCluster.setNetworkInterfacesAttribute([
|
|
2048
|
+
{
|
|
2049
|
+
name: 'eth0',
|
|
2050
|
+
isOperational: true,
|
|
2051
|
+
offPremiseServicesReachableIPv4: null,
|
|
2052
|
+
offPremiseServicesReachableIPv6: null,
|
|
2053
|
+
hardwareAddress: Uint8Array.fromString('00000000'),
|
|
2054
|
+
iPv4Addresses: [Uint8Array.fromString('0000')],
|
|
2055
|
+
iPv6Addresses: [Uint8Array.fromString('0000000000000000')],
|
|
2056
|
+
type: GeneralDiagnostics.InterfaceType.Ethernet,
|
|
2057
|
+
},
|
|
2058
|
+
]);
|
|
2059
|
+
}
|
|
2060
|
+
else
|
|
2061
|
+
this.log.warn(`*GeneralDiagnosticsCluster not found for ${plg}${pluginName}${wr}`);
|
|
1968
2062
|
commissioningServer.addCommandHandler('testEventTrigger', async ({ request: { enableKey, eventTrigger } }) => this.log.info(`testEventTrigger called on GeneralDiagnostic cluster: ${enableKey} ${eventTrigger}`));
|
|
1969
2063
|
return commissioningServer;
|
|
1970
2064
|
}
|
|
@@ -1991,7 +2085,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1991
2085
|
const matterAggregator = new Aggregator();
|
|
1992
2086
|
matterAggregator.addClusterServer(ClusterServer(BasicInformationCluster, {
|
|
1993
2087
|
dataModelRevision: 1,
|
|
1994
|
-
location: '
|
|
2088
|
+
location: 'FR',
|
|
1995
2089
|
vendorId: VendorId(0xfff1),
|
|
1996
2090
|
vendorName: 'Matterbridge',
|
|
1997
2091
|
productId: 0x8000,
|
|
@@ -2228,6 +2322,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2228
2322
|
type: plugin.type,
|
|
2229
2323
|
name: plugin.name,
|
|
2230
2324
|
version: plugin.version,
|
|
2325
|
+
latestVersion: plugin.latestVersion,
|
|
2231
2326
|
description: plugin.description,
|
|
2232
2327
|
author: plugin.author,
|
|
2233
2328
|
enabled: plugin.enabled,
|
|
@@ -2522,6 +2617,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2522
2617
|
//console.log(error);
|
|
2523
2618
|
}
|
|
2524
2619
|
data.push({
|
|
2620
|
+
endpoint: registeredDevice.device.number ? registeredDevice.device.number.toString() : '...',
|
|
2525
2621
|
clusterName: clusterServer.name,
|
|
2526
2622
|
clusterId: '0x' + clusterServer.id.toString(16).padStart(2, '0'),
|
|
2527
2623
|
attributeName: key,
|
|
@@ -2530,6 +2626,37 @@ export class Matterbridge extends EventEmitter {
|
|
|
2530
2626
|
});
|
|
2531
2627
|
});
|
|
2532
2628
|
});
|
|
2629
|
+
registeredDevice.device.getChildEndpoints().forEach((childEndpoint) => {
|
|
2630
|
+
const name = registeredDevice.device.getChildEndpointName(childEndpoint);
|
|
2631
|
+
const clusterServers = childEndpoint.getAllClusterServers();
|
|
2632
|
+
clusterServers.forEach((clusterServer) => {
|
|
2633
|
+
Object.entries(clusterServer.attributes).forEach(([key, value]) => {
|
|
2634
|
+
if (clusterServer.name === 'EveHistory')
|
|
2635
|
+
return;
|
|
2636
|
+
//this.log.debug(`***--clusterServer: ${clusterServer.name}(${clusterServer.id}) attribute:${key}(${value.id}) ${value.isFixed} ${value.isWritable} ${value.isWritable}`);
|
|
2637
|
+
let attributeValue;
|
|
2638
|
+
try {
|
|
2639
|
+
if (typeof value.getLocal() === 'object')
|
|
2640
|
+
attributeValue = stringify(value.getLocal());
|
|
2641
|
+
else
|
|
2642
|
+
attributeValue = value.getLocal().toString();
|
|
2643
|
+
}
|
|
2644
|
+
catch (error) {
|
|
2645
|
+
attributeValue = 'Unavailable';
|
|
2646
|
+
this.log.debug(`GetLocal error ${error} in clusterServer: ${clusterServer.name}(${clusterServer.id}) attribute: ${key}(${value.id})`);
|
|
2647
|
+
//console.log(error);
|
|
2648
|
+
}
|
|
2649
|
+
data.push({
|
|
2650
|
+
endpoint: (childEndpoint.number ? childEndpoint.number.toString() : '...') + (name ? ' (' + name + ')' : ''),
|
|
2651
|
+
clusterName: clusterServer.name,
|
|
2652
|
+
clusterId: '0x' + clusterServer.id.toString(16).padStart(2, '0'),
|
|
2653
|
+
attributeName: key,
|
|
2654
|
+
attributeId: '0x' + value.id.toString(16).padStart(2, '0'),
|
|
2655
|
+
attributeValue,
|
|
2656
|
+
});
|
|
2657
|
+
});
|
|
2658
|
+
});
|
|
2659
|
+
});
|
|
2533
2660
|
}
|
|
2534
2661
|
});
|
|
2535
2662
|
res.json(data);
|
|
@@ -2567,17 +2694,34 @@ export class Matterbridge extends EventEmitter {
|
|
|
2567
2694
|
this.debugEnabled = false;
|
|
2568
2695
|
Logger.defaultLogLevel = Level.WARN;
|
|
2569
2696
|
}
|
|
2697
|
+
else if (param === 'Error') {
|
|
2698
|
+
this.log.setLogDebug(false);
|
|
2699
|
+
this.debugEnabled = false;
|
|
2700
|
+
Logger.defaultLogLevel = Level.ERROR;
|
|
2701
|
+
}
|
|
2570
2702
|
this.registeredPlugins.forEach((plugin) => {
|
|
2571
2703
|
plugin.platform?.log.setLogDebug(this.debugEnabled);
|
|
2572
2704
|
});
|
|
2573
2705
|
}
|
|
2574
|
-
// Handle the command
|
|
2706
|
+
// Handle the command reset from Settings
|
|
2707
|
+
if (command === 'unregister') {
|
|
2708
|
+
await this.unregisterAndShutdownProcess();
|
|
2709
|
+
}
|
|
2710
|
+
// Handle the command reset from Settings
|
|
2711
|
+
if (command === 'reset') {
|
|
2712
|
+
this.shutdownProcessAndReset(); // No await do it asyncronously
|
|
2713
|
+
}
|
|
2714
|
+
// Handle the command factoryreset from Settings
|
|
2715
|
+
if (command === 'factoryreset') {
|
|
2716
|
+
this.shutdownProcessAndFactoryReset(); // No await do it asyncronously
|
|
2717
|
+
}
|
|
2718
|
+
// Handle the command restart from Header
|
|
2575
2719
|
if (command === 'shutdown') {
|
|
2576
|
-
this.shutdownProcess();
|
|
2720
|
+
this.shutdownProcess(); // No await do it asyncronously
|
|
2577
2721
|
}
|
|
2578
2722
|
// Handle the command restart from Header
|
|
2579
2723
|
if (command === 'restart') {
|
|
2580
|
-
this.restartProcess();
|
|
2724
|
+
this.restartProcess(); // No await do it asyncronously
|
|
2581
2725
|
}
|
|
2582
2726
|
// Handle the command update from Header
|
|
2583
2727
|
if (command === 'update') {
|
|
@@ -2608,7 +2752,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2608
2752
|
}
|
|
2609
2753
|
}
|
|
2610
2754
|
// Handle the command addplugin from Home
|
|
2611
|
-
if (command === 'addplugin') {
|
|
2755
|
+
if (command === 'addplugin' || command === 'installplugin') {
|
|
2612
2756
|
param = param.replace(/\*/g, '\\');
|
|
2613
2757
|
if (this.registeredPlugins.find((plugin) => plugin.name === param)) {
|
|
2614
2758
|
this.log.warn(`Plugin ${plg}${param}${wr} already added to matterbridge`);
|
|
@@ -2647,7 +2791,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2647
2791
|
if (index !== -1) {
|
|
2648
2792
|
if (this.registeredPlugins[index].platform) {
|
|
2649
2793
|
await this.registeredPlugins[index].platform?.onShutdown('The plugin has been removed.');
|
|
2650
|
-
await this.savePluginConfig(this.registeredPlugins[index]);
|
|
2794
|
+
// await this.savePluginConfig(this.registeredPlugins[index]);
|
|
2651
2795
|
}
|
|
2652
2796
|
this.registeredPlugins.splice(index, 1);
|
|
2653
2797
|
await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
|
|
@@ -2665,10 +2809,13 @@ export class Matterbridge extends EventEmitter {
|
|
|
2665
2809
|
const plugin = plugins.find((plugin) => plugin.name === param);
|
|
2666
2810
|
if (plugin) {
|
|
2667
2811
|
plugin.enabled = true;
|
|
2812
|
+
plugin.error = undefined;
|
|
2668
2813
|
plugin.loaded = undefined;
|
|
2669
2814
|
plugin.started = undefined;
|
|
2670
2815
|
plugin.configured = undefined;
|
|
2671
2816
|
plugin.connected = undefined;
|
|
2817
|
+
plugin.platform = undefined;
|
|
2818
|
+
plugin.registeredDevices = undefined;
|
|
2672
2819
|
await this.nodeContext?.set('plugins', plugins);
|
|
2673
2820
|
this.log.info(`Enabled plugin ${plg}${param}${nf}`);
|
|
2674
2821
|
}
|
|
@@ -2679,7 +2826,6 @@ export class Matterbridge extends EventEmitter {
|
|
|
2679
2826
|
pluginToEnable.platform = await this.loadPlugin(pluginToEnable);
|
|
2680
2827
|
if (pluginToEnable.platform) {
|
|
2681
2828
|
await this.startPlugin(pluginToEnable, 'The plugin has been enabled', true);
|
|
2682
|
-
pluginToEnable.enabled = false;
|
|
2683
2829
|
}
|
|
2684
2830
|
else {
|
|
2685
2831
|
pluginToEnable.enabled = false;
|
|
@@ -2695,24 +2841,29 @@ export class Matterbridge extends EventEmitter {
|
|
|
2695
2841
|
if (pluginToDisable) {
|
|
2696
2842
|
if (pluginToDisable.platform) {
|
|
2697
2843
|
await pluginToDisable.platform.onShutdown('The plugin has been removed.');
|
|
2698
|
-
await this.savePluginConfig(pluginToDisable);
|
|
2844
|
+
// await this.savePluginConfig(pluginToDisable);
|
|
2699
2845
|
}
|
|
2700
2846
|
pluginToDisable.enabled = false;
|
|
2847
|
+
pluginToDisable.error = undefined;
|
|
2701
2848
|
pluginToDisable.loaded = undefined;
|
|
2702
2849
|
pluginToDisable.started = undefined;
|
|
2703
2850
|
pluginToDisable.configured = undefined;
|
|
2704
2851
|
pluginToDisable.connected = undefined;
|
|
2705
2852
|
pluginToDisable.platform = undefined;
|
|
2853
|
+
pluginToDisable.registeredDevices = undefined;
|
|
2706
2854
|
const plugins = await this.nodeContext?.get('plugins');
|
|
2707
2855
|
if (!plugins)
|
|
2708
2856
|
return;
|
|
2709
2857
|
const plugin = plugins.find((plugin) => plugin.name === param);
|
|
2710
2858
|
if (plugin) {
|
|
2711
2859
|
plugin.enabled = false;
|
|
2860
|
+
plugin.error = undefined;
|
|
2712
2861
|
plugin.loaded = undefined;
|
|
2713
2862
|
plugin.started = undefined;
|
|
2714
2863
|
plugin.configured = undefined;
|
|
2715
2864
|
plugin.connected = undefined;
|
|
2865
|
+
plugin.platform = undefined;
|
|
2866
|
+
plugin.registeredDevices = undefined;
|
|
2716
2867
|
await this.nodeContext?.set('plugins', plugins);
|
|
2717
2868
|
this.log.info(`Disabled plugin ${plg}${param}${nf}`);
|
|
2718
2869
|
}
|
|
@@ -2728,7 +2879,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2728
2879
|
if (!useHttps) {
|
|
2729
2880
|
// Listen on HTTP
|
|
2730
2881
|
this.expressServer = this.expressApp.listen(port, () => {
|
|
2731
|
-
this.log.info(`The frontend is
|
|
2882
|
+
this.log.info(`The frontend is listening on ${UNDERLINE}http://${this.systemInformation.ipv4Address}:${port}${UNDERLINEOFF}${rs}`);
|
|
2732
2883
|
});
|
|
2733
2884
|
}
|
|
2734
2885
|
else {
|
|
@@ -2742,7 +2893,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2742
2893
|
// Specify the port to listen on, for example 443 for default HTTPS
|
|
2743
2894
|
const PORT = 443;
|
|
2744
2895
|
httpsServer.listen(PORT, () => {
|
|
2745
|
-
this.log.info(`The frontend is
|
|
2896
|
+
this.log.info(`The frontend is listening on ${UNDERLINE}https://${this.systemInformation.ipv4Address}:${PORT}${UNDERLINEOFF}${rs}`);
|
|
2746
2897
|
});
|
|
2747
2898
|
}
|
|
2748
2899
|
this.log.debug(`Frontend initialized on port ${YELLOW}${port}${db} static ${UNDERLINE}${path.join(this.rootDirectory, 'frontend/build')}${UNDERLINEOFF}${rs}`);
|
|
@@ -2753,6 +2904,16 @@ export class Matterbridge extends EventEmitter {
|
|
|
2753
2904
|
* @returns The attributes of the cluster servers in the device.
|
|
2754
2905
|
*/
|
|
2755
2906
|
getClusterTextFromDevice(device) {
|
|
2907
|
+
const stringifyFixedLabel = (endpoint) => {
|
|
2908
|
+
const labelList = endpoint.getClusterServer(FixedLabelCluster)?.getLabelListAttribute();
|
|
2909
|
+
if (!labelList)
|
|
2910
|
+
return;
|
|
2911
|
+
const composed = labelList.find((entry) => entry.label === 'composed');
|
|
2912
|
+
if (composed)
|
|
2913
|
+
return 'Composed: ' + composed.value;
|
|
2914
|
+
else
|
|
2915
|
+
return ''; //'FixedLabel: ' + labelList.map((entry) => entry.label + ': ' + entry.value).join(' ');
|
|
2916
|
+
};
|
|
2756
2917
|
let attributes = '';
|
|
2757
2918
|
//this.log.debug(`getClusterTextFromDevice: ${device.name}`);
|
|
2758
2919
|
const clusterServers = device.getAllClusterServers();
|
|
@@ -2789,7 +2950,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
2789
2950
|
if (clusterServer.name === 'PressureMeasurement')
|
|
2790
2951
|
attributes += `Pressure: ${clusterServer.getMeasuredValueAttribute()} `;
|
|
2791
2952
|
if (clusterServer.name === 'FlowMeasurement')
|
|
2792
|
-
attributes += `
|
|
2953
|
+
attributes += `Flow: ${clusterServer.getMeasuredValueAttribute()} `;
|
|
2954
|
+
if (clusterServer.name === 'FixedLabel')
|
|
2955
|
+
attributes += `${stringifyFixedLabel(device)} `;
|
|
2793
2956
|
});
|
|
2794
2957
|
return attributes;
|
|
2795
2958
|
}
|
|
@@ -2819,6 +2982,31 @@ function restartProcess() {
|
|
|
2819
2982
|
process.exit();
|
|
2820
2983
|
}
|
|
2821
2984
|
|
|
2985
|
+
import React from 'react';
|
|
2986
|
+
import Form from "@rjsf/core";
|
|
2987
|
+
|
|
2988
|
+
const schema = {
|
|
2989
|
+
title: "Todo",
|
|
2990
|
+
type: "object",
|
|
2991
|
+
required: ["title"],
|
|
2992
|
+
properties: {
|
|
2993
|
+
title: {type: "string", title: "Title", default: "A new task"},
|
|
2994
|
+
done: {type: "boolean", title: "Done?", default: false}
|
|
2995
|
+
}
|
|
2996
|
+
};
|
|
2997
|
+
|
|
2998
|
+
const log = (type) => console.log.bind(console, type);
|
|
2999
|
+
|
|
3000
|
+
function Todo() {
|
|
3001
|
+
return (
|
|
3002
|
+
<Form schema={schema}
|
|
3003
|
+
onChange={log("changed")}
|
|
3004
|
+
onSubmit={log("submitted")}
|
|
3005
|
+
onError={log("errors")} />
|
|
3006
|
+
);
|
|
3007
|
+
}
|
|
3008
|
+
|
|
3009
|
+
export default Todo;
|
|
2822
3010
|
|
|
2823
3011
|
/*
|
|
2824
3012
|
How frontend was created
|