matterbridge 1.2.11 → 1.2.12
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 +17 -1
- package/README.md +26 -26
- 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 +180 -34
- package/dist/matterbridge.js.map +1 -1
- package/dist/matterbridgeDevice.d.ts +30 -2
- package/dist/matterbridgeDevice.d.ts.map +1 -1
- package/dist/matterbridgeDevice.js +46 -2
- package/dist/matterbridgeDevice.js.map +1 -1
- package/frontend/build/asset-manifest.json +3 -3
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/js/main.0c70c26b.js +3 -0
- package/frontend/build/static/js/{main.60e6f24a.js.LICENSE.txt → main.0c70c26b.js.LICENSE.txt} +2 -0
- package/frontend/build/static/js/main.0c70c26b.js.map +1 -0
- package/package.json +1 -1
- package/frontend/build/static/js/main.60e6f24a.js +0 -3
- package/frontend/build/static/js/main.60e6f24a.js.map +0 -1
package/dist/matterbridge.js
CHANGED
|
@@ -33,9 +33,7 @@ import os from 'os';
|
|
|
33
33
|
import path from 'path';
|
|
34
34
|
import WebSocket, { WebSocketServer } from 'ws';
|
|
35
35
|
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';
|
|
36
|
+
import { BasicInformationCluster, BooleanStateCluster, BridgedDeviceBasicInformation, BridgedDeviceBasicInformationCluster, ClusterServer, FixedLabelCluster, GeneralCommissioning, PowerSourceCluster, ThreadNetworkDiagnosticsCluster, getClusterNameById, } from '@project-chip/matter-node.js/cluster';
|
|
39
37
|
import { DeviceTypeId, VendorId } from '@project-chip/matter-node.js/datatype';
|
|
40
38
|
import { Aggregator, DeviceTypes, NodeStateInformation } from '@project-chip/matter-node.js/device';
|
|
41
39
|
import { Format, Level, Logger } from '@project-chip/matter-node.js/log';
|
|
@@ -190,7 +188,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
190
188
|
await this.showCommissioningQRCode(this.commissioningServer, this.matterbridgeContext, this.nodeContext, 'Matterbridge');
|
|
191
189
|
// Set reachability to true and trigger event after 60 seconds
|
|
192
190
|
setTimeout(() => {
|
|
193
|
-
this.log.info(
|
|
191
|
+
this.log.info(`Setting reachability to true for ${plg}Matterbridge${db}`);
|
|
194
192
|
if (this.commissioningServer)
|
|
195
193
|
this.setCommissioningServerReachability(this.commissioningServer, true);
|
|
196
194
|
if (this.matterAggregator)
|
|
@@ -367,7 +365,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
367
365
|
// Delete matter storage file
|
|
368
366
|
await fs.unlink(path.join(this.matterbridgeDirectory, 'matterbridge.json'));
|
|
369
367
|
// Delete node storage directory with its subdirectories
|
|
370
|
-
await fs.
|
|
368
|
+
await fs.rm(path.join(this.matterbridgeDirectory, 'storage'), { recursive: true });
|
|
371
369
|
this.log.info('Factory reset done! Remove all paired devices from the controllers.');
|
|
372
370
|
this.emit('shutdown');
|
|
373
371
|
process.exit(0);
|
|
@@ -611,6 +609,31 @@ export class Matterbridge extends EventEmitter {
|
|
|
611
609
|
await this.cleanup('shutting down...', false);
|
|
612
610
|
this.hasCleanupStarted = false;
|
|
613
611
|
}
|
|
612
|
+
/**
|
|
613
|
+
* Shut down the process and reset.
|
|
614
|
+
*/
|
|
615
|
+
async unregisterAndShutdownProcess() {
|
|
616
|
+
this.log.info('Unregistering all devices and shutting down...');
|
|
617
|
+
for (const plugin of this.registeredPlugins.filter((plugin) => plugin.enabled && !plugin.error)) {
|
|
618
|
+
await this.removeAllBridgedDevices(plugin.name);
|
|
619
|
+
}
|
|
620
|
+
await this.cleanup('unregistered all devices and shutting down...', false);
|
|
621
|
+
this.hasCleanupStarted = false;
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Shut down the process and reset.
|
|
625
|
+
*/
|
|
626
|
+
async shutdownProcessAndReset() {
|
|
627
|
+
await this.cleanup('shutting down with reset...', false);
|
|
628
|
+
this.hasCleanupStarted = false;
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Shut down the process and factory reset.
|
|
632
|
+
*/
|
|
633
|
+
async shutdownProcessAndFactoryReset() {
|
|
634
|
+
await this.cleanup('shutting down with factory reset...', false);
|
|
635
|
+
this.hasCleanupStarted = false;
|
|
636
|
+
}
|
|
614
637
|
/**
|
|
615
638
|
* Cleans up the Matterbridge instance.
|
|
616
639
|
* @param message - The cleanup message.
|
|
@@ -628,7 +651,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
628
651
|
for (const plugin of this.registeredPlugins) {
|
|
629
652
|
if (!plugin.enabled || plugin.error)
|
|
630
653
|
continue;
|
|
631
|
-
this.log.info(
|
|
654
|
+
this.log.info(`Shutting down plugin ${plg}${plugin.name}${nf}`);
|
|
632
655
|
if (plugin.platform) {
|
|
633
656
|
try {
|
|
634
657
|
await plugin.platform.onShutdown('Matterbridge is closing: ' + message);
|
|
@@ -710,7 +733,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
710
733
|
});
|
|
711
734
|
this.webSocketServer = undefined;
|
|
712
735
|
}
|
|
713
|
-
|
|
736
|
+
setTimeout(async () => {
|
|
714
737
|
// Closing matter
|
|
715
738
|
await this.stopMatter();
|
|
716
739
|
// Closing storage
|
|
@@ -740,7 +763,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
740
763
|
this.registeredPlugins = [];
|
|
741
764
|
this.registeredDevices = [];
|
|
742
765
|
this.log.info('Waiting for matter to deliver last messages...');
|
|
743
|
-
|
|
766
|
+
setTimeout(async () => {
|
|
744
767
|
if (restart) {
|
|
745
768
|
if (message === 'updating...') {
|
|
746
769
|
this.log.info('Cleanup completed. Updating...');
|
|
@@ -754,14 +777,27 @@ export class Matterbridge extends EventEmitter {
|
|
|
754
777
|
}
|
|
755
778
|
}
|
|
756
779
|
else {
|
|
780
|
+
if (message === 'shutting down with reset...') {
|
|
781
|
+
// Delete matter storage file
|
|
782
|
+
this.log.info('Resetting Matterbridge commissioning information...');
|
|
783
|
+
await fs.unlink(path.join(this.matterbridgeDirectory, 'matterbridge.json'));
|
|
784
|
+
this.log.info('Reset done! Remove all paired devices from the controllers.');
|
|
785
|
+
}
|
|
786
|
+
if (message === 'shutting down with factory reset...') {
|
|
787
|
+
// Delete matter storage file
|
|
788
|
+
this.log.info('Resetting Matterbridge commissioning information...');
|
|
789
|
+
await fs.unlink(path.join(this.matterbridgeDirectory, 'matterbridge.json'));
|
|
790
|
+
// Delete node storage directory with its subdirectories
|
|
791
|
+
this.log.info('Resetting Matterbridge storage...');
|
|
792
|
+
await fs.rm(path.join(this.matterbridgeDirectory, 'storage'), { recursive: true });
|
|
793
|
+
this.log.info('Factory reset done! Remove all paired devices from the controllers.');
|
|
794
|
+
}
|
|
757
795
|
this.log.info('Cleanup completed. Shutting down...');
|
|
758
796
|
Matterbridge.instance = undefined;
|
|
759
797
|
this.emit('shutdown');
|
|
760
798
|
}
|
|
761
799
|
}, 2 * 1000);
|
|
762
|
-
//cleanupTimeout2.unref();
|
|
763
800
|
}, 3 * 1000);
|
|
764
|
-
//cleanupTimeout1.unref();
|
|
765
801
|
}
|
|
766
802
|
}
|
|
767
803
|
/**
|
|
@@ -911,7 +947,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
911
947
|
async removeAllBridgedDevices(pluginName) {
|
|
912
948
|
const plugin = this.findPlugin(pluginName);
|
|
913
949
|
if (this.bridgeMode === 'childbridge' && plugin?.type === 'AccessoryPlatform') {
|
|
914
|
-
this.log.info(`Removing devices for plugin ${plg}${pluginName}${nf}
|
|
950
|
+
this.log.info(`Removing devices for plugin ${plg}${pluginName}${nf} type AccessoryPlatform is not supported in childbridge mode`);
|
|
915
951
|
return;
|
|
916
952
|
}
|
|
917
953
|
const devicesToRemove = [];
|
|
@@ -1534,7 +1570,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1534
1570
|
await this.showCommissioningQRCode(this.commissioningServer, this.matterbridgeContext, this.nodeContext, 'Matterbridge');
|
|
1535
1571
|
//if (hasParameter('advertise')) await this.commissioningServer.advertise();
|
|
1536
1572
|
setTimeout(() => {
|
|
1537
|
-
this.log.info(
|
|
1573
|
+
this.log.info(`Setting reachability to true for ${plg}Matterbridge${db}`);
|
|
1538
1574
|
if (this.commissioningServer)
|
|
1539
1575
|
this.setCommissioningServerReachability(this.commissioningServer, true);
|
|
1540
1576
|
if (this.matterAggregator)
|
|
@@ -1637,7 +1673,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1637
1673
|
}
|
|
1638
1674
|
await this.showCommissioningQRCode(plugin.commissioningServer, plugin.storageContext, plugin.nodeContext, plugin.name);
|
|
1639
1675
|
// Setting reachability to true
|
|
1640
|
-
this.log.info(
|
|
1676
|
+
this.log.info(`Setting reachability to true for ${plg}${plugin.name}${db}`);
|
|
1641
1677
|
if (plugin.commissioningServer)
|
|
1642
1678
|
this.setCommissioningServerReachability(plugin.commissioningServer, true);
|
|
1643
1679
|
if (plugin.type === 'AccessoryPlatform' && plugin.device)
|
|
@@ -1756,7 +1792,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1756
1792
|
await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
|
|
1757
1793
|
}
|
|
1758
1794
|
else {
|
|
1759
|
-
this.log.info(
|
|
1795
|
+
this.log.info(`*The commissioning server on port ${commissioningServer.getPort()} for ${plg}${pluginName}${nf} is already commissioned . Waiting for controllers to connect ...`);
|
|
1760
1796
|
if (pluginName !== 'Matterbridge') {
|
|
1761
1797
|
const plugin = this.findPlugin(pluginName);
|
|
1762
1798
|
if (plugin) {
|
|
@@ -1805,7 +1841,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1805
1841
|
if (basicInformationCluster && basicInformationCluster.triggerReachableChangedEvent)
|
|
1806
1842
|
basicInformationCluster.triggerReachableChangedEvent({ reachableNewValue: reachable });
|
|
1807
1843
|
matterAggregator.getBridgedDevices().forEach((device) => {
|
|
1808
|
-
this.log.debug(
|
|
1844
|
+
this.log.debug(`Setting reachability to true for bridged device: ${dev}${device.name}${nf}`);
|
|
1809
1845
|
device.getClusterServer(BridgedDeviceBasicInformationCluster)?.setReachableAttribute(reachable);
|
|
1810
1846
|
device.getClusterServer(BridgedDeviceBasicInformationCluster)?.triggerReachableChangedEvent({ reachableNewValue: reachable });
|
|
1811
1847
|
});
|
|
@@ -1831,6 +1867,35 @@ export class Matterbridge extends EventEmitter {
|
|
|
1831
1867
|
* @returns {CommissioningServer} The created commissioning server.
|
|
1832
1868
|
*/
|
|
1833
1869
|
async createCommisioningServer(context, pluginName) {
|
|
1870
|
+
const getVendorIdName = (vendorId) => {
|
|
1871
|
+
if (!vendorId)
|
|
1872
|
+
return '';
|
|
1873
|
+
let vendorName = '';
|
|
1874
|
+
switch (vendorId) {
|
|
1875
|
+
case 4937:
|
|
1876
|
+
vendorName = '(AppleHome)';
|
|
1877
|
+
break;
|
|
1878
|
+
case 4362:
|
|
1879
|
+
vendorName = '(SmartThings)';
|
|
1880
|
+
break;
|
|
1881
|
+
case 4939:
|
|
1882
|
+
vendorName = '(HomeAssistant)';
|
|
1883
|
+
break;
|
|
1884
|
+
case 24582:
|
|
1885
|
+
vendorName = '(GoogleHome)';
|
|
1886
|
+
break;
|
|
1887
|
+
case 4701:
|
|
1888
|
+
vendorName = '(Tuya)';
|
|
1889
|
+
break;
|
|
1890
|
+
case 4742:
|
|
1891
|
+
vendorName = '(eWeLink)';
|
|
1892
|
+
break;
|
|
1893
|
+
default:
|
|
1894
|
+
vendorName = '(unknown)';
|
|
1895
|
+
break;
|
|
1896
|
+
}
|
|
1897
|
+
return vendorName;
|
|
1898
|
+
};
|
|
1834
1899
|
this.log.debug(`Creating matter commissioning server for plugin ${plg}${pluginName}${db}`);
|
|
1835
1900
|
const deviceName = await context.get('deviceName');
|
|
1836
1901
|
const deviceType = await context.get('deviceType');
|
|
@@ -1873,16 +1938,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
1873
1938
|
const info = commissioningServer.getActiveSessionInformation(fabricIndex);
|
|
1874
1939
|
let connected = false;
|
|
1875
1940
|
info.forEach((session) => {
|
|
1876
|
-
this.log.info(
|
|
1941
|
+
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
1942
|
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}`);
|
|
1943
|
+
this.log.info(`*Controller ${session.fabric?.rootVendorId}${getVendorIdName(session.fabric?.rootVendorId)}/${session.fabric?.label} connected to ${plg}${pluginName}${nf} on session ${session.name}`);
|
|
1886
1944
|
connected = true;
|
|
1887
1945
|
}
|
|
1888
1946
|
});
|
|
@@ -1944,9 +2002,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
1944
2002
|
},
|
|
1945
2003
|
commissioningChangedCallback: async (fabricIndex) => {
|
|
1946
2004
|
const info = commissioningServer.getCommissionedFabricInformation(fabricIndex);
|
|
1947
|
-
this.log.debug(
|
|
2005
|
+
this.log.debug(`*Commissioning changed on fabric ${fabricIndex} for ${plg}${pluginName}${nf}`, debugStringify(info));
|
|
1948
2006
|
if (info.length === 0) {
|
|
1949
|
-
this.log.warn(
|
|
2007
|
+
this.log.warn(`*Commissioning removed from fabric ${fabricIndex} for ${plg}${pluginName}${wr}. Resetting the commissioning server ...`);
|
|
1950
2008
|
await commissioningServer.factoryReset();
|
|
1951
2009
|
if (pluginName === 'Matterbridge') {
|
|
1952
2010
|
await this.matterbridgeContext?.clearAll();
|
|
@@ -1961,7 +2019,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1961
2019
|
}
|
|
1962
2020
|
}
|
|
1963
2021
|
}
|
|
1964
|
-
this.log.warn(
|
|
2022
|
+
this.log.warn(`*Restart to activate the pairing for ${plg}${pluginName}${wr}`);
|
|
1965
2023
|
}
|
|
1966
2024
|
},
|
|
1967
2025
|
});
|
|
@@ -2522,6 +2580,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2522
2580
|
//console.log(error);
|
|
2523
2581
|
}
|
|
2524
2582
|
data.push({
|
|
2583
|
+
endpoint: registeredDevice.device.number ? registeredDevice.device.number.toString() : '...',
|
|
2525
2584
|
clusterName: clusterServer.name,
|
|
2526
2585
|
clusterId: '0x' + clusterServer.id.toString(16).padStart(2, '0'),
|
|
2527
2586
|
attributeName: key,
|
|
@@ -2530,6 +2589,37 @@ export class Matterbridge extends EventEmitter {
|
|
|
2530
2589
|
});
|
|
2531
2590
|
});
|
|
2532
2591
|
});
|
|
2592
|
+
registeredDevice.device.getChildEndpoints().forEach((childEndpoint) => {
|
|
2593
|
+
const name = registeredDevice.device.getChildEndpointName(childEndpoint);
|
|
2594
|
+
const clusterServers = childEndpoint.getAllClusterServers();
|
|
2595
|
+
clusterServers.forEach((clusterServer) => {
|
|
2596
|
+
Object.entries(clusterServer.attributes).forEach(([key, value]) => {
|
|
2597
|
+
if (clusterServer.name === 'EveHistory')
|
|
2598
|
+
return;
|
|
2599
|
+
//this.log.debug(`***--clusterServer: ${clusterServer.name}(${clusterServer.id}) attribute:${key}(${value.id}) ${value.isFixed} ${value.isWritable} ${value.isWritable}`);
|
|
2600
|
+
let attributeValue;
|
|
2601
|
+
try {
|
|
2602
|
+
if (typeof value.getLocal() === 'object')
|
|
2603
|
+
attributeValue = stringify(value.getLocal());
|
|
2604
|
+
else
|
|
2605
|
+
attributeValue = value.getLocal().toString();
|
|
2606
|
+
}
|
|
2607
|
+
catch (error) {
|
|
2608
|
+
attributeValue = 'Unavailable';
|
|
2609
|
+
this.log.debug(`GetLocal error ${error} in clusterServer: ${clusterServer.name}(${clusterServer.id}) attribute: ${key}(${value.id})`);
|
|
2610
|
+
//console.log(error);
|
|
2611
|
+
}
|
|
2612
|
+
data.push({
|
|
2613
|
+
endpoint: (childEndpoint.number ? childEndpoint.number.toString() : '...') + (name ? ' (' + name + ')' : ''),
|
|
2614
|
+
clusterName: clusterServer.name,
|
|
2615
|
+
clusterId: '0x' + clusterServer.id.toString(16).padStart(2, '0'),
|
|
2616
|
+
attributeName: key,
|
|
2617
|
+
attributeId: '0x' + value.id.toString(16).padStart(2, '0'),
|
|
2618
|
+
attributeValue,
|
|
2619
|
+
});
|
|
2620
|
+
});
|
|
2621
|
+
});
|
|
2622
|
+
});
|
|
2533
2623
|
}
|
|
2534
2624
|
});
|
|
2535
2625
|
res.json(data);
|
|
@@ -2571,13 +2661,25 @@ export class Matterbridge extends EventEmitter {
|
|
|
2571
2661
|
plugin.platform?.log.setLogDebug(this.debugEnabled);
|
|
2572
2662
|
});
|
|
2573
2663
|
}
|
|
2574
|
-
// Handle the command
|
|
2664
|
+
// Handle the command reset from Settings
|
|
2665
|
+
if (command === 'unregister') {
|
|
2666
|
+
await this.unregisterAndShutdownProcess();
|
|
2667
|
+
}
|
|
2668
|
+
// Handle the command reset from Settings
|
|
2669
|
+
if (command === 'reset') {
|
|
2670
|
+
this.shutdownProcessAndReset(); // No await do it asyncronously
|
|
2671
|
+
}
|
|
2672
|
+
// Handle the command factoryreset from Settings
|
|
2673
|
+
if (command === 'factoryreset') {
|
|
2674
|
+
this.shutdownProcessAndFactoryReset(); // No await do it asyncronously
|
|
2675
|
+
}
|
|
2676
|
+
// Handle the command restart from Header
|
|
2575
2677
|
if (command === 'shutdown') {
|
|
2576
|
-
this.shutdownProcess();
|
|
2678
|
+
this.shutdownProcess(); // No await do it asyncronously
|
|
2577
2679
|
}
|
|
2578
2680
|
// Handle the command restart from Header
|
|
2579
2681
|
if (command === 'restart') {
|
|
2580
|
-
this.restartProcess();
|
|
2682
|
+
this.restartProcess(); // No await do it asyncronously
|
|
2581
2683
|
}
|
|
2582
2684
|
// Handle the command update from Header
|
|
2583
2685
|
if (command === 'update') {
|
|
@@ -2665,10 +2767,13 @@ export class Matterbridge extends EventEmitter {
|
|
|
2665
2767
|
const plugin = plugins.find((plugin) => plugin.name === param);
|
|
2666
2768
|
if (plugin) {
|
|
2667
2769
|
plugin.enabled = true;
|
|
2770
|
+
plugin.error = undefined;
|
|
2668
2771
|
plugin.loaded = undefined;
|
|
2669
2772
|
plugin.started = undefined;
|
|
2670
2773
|
plugin.configured = undefined;
|
|
2671
2774
|
plugin.connected = undefined;
|
|
2775
|
+
plugin.platform = undefined;
|
|
2776
|
+
plugin.registeredDevices = undefined;
|
|
2672
2777
|
await this.nodeContext?.set('plugins', plugins);
|
|
2673
2778
|
this.log.info(`Enabled plugin ${plg}${param}${nf}`);
|
|
2674
2779
|
}
|
|
@@ -2679,7 +2784,6 @@ export class Matterbridge extends EventEmitter {
|
|
|
2679
2784
|
pluginToEnable.platform = await this.loadPlugin(pluginToEnable);
|
|
2680
2785
|
if (pluginToEnable.platform) {
|
|
2681
2786
|
await this.startPlugin(pluginToEnable, 'The plugin has been enabled', true);
|
|
2682
|
-
pluginToEnable.enabled = false;
|
|
2683
2787
|
}
|
|
2684
2788
|
else {
|
|
2685
2789
|
pluginToEnable.enabled = false;
|
|
@@ -2698,21 +2802,26 @@ export class Matterbridge extends EventEmitter {
|
|
|
2698
2802
|
await this.savePluginConfig(pluginToDisable);
|
|
2699
2803
|
}
|
|
2700
2804
|
pluginToDisable.enabled = false;
|
|
2805
|
+
pluginToDisable.error = undefined;
|
|
2701
2806
|
pluginToDisable.loaded = undefined;
|
|
2702
2807
|
pluginToDisable.started = undefined;
|
|
2703
2808
|
pluginToDisable.configured = undefined;
|
|
2704
2809
|
pluginToDisable.connected = undefined;
|
|
2705
2810
|
pluginToDisable.platform = undefined;
|
|
2811
|
+
pluginToDisable.registeredDevices = undefined;
|
|
2706
2812
|
const plugins = await this.nodeContext?.get('plugins');
|
|
2707
2813
|
if (!plugins)
|
|
2708
2814
|
return;
|
|
2709
2815
|
const plugin = plugins.find((plugin) => plugin.name === param);
|
|
2710
2816
|
if (plugin) {
|
|
2711
2817
|
plugin.enabled = false;
|
|
2818
|
+
plugin.error = undefined;
|
|
2712
2819
|
plugin.loaded = undefined;
|
|
2713
2820
|
plugin.started = undefined;
|
|
2714
2821
|
plugin.configured = undefined;
|
|
2715
2822
|
plugin.connected = undefined;
|
|
2823
|
+
plugin.platform = undefined;
|
|
2824
|
+
plugin.registeredDevices = undefined;
|
|
2716
2825
|
await this.nodeContext?.set('plugins', plugins);
|
|
2717
2826
|
this.log.info(`Disabled plugin ${plg}${param}${nf}`);
|
|
2718
2827
|
}
|
|
@@ -2728,7 +2837,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2728
2837
|
if (!useHttps) {
|
|
2729
2838
|
// Listen on HTTP
|
|
2730
2839
|
this.expressServer = this.expressApp.listen(port, () => {
|
|
2731
|
-
this.log.info(`The frontend is
|
|
2840
|
+
this.log.info(`The frontend is listening on ${UNDERLINE}http://${this.systemInformation.ipv4Address}:${port}${UNDERLINEOFF}${rs}`);
|
|
2732
2841
|
});
|
|
2733
2842
|
}
|
|
2734
2843
|
else {
|
|
@@ -2742,7 +2851,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2742
2851
|
// Specify the port to listen on, for example 443 for default HTTPS
|
|
2743
2852
|
const PORT = 443;
|
|
2744
2853
|
httpsServer.listen(PORT, () => {
|
|
2745
|
-
this.log.info(`The frontend is
|
|
2854
|
+
this.log.info(`The frontend is listening on ${UNDERLINE}https://${this.systemInformation.ipv4Address}:${PORT}${UNDERLINEOFF}${rs}`);
|
|
2746
2855
|
});
|
|
2747
2856
|
}
|
|
2748
2857
|
this.log.debug(`Frontend initialized on port ${YELLOW}${port}${db} static ${UNDERLINE}${path.join(this.rootDirectory, 'frontend/build')}${UNDERLINEOFF}${rs}`);
|
|
@@ -2753,6 +2862,16 @@ export class Matterbridge extends EventEmitter {
|
|
|
2753
2862
|
* @returns The attributes of the cluster servers in the device.
|
|
2754
2863
|
*/
|
|
2755
2864
|
getClusterTextFromDevice(device) {
|
|
2865
|
+
const stringifyFixedLabel = (endpoint) => {
|
|
2866
|
+
const labelList = endpoint.getClusterServer(FixedLabelCluster)?.getLabelListAttribute();
|
|
2867
|
+
if (!labelList)
|
|
2868
|
+
return;
|
|
2869
|
+
const composed = labelList.find((entry) => entry.label === 'composed');
|
|
2870
|
+
if (composed)
|
|
2871
|
+
return 'Composed: ' + composed.value;
|
|
2872
|
+
else
|
|
2873
|
+
return ''; //'FixedLabel: ' + labelList.map((entry) => entry.label + ': ' + entry.value).join(' ');
|
|
2874
|
+
};
|
|
2756
2875
|
let attributes = '';
|
|
2757
2876
|
//this.log.debug(`getClusterTextFromDevice: ${device.name}`);
|
|
2758
2877
|
const clusterServers = device.getAllClusterServers();
|
|
@@ -2789,7 +2908,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
2789
2908
|
if (clusterServer.name === 'PressureMeasurement')
|
|
2790
2909
|
attributes += `Pressure: ${clusterServer.getMeasuredValueAttribute()} `;
|
|
2791
2910
|
if (clusterServer.name === 'FlowMeasurement')
|
|
2792
|
-
attributes += `
|
|
2911
|
+
attributes += `Flow: ${clusterServer.getMeasuredValueAttribute()} `;
|
|
2912
|
+
if (clusterServer.name === 'FixedLabel')
|
|
2913
|
+
attributes += `${stringifyFixedLabel(device)} `;
|
|
2793
2914
|
});
|
|
2794
2915
|
return attributes;
|
|
2795
2916
|
}
|
|
@@ -2819,6 +2940,31 @@ function restartProcess() {
|
|
|
2819
2940
|
process.exit();
|
|
2820
2941
|
}
|
|
2821
2942
|
|
|
2943
|
+
import React from 'react';
|
|
2944
|
+
import Form from "@rjsf/core";
|
|
2945
|
+
|
|
2946
|
+
const schema = {
|
|
2947
|
+
title: "Todo",
|
|
2948
|
+
type: "object",
|
|
2949
|
+
required: ["title"],
|
|
2950
|
+
properties: {
|
|
2951
|
+
title: {type: "string", title: "Title", default: "A new task"},
|
|
2952
|
+
done: {type: "boolean", title: "Done?", default: false}
|
|
2953
|
+
}
|
|
2954
|
+
};
|
|
2955
|
+
|
|
2956
|
+
const log = (type) => console.log.bind(console, type);
|
|
2957
|
+
|
|
2958
|
+
function Todo() {
|
|
2959
|
+
return (
|
|
2960
|
+
<Form schema={schema}
|
|
2961
|
+
onChange={log("changed")}
|
|
2962
|
+
onSubmit={log("submitted")}
|
|
2963
|
+
onError={log("errors")} />
|
|
2964
|
+
);
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
export default Todo;
|
|
2822
2968
|
|
|
2823
2969
|
/*
|
|
2824
2970
|
How frontend was created
|