matterbridge 1.2.14 → 1.2.16
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 +34 -0
- package/README.md +3 -0
- package/dist/matterbridge.d.ts +18 -0
- package/dist/matterbridge.d.ts.map +1 -1
- package/dist/matterbridge.js +179 -147
- package/dist/matterbridge.js.map +1 -1
- package/dist/matterbridgeDevice.d.ts +14 -30
- package/dist/matterbridgeDevice.d.ts.map +1 -1
- package/dist/matterbridgeDevice.js +1 -1
- package/dist/matterbridgeDevice.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.57bd18a9.css +2 -0
- package/frontend/build/static/css/main.57bd18a9.css.map +1 -0
- package/frontend/build/static/js/main.b08bfdf4.js +3 -0
- package/frontend/build/static/js/main.b08bfdf4.js.map +1 -0
- package/package.json +13 -11
- package/frontend/build/static/css/main.979e07d2.css +0 -2
- package/frontend/build/static/css/main.979e07d2.css.map +0 -1
- package/frontend/build/static/js/main.ed3f81ca.js +0 -3
- package/frontend/build/static/js/main.ed3f81ca.js.map +0 -1
- /package/frontend/build/static/js/{main.ed3f81ca.js.LICENSE.txt → main.b08bfdf4.js.LICENSE.txt} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.2.16] - 2024-05-15
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- [matter.js]: Update to @project-chip/matter-node.js v. 0.9.0
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- [frontend]: Frontend updated to 1.0.0.
|
|
13
|
+
- [frontend]: Added check version interval.
|
|
14
|
+
- [frontend]: Added help and version information icons for plugins.
|
|
15
|
+
- [frontend]: Added version information for Matterbridge (Click on the version badge).
|
|
16
|
+
- [frontend]: Added help badge for Matterbridge.
|
|
17
|
+
- [frontend]: Added version information badge for Matterbridge.
|
|
18
|
+
|
|
19
|
+
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
20
|
+
<img src="./yellow-button.png" alt="Buy me a coffee" width="120">
|
|
21
|
+
</a>
|
|
22
|
+
|
|
23
|
+
## [1.2.15] - 2024-05-14
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- [frontend]: Added sponsor link in Header.
|
|
28
|
+
- [frontend]: Added sponsor link in the plugin list.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- [frontend]: Fixed the case when the latest version of Matterbridge or a plugin is not available.
|
|
33
|
+
|
|
34
|
+
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
35
|
+
<img src="./yellow-button.png" alt="Buy me a coffee" width="120">
|
|
36
|
+
</a>
|
|
37
|
+
|
|
38
|
+
|
|
5
39
|
## [1.2.14] - 2024-05-09
|
|
6
40
|
|
|
7
41
|
### Added
|
package/README.md
CHANGED
|
@@ -107,6 +107,9 @@ Devices page:
|
|
|
107
107
|
Logs page:
|
|
108
108
|

|
|
109
109
|
|
|
110
|
+
Config editor:
|
|
111
|
+

|
|
112
|
+
|
|
110
113
|
## Plugins
|
|
111
114
|
|
|
112
115
|
### Accessory platform example
|
package/dist/matterbridge.d.ts
CHANGED
|
@@ -71,6 +71,7 @@ export declare class Matterbridge extends EventEmitter {
|
|
|
71
71
|
globalModulesDirectory: string;
|
|
72
72
|
matterbridgeVersion: string;
|
|
73
73
|
matterbridgeLatestVersion: string;
|
|
74
|
+
private checkUpdateInterval?;
|
|
74
75
|
bridgeMode: 'bridge' | 'childbridge' | 'controller' | '';
|
|
75
76
|
restartMode: 'service' | 'docker' | '';
|
|
76
77
|
debugEnabled: boolean;
|
|
@@ -418,6 +419,23 @@ export declare class Matterbridge extends EventEmitter {
|
|
|
418
419
|
* Logs the node and system information.
|
|
419
420
|
*/
|
|
420
421
|
private logNodeAndSystemInfo;
|
|
422
|
+
/**
|
|
423
|
+
* Retrieves the latest version of Matterbridge and performs necessary actions based on the version comparison.
|
|
424
|
+
* @private
|
|
425
|
+
* @returns {Promise<void>} A promise that resolves when the latest version is retrieved and actions are performed.
|
|
426
|
+
*/
|
|
427
|
+
private getMatterbridgeLatestVersion;
|
|
428
|
+
/**
|
|
429
|
+
* Retrieves the latest version of a plugin and updates the plugin's latestVersion property.
|
|
430
|
+
* If the plugin's version is different from the latest version, logs a warning message.
|
|
431
|
+
* If the plugin's version is the same as the latest version, logs an info message.
|
|
432
|
+
* If there is an error retrieving the latest version, logs an error message.
|
|
433
|
+
*
|
|
434
|
+
* @private
|
|
435
|
+
* @param {RegisteredPlugin} plugin - The plugin for which to retrieve the latest version.
|
|
436
|
+
* @returns {Promise<void>} A promise that resolves when the latest version is retrieved and actions are performed.
|
|
437
|
+
*/
|
|
438
|
+
private getPluginLatestVersion;
|
|
421
439
|
/**
|
|
422
440
|
* Retrieves an array of base registered plugins.
|
|
423
441
|
*
|
|
@@ -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
|
@@ -34,7 +34,7 @@ import path from 'path';
|
|
|
34
34
|
import WebSocket, { WebSocketServer } from 'ws';
|
|
35
35
|
import { BridgedDeviceBasicInformation, BridgedDeviceBasicInformationCluster } from './BridgedDeviceBasicInformationCluster.js';
|
|
36
36
|
import { CommissioningController, CommissioningServer, MatterServer } from '@project-chip/matter-node.js';
|
|
37
|
-
import { BasicInformationCluster,
|
|
37
|
+
import { BasicInformationCluster, ClusterServer, FixedLabelCluster, GeneralCommissioning, PowerSourceCluster, ThreadNetworkDiagnosticsCluster, getClusterNameById } from '@project-chip/matter-node.js/cluster';
|
|
38
38
|
import { DeviceTypeId, VendorId } from '@project-chip/matter-node.js/datatype';
|
|
39
39
|
import { Aggregator, DeviceTypes, NodeStateInformation } from '@project-chip/matter-node.js/device';
|
|
40
40
|
import { Format, Level, Logger } from '@project-chip/matter-node.js/log';
|
|
@@ -84,6 +84,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
84
84
|
globalModulesDirectory = '';
|
|
85
85
|
matterbridgeVersion = '';
|
|
86
86
|
matterbridgeLatestVersion = '';
|
|
87
|
+
checkUpdateInterval; // = 24 * 60 * 60 * 1000; // 24 hours
|
|
87
88
|
bridgeMode = '';
|
|
88
89
|
restartMode = '';
|
|
89
90
|
debugEnabled = false;
|
|
@@ -181,7 +182,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
181
182
|
this.log.debug(`Creating commissioning server for ${plg}Matterbridge${db}`);
|
|
182
183
|
this.commissioningServer = await this.createCommisioningServer(this.matterbridgeContext, 'Matterbridge');
|
|
183
184
|
this.log.debug(`Creating matter aggregator for ${plg}Matterbridge${db}`);
|
|
184
|
-
this.matterAggregator = await this.createMatterAggregator(this.matterbridgeContext);
|
|
185
|
+
this.matterAggregator = await this.createMatterAggregator(this.matterbridgeContext, 'Matterbridge');
|
|
185
186
|
this.log.debug('Adding matterbridge aggregator to commissioning server');
|
|
186
187
|
this.commissioningServer.addDevice(this.matterAggregator);
|
|
187
188
|
this.log.debug('Adding matterbridge commissioning server to matter server');
|
|
@@ -285,12 +286,6 @@ export class Matterbridge extends EventEmitter {
|
|
|
285
286
|
await plugin.nodeContext.set('description', plugin.description);
|
|
286
287
|
await plugin.nodeContext.set('author', plugin.author);
|
|
287
288
|
}
|
|
288
|
-
if (hasParameter('logstorage')) {
|
|
289
|
-
await this.nodeContext.logStorage();
|
|
290
|
-
for (const plugin of this.registeredPlugins) {
|
|
291
|
-
await plugin.nodeContext?.logStorage();
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
289
|
// Log system info and create .matterbridge directory
|
|
295
290
|
await this.logNodeAndSystemInfo();
|
|
296
291
|
this.log.info(
|
|
@@ -340,6 +335,16 @@ export class Matterbridge extends EventEmitter {
|
|
|
340
335
|
this.emit('shutdown');
|
|
341
336
|
process.exit(0);
|
|
342
337
|
}
|
|
338
|
+
if (hasParameter('logstorage')) {
|
|
339
|
+
this.log.info(`${plg}matterbridge${nf} storage log`);
|
|
340
|
+
await this.nodeContext?.logStorage();
|
|
341
|
+
for (const plugin of this.registeredPlugins) {
|
|
342
|
+
this.log.info(`${plg}${plugin.name}${nf} storage log`);
|
|
343
|
+
await plugin.nodeContext?.logStorage();
|
|
344
|
+
}
|
|
345
|
+
this.emit('shutdown');
|
|
346
|
+
process.exit(0);
|
|
347
|
+
}
|
|
343
348
|
if (getParameter('add')) {
|
|
344
349
|
this.log.debug(`Registering plugin ${getParameter('add')}`);
|
|
345
350
|
await this.executeCommandLine(getParameter('add'), 'add');
|
|
@@ -393,6 +398,12 @@ export class Matterbridge extends EventEmitter {
|
|
|
393
398
|
}
|
|
394
399
|
// Initialize frontend
|
|
395
400
|
await this.initializeFrontend(getIntParameter('frontend'));
|
|
401
|
+
this.checkUpdateInterval = setInterval(() => {
|
|
402
|
+
this.getMatterbridgeLatestVersion();
|
|
403
|
+
this.registeredPlugins.forEach((plugin) => {
|
|
404
|
+
this.getPluginLatestVersion(plugin);
|
|
405
|
+
});
|
|
406
|
+
}, 60 * 60 * 1000);
|
|
396
407
|
if (hasParameter('test')) {
|
|
397
408
|
this.bridgeMode = 'childbridge';
|
|
398
409
|
MatterbridgeDevice.bridgeMode = 'childbridge';
|
|
@@ -650,6 +661,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
650
661
|
process.removeAllListeners('SIGINT');
|
|
651
662
|
process.removeAllListeners('SIGTERM');
|
|
652
663
|
this.log.debug('All listeners removed');
|
|
664
|
+
this.checkUpdateInterval && clearInterval(this.checkUpdateInterval);
|
|
665
|
+
this.checkUpdateInterval = undefined;
|
|
653
666
|
// Calling the shutdown functions with a reason
|
|
654
667
|
for (const plugin of this.registeredPlugins) {
|
|
655
668
|
if (!plugin.enabled || plugin.error)
|
|
@@ -1038,93 +1051,85 @@ export class Matterbridge extends EventEmitter {
|
|
|
1038
1051
|
this.mattercontrollerContext = undefined;
|
|
1039
1052
|
}
|
|
1040
1053
|
async testStartMatterBridge() {
|
|
1041
|
-
|
|
1042
|
-
// Plugins are started and configured by callback when Matterbridge is commissioned
|
|
1054
|
+
/*
|
|
1043
1055
|
if (!this.storageManager) {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1056
|
+
this.log.error('No storage manager initialized');
|
|
1057
|
+
await this.cleanup('No storage manager initialized');
|
|
1058
|
+
return;
|
|
1047
1059
|
}
|
|
1048
1060
|
this.log.debug('Starting matterbridge in mode', this.bridgeMode);
|
|
1049
1061
|
this.matterServer = this.createMatterServer(this.storageManager);
|
|
1062
|
+
|
|
1050
1063
|
this.log.debug('***Starting startMatterbridge interval for Matterbridge');
|
|
1051
1064
|
let failCount = 0;
|
|
1052
1065
|
const startInterval = setInterval(async () => {
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
}
|
|
1063
|
-
else {
|
|
1064
|
-
return;
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
clearInterval(startInterval);
|
|
1069
|
-
this.log.debug('***Cleared startMatterbridge interval for Matterbridge');
|
|
1070
|
-
this.log.debug(`Creating commissioning server context for ${plg}Matterbridge${db}`);
|
|
1071
|
-
this.matterbridgeContext = await this.createCommissioningServerContext('Matterbridge', 'Matterbridge', DeviceTypes.AGGREGATOR.code, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Aggregator');
|
|
1072
|
-
if (!this.matterbridgeContext) {
|
|
1073
|
-
this.log.error(`Error creating storage context for ${plg}Matterbridge${er}`);
|
|
1074
|
-
return;
|
|
1075
|
-
}
|
|
1076
|
-
if (!this.nodeContext) {
|
|
1077
|
-
this.log.error(`Node storage context undefined for ${plg}Matterbridge${er}`);
|
|
1066
|
+
for (const plugin of this.registeredPlugins) {
|
|
1067
|
+
if (!plugin.enabled) continue;
|
|
1068
|
+
if (!plugin.loaded) {
|
|
1069
|
+
this.log.info(`***Waiting (failSafeCount=${failCount}/30) in startMatterbridge interval for plugin ${plg}${plugin.name}${db} loaded: ${plugin.loaded}...`);
|
|
1070
|
+
failCount++;
|
|
1071
|
+
if (failCount > 30) {
|
|
1072
|
+
this.log.error(`***Failed to load plugin ${plg}${plugin.name}${er}`);
|
|
1073
|
+
plugin.error = true;
|
|
1074
|
+
} else {
|
|
1078
1075
|
return;
|
|
1076
|
+
}
|
|
1079
1077
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
this.
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1078
|
+
}
|
|
1079
|
+
clearInterval(startInterval);
|
|
1080
|
+
this.log.debug('***Cleared startMatterbridge interval for Matterbridge');
|
|
1081
|
+
|
|
1082
|
+
this.log.debug(`Creating commissioning server context for ${plg}Matterbridge${db}`);
|
|
1083
|
+
this.matterbridgeContext = await this.createCommissioningServerContext('Matterbridge', 'Matterbridge', DeviceTypes.AGGREGATOR.code, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Aggregator');
|
|
1084
|
+
if (!this.matterbridgeContext) {
|
|
1085
|
+
this.log.error(`Error creating storage context for ${plg}Matterbridge${er}`);
|
|
1086
|
+
return;
|
|
1087
|
+
}
|
|
1088
|
+
if (!this.nodeContext) {
|
|
1089
|
+
this.log.error(`Node storage context undefined for ${plg}Matterbridge${er}`);
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
await this.matterbridgeContext.set('softwareVersion', 1);
|
|
1093
|
+
await this.matterbridgeContext.set('softwareVersionString', this.matterbridgeVersion);
|
|
1094
|
+
this.log.debug(`Creating commissioning server for ${plg}Matterbridge${db}`);
|
|
1095
|
+
this.commissioningServer = await this.createCommisioningServer(this.matterbridgeContext, 'Matterbridge');
|
|
1096
|
+
|
|
1097
|
+
this.log.debug(`Creating matter aggregator for ${plg}Matterbridge${db}`);
|
|
1098
|
+
this.matterAggregator = await this.createMatterAggregator(this.matterbridgeContext, 'Matterbridge');
|
|
1099
|
+
this.log.debug('Adding matterbridge aggregator to commissioning server');
|
|
1100
|
+
this.commissioningServer.addDevice(this.matterAggregator);
|
|
1101
|
+
|
|
1102
|
+
const device = new MatterbridgeDevice(DeviceTypes.CONTACT_SENSOR);
|
|
1103
|
+
device.createDefaultIdentifyClusterServer();
|
|
1104
|
+
device.createDefaultBridgedDeviceBasicInformationClusterServer('Boolean test', '0x89930475', 0x8000, 'Matterbridge', 'Boolean');
|
|
1105
|
+
device.createDefaultBooleanStateClusterServer(true);
|
|
1106
|
+
device.createDefaultPowerSourceReplaceableBatteryClusterServer(75);
|
|
1107
|
+
device.createDefaultPowerSourceConfigurationClusterServer(1);
|
|
1108
|
+
|
|
1109
|
+
this.log.debug('Adding matterbridge commissioning server to matter server');
|
|
1110
|
+
await this.matterServer?.addCommissioningServer(this.commissioningServer, { uniqueStorageKey: 'Matterbridge' });
|
|
1111
|
+
this.log.debug(`Setting reachability to true for ${plg}Matterbridge${db}`);
|
|
1112
|
+
this.commissioningServer.setReachability(true);
|
|
1113
|
+
this.log.debug('Starting matter server...');
|
|
1114
|
+
await this.startMatterServer();
|
|
1115
|
+
this.log.info('Matter server started');
|
|
1116
|
+
await this.showCommissioningQRCode(this.commissioningServer, this.matterbridgeContext, this.nodeContext, 'Matterbridge');
|
|
1117
|
+
|
|
1118
|
+
setTimeout(() => {
|
|
1119
|
+
this.matterAggregator?.addBridgedDevice(device);
|
|
1120
|
+
this.log.info('Added device to aggregator');
|
|
1121
|
+
}, 30 * 1000);
|
|
1122
|
+
|
|
1123
|
+
setInterval(() => {
|
|
1124
|
+
const cluster = device.getClusterServer(BooleanStateCluster);
|
|
1125
|
+
if (!cluster) return;
|
|
1126
|
+
const contact = cluster.getStateValueAttribute();
|
|
1127
|
+
cluster.setStateValueAttribute(!contact);
|
|
1128
|
+
if (cluster.isEventSupportedByName('stateChange')) cluster.triggerStateChangeEvent!({ stateValue: !contact });
|
|
1129
|
+
this.log.info('Set attribute and event for BooleanStateCluster to', !contact);
|
|
1130
|
+
}, 60 * 1000);
|
|
1127
1131
|
}, 1000);
|
|
1132
|
+
*/
|
|
1128
1133
|
}
|
|
1129
1134
|
/**
|
|
1130
1135
|
* Loads the schema for a plugin.
|
|
@@ -1431,18 +1436,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1431
1436
|
plugin.registeredDevices = 0;
|
|
1432
1437
|
plugin.addedDevices = 0;
|
|
1433
1438
|
await this.nodeContext?.set('plugins', await this.getBaseRegisteredPlugins());
|
|
1434
|
-
this.
|
|
1435
|
-
.then(async (latestVersion) => {
|
|
1436
|
-
plugin.latestVersion = latestVersion;
|
|
1437
|
-
await this.nodeContext?.set('plugins', await this.getBaseRegisteredPlugins());
|
|
1438
|
-
if (plugin.version !== latestVersion)
|
|
1439
|
-
this.log.warn(`The plugin ${plg}${plugin.name}${wr} is out of date. Current version: ${plugin.version}, Latest version: ${latestVersion}`);
|
|
1440
|
-
else
|
|
1441
|
-
this.log.info(`The plugin ${plg}${plugin.name}${nf} is up to date. Current version: ${plugin.version}, Latest version: ${latestVersion}`);
|
|
1442
|
-
})
|
|
1443
|
-
.catch((error) => {
|
|
1444
|
-
this.log.error(`Error getting ${plugin.name} latest version: ${error}`);
|
|
1445
|
-
});
|
|
1439
|
+
await this.getPluginLatestVersion(plugin);
|
|
1446
1440
|
this.log.info(`Loaded plugin ${plg}${plugin.name}${nf} type ${typ}${platform.type} ${db}(entrypoint ${UNDERLINE}${pluginEntry}${UNDERLINEOFF})`);
|
|
1447
1441
|
if (start)
|
|
1448
1442
|
this.startPlugin(plugin, message); // No await do it asyncronously
|
|
@@ -1675,7 +1669,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1675
1669
|
this.log.debug(`Creating commissioning server for ${plg}Matterbridge${db}`);
|
|
1676
1670
|
this.commissioningServer = await this.createCommisioningServer(this.matterbridgeContext, 'Matterbridge');
|
|
1677
1671
|
this.log.debug(`Creating matter aggregator for ${plg}Matterbridge${db}`);
|
|
1678
|
-
this.matterAggregator = await this.createMatterAggregator(this.matterbridgeContext);
|
|
1672
|
+
this.matterAggregator = await this.createMatterAggregator(this.matterbridgeContext, 'Matterbridge');
|
|
1679
1673
|
this.log.debug('Adding matterbridge aggregator to commissioning server');
|
|
1680
1674
|
this.commissioningServer.addDevice(this.matterAggregator);
|
|
1681
1675
|
this.log.debug('Adding matterbridge commissioning server to matter server');
|
|
@@ -1739,7 +1733,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1739
1733
|
this.log.debug(`Creating commissioning server for ${plg}${plugin.name}${db}`);
|
|
1740
1734
|
plugin.commissioningServer = await this.createCommisioningServer(plugin.storageContext, plugin.name);
|
|
1741
1735
|
this.log.debug(`Creating aggregator for plugin ${plg}${plugin.name}${db}`);
|
|
1742
|
-
plugin.aggregator = await this.createMatterAggregator(plugin.storageContext); // Generate serialNumber and uniqueId
|
|
1736
|
+
plugin.aggregator = await this.createMatterAggregator(plugin.storageContext, plugin.name); // Generate serialNumber and uniqueId
|
|
1743
1737
|
this.log.debug(`Adding matter aggregator to commissioning server for plugin ${plg}${plugin.name}${db}`);
|
|
1744
1738
|
plugin.commissioningServer.addDevice(plugin.aggregator);
|
|
1745
1739
|
this.log.debug(`Adding commissioning server to matter server for plugin ${plg}${plugin.name}${db}`);
|
|
@@ -1813,6 +1807,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1813
1807
|
this.log.debug('Starting matter server...');
|
|
1814
1808
|
await this.matterServer.start();
|
|
1815
1809
|
this.log.debug('Started matter server');
|
|
1810
|
+
//this.commissioningServer?.getRootEndpoint() && logEndpoint(this.commissioningServer?.getRootEndpoint());
|
|
1816
1811
|
}
|
|
1817
1812
|
/**
|
|
1818
1813
|
* Imports the commissioning server context for a specific plugin and device.
|
|
@@ -2167,48 +2162,48 @@ export class Matterbridge extends EventEmitter {
|
|
|
2167
2162
|
}
|
|
2168
2163
|
},
|
|
2169
2164
|
});
|
|
2165
|
+
/*
|
|
2170
2166
|
const gdcCluster = commissioningServer.getRootClusterServer(GeneralDiagnosticsCluster);
|
|
2171
2167
|
if (gdcCluster) {
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
}
|
|
2210
|
-
|
|
2211
|
-
this.log.warn(`*GeneralDiagnosticsCluster not found for ${plg}${pluginName}${wr}`);
|
|
2168
|
+
// console.log('GeneralDiagnosticsCluster found for', plg, pluginName, db);
|
|
2169
|
+
// console.log('GeneralDiagnosticsCluster', gdcCluster);
|
|
2170
|
+
// We have like "30:f6:ef:69:2b:c5" in this.systemInformation.macAddress
|
|
2171
|
+
const macArray = this.systemInformation.macAddress.split(':').map((hex) => parseInt(hex, 16));
|
|
2172
|
+
let hardwareAddress = new Uint8Array(macArray);
|
|
2173
|
+
if (hardwareAddress.length === 6) hardwareAddress = Uint8Array.from([0, 0, ...hardwareAddress]);
|
|
2174
|
+
// We have like "192.168.1.189" in this.systemInformation.ipv4Address
|
|
2175
|
+
const ipv4Array = this.systemInformation.ipv4Address.split('.').map((num) => parseInt(num));
|
|
2176
|
+
const iPv4Address = new Uint8Array(ipv4Array);
|
|
2177
|
+
// We have like "fd78:cbf8:4939:746:d555:85a9:74f6:9c6" in this.systemInformation.ipv6Address
|
|
2178
|
+
const ipv6Groups = this.systemInformation.ipv6Address.split(':');
|
|
2179
|
+
const ipv6Array = [];
|
|
2180
|
+
for (const group of ipv6Groups) {
|
|
2181
|
+
const decimal = parseInt(group, 16);
|
|
2182
|
+
ipv6Array.push(decimal >> 8); // High byte
|
|
2183
|
+
ipv6Array.push(decimal & 0xff); // Low byte
|
|
2184
|
+
}
|
|
2185
|
+
const iPv6Address = new Uint8Array(ipv6Array);
|
|
2186
|
+
this.log.debug(`GeneralDiagnosticsCluster for ${plg}${pluginName}${db} hardwareAddress ${this.systemInformation.macAddress} => ${debugStringify(hardwareAddress)}`);
|
|
2187
|
+
this.log.debug(`GeneralDiagnosticsCluster for ${plg}${pluginName}${db} iPv4Address ${this.systemInformation.ipv4Address} => ${debugStringify(iPv4Address)}`);
|
|
2188
|
+
this.log.debug(`GeneralDiagnosticsCluster for ${plg}${pluginName}${db} iPv6Address ${this.systemInformation.ipv6Address} => ${debugStringify(iPv6Address)}`);
|
|
2189
|
+
try {
|
|
2190
|
+
gdcCluster.setNetworkInterfacesAttribute([
|
|
2191
|
+
{
|
|
2192
|
+
name: 'eth0',
|
|
2193
|
+
isOperational: true,
|
|
2194
|
+
offPremiseServicesReachableIPv4: null,
|
|
2195
|
+
offPremiseServicesReachableIPv6: null,
|
|
2196
|
+
hardwareAddress,
|
|
2197
|
+
iPv4Addresses: [iPv4Address],
|
|
2198
|
+
iPv6Addresses: [iPv6Address],
|
|
2199
|
+
type: GeneralDiagnostics.InterfaceType.Ethernet,
|
|
2200
|
+
},
|
|
2201
|
+
]);
|
|
2202
|
+
} catch (error) {
|
|
2203
|
+
this.log.error(`GeneralDiagnosticsCluster.setNetworkInterfacesAttribute for ${plg}${pluginName}${er} error:`, error);
|
|
2204
|
+
}
|
|
2205
|
+
} else this.log.warn(`*GeneralDiagnosticsCluster not found for ${plg}${pluginName}${wr}`);
|
|
2206
|
+
*/
|
|
2212
2207
|
commissioningServer.addCommandHandler('testEventTrigger', async ({ request: { enableKey, eventTrigger } }) => this.log.info(`testEventTrigger called on GeneralDiagnostic cluster: ${enableKey} ${eventTrigger}`));
|
|
2213
2208
|
return commissioningServer;
|
|
2214
2209
|
}
|
|
@@ -2228,10 +2223,13 @@ export class Matterbridge extends EventEmitter {
|
|
|
2228
2223
|
* @param {StorageContext} context - The storage context.
|
|
2229
2224
|
* @returns {Aggregator} - The created Matter Aggregator.
|
|
2230
2225
|
*/
|
|
2231
|
-
async createMatterAggregator(context) {
|
|
2226
|
+
async createMatterAggregator(context, pluginName) {
|
|
2232
2227
|
const random = 'AG' + CryptoNode.getRandomData(8).toHex();
|
|
2233
2228
|
await context.set('aggregatorSerialNumber', await context.get('aggregatorSerialNumber', random));
|
|
2234
2229
|
await context.set('aggregatorUniqueId', await context.get('aggregatorUniqueId', random));
|
|
2230
|
+
this.log.debug(`Creating matter aggregator for plugin ${plg}${pluginName}${db} with uniqueId ${await context.get('aggregatorUniqueId')} serialNumber ${await context.get('aggregatorSerialNumber')}`);
|
|
2231
|
+
this.log.debug(`Creating matter aggregator for plugin ${plg}${pluginName}${db} with softwareVersion ${await context.get('softwareVersion', 1)} softwareVersionString ${await context.get('softwareVersionString', '1.0.0')}`);
|
|
2232
|
+
this.log.debug(`Creating matter aggregator for plugin ${plg}${pluginName}${db} with hardwareVersion ${await context.get('hardwareVersion', 1)} hardwareVersionString ${await context.get('hardwareVersionString', '1.0.0')}`);
|
|
2235
2233
|
const matterAggregator = new Aggregator();
|
|
2236
2234
|
matterAggregator.addClusterServer(ClusterServer(BasicInformationCluster, {
|
|
2237
2235
|
dataModelRevision: 1,
|
|
@@ -2444,6 +2442,20 @@ export class Matterbridge extends EventEmitter {
|
|
|
2444
2442
|
if (this.nodeContext)
|
|
2445
2443
|
this.matterbridgeLatestVersion = await this.nodeContext.get('matterbridgeLatestVersion', '');
|
|
2446
2444
|
this.log.debug(`Matterbridge Latest Version: ${this.matterbridgeLatestVersion}`);
|
|
2445
|
+
await this.getMatterbridgeLatestVersion();
|
|
2446
|
+
// Current working directory
|
|
2447
|
+
const currentDir = process.cwd();
|
|
2448
|
+
this.log.debug(`Current Working Directory: ${currentDir}`);
|
|
2449
|
+
// Command line arguments (excluding 'node' and the script name)
|
|
2450
|
+
const cmdArgs = process.argv.slice(2).join(' ');
|
|
2451
|
+
this.log.debug(`Command Line Arguments: ${cmdArgs}`);
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* Retrieves the latest version of Matterbridge and performs necessary actions based on the version comparison.
|
|
2455
|
+
* @private
|
|
2456
|
+
* @returns {Promise<void>} A promise that resolves when the latest version is retrieved and actions are performed.
|
|
2457
|
+
*/
|
|
2458
|
+
async getMatterbridgeLatestVersion() {
|
|
2447
2459
|
this.getLatestVersion('matterbridge')
|
|
2448
2460
|
.then(async (matterbridgeLatestVersion) => {
|
|
2449
2461
|
this.matterbridgeLatestVersion = matterbridgeLatestVersion;
|
|
@@ -2455,14 +2467,34 @@ export class Matterbridge extends EventEmitter {
|
|
|
2455
2467
|
}
|
|
2456
2468
|
})
|
|
2457
2469
|
.catch((error) => {
|
|
2458
|
-
this.log.error(`Error getting Matterbridge latest version: ${error}`);
|
|
2470
|
+
this.log.error(`Error getting Matterbridge latest version: ${error.message}`);
|
|
2471
|
+
error.stack && this.log.debug(error.stack);
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
/**
|
|
2475
|
+
* Retrieves the latest version of a plugin and updates the plugin's latestVersion property.
|
|
2476
|
+
* If the plugin's version is different from the latest version, logs a warning message.
|
|
2477
|
+
* If the plugin's version is the same as the latest version, logs an info message.
|
|
2478
|
+
* If there is an error retrieving the latest version, logs an error message.
|
|
2479
|
+
*
|
|
2480
|
+
* @private
|
|
2481
|
+
* @param {RegisteredPlugin} plugin - The plugin for which to retrieve the latest version.
|
|
2482
|
+
* @returns {Promise<void>} A promise that resolves when the latest version is retrieved and actions are performed.
|
|
2483
|
+
*/
|
|
2484
|
+
async getPluginLatestVersion(plugin) {
|
|
2485
|
+
this.getLatestVersion(plugin.name)
|
|
2486
|
+
.then(async (latestVersion) => {
|
|
2487
|
+
plugin.latestVersion = latestVersion;
|
|
2488
|
+
await this.nodeContext?.set('plugins', await this.getBaseRegisteredPlugins());
|
|
2489
|
+
if (plugin.version !== latestVersion)
|
|
2490
|
+
this.log.warn(`The plugin ${plg}${plugin.name}${wr} is out of date. Current version: ${plugin.version}, Latest version: ${latestVersion}`);
|
|
2491
|
+
else
|
|
2492
|
+
this.log.info(`The plugin ${plg}${plugin.name}${nf} is up to date. Current version: ${plugin.version}, Latest version: ${latestVersion}`);
|
|
2493
|
+
})
|
|
2494
|
+
.catch((error) => {
|
|
2495
|
+
this.log.error(`Error getting ${plugin.name} latest version: ${error.message}`);
|
|
2496
|
+
error.stack && this.log.debug(error.stack);
|
|
2459
2497
|
});
|
|
2460
|
-
// Current working directory
|
|
2461
|
-
const currentDir = process.cwd();
|
|
2462
|
-
this.log.debug(`Current Working Directory: ${currentDir}`);
|
|
2463
|
-
// Command line arguments (excluding 'node' and the script name)
|
|
2464
|
-
const cmdArgs = process.argv.slice(2).join(' ');
|
|
2465
|
-
this.log.debug(`Command Line Arguments: ${cmdArgs}`);
|
|
2466
2498
|
}
|
|
2467
2499
|
/**
|
|
2468
2500
|
* Retrieves an array of base registered plugins.
|