matterbridge 2.1.6-dev.1 → 2.1.6-dev.3
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 +3 -2
- package/dist/cli.js +104 -1
- package/dist/frontend.js +2 -15
- package/dist/matter/export.js +1 -1
- package/dist/matterbridge.js +1 -0
- package/dist/matterbridgePlatform.js +27 -20
- package/dist/pluginManager.js +26 -30
- package/frontend/build/matterbridge 32x32.png +0 -0
- package/frontend/build/matterbridge 64x64.png +0 -0
- package/frontend/build/matterbridge.svg +50 -0
- package/frontend/build/static/js/main.a241d4f0.js.map +1 -1
- package/npm-shrinkwrap.json +47 -47
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -33,18 +33,19 @@ matterbridge-zigbee2mqtt v. 2.4.4
|
|
|
33
33
|
matterbridge-somfy-tahoma v. 1.2.3
|
|
34
34
|
matterbridge-hass v. 0.0.8
|
|
35
35
|
|
|
36
|
-
## [2.1.6] - 2025-02-
|
|
36
|
+
## [2.1.6] - 2025-02-13
|
|
37
37
|
|
|
38
38
|
### Added
|
|
39
39
|
|
|
40
40
|
- [docker]: Added health check directly inside the docker image. No need to change configuration.
|
|
41
|
-
- [platform]:
|
|
41
|
+
- [platform]: Saving in the storage the selects for faster loading of plugins.
|
|
42
42
|
- [icon]: Added matterbridge svg icon (thanks: https://github.com/robvanoostenrijk https://github.com/stuntguy3000).
|
|
43
43
|
- [frontend]: Frontend v.2.4.2.
|
|
44
44
|
|
|
45
45
|
### Changed
|
|
46
46
|
|
|
47
47
|
- [package]: Update matter.js to 0.12.4-alpha.0-20250212-b2729c9eb
|
|
48
|
+
- [package]: Update matter.js to 0.12.4-alpha.0-20250213-1187f81eb
|
|
48
49
|
|
|
49
50
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
50
51
|
<img src="./yellow-button.png" alt="Buy me a coffee" width="120">
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Matterbridge } from './matterbridge.js';
|
|
3
3
|
let instance;
|
|
4
|
+
let session;
|
|
5
|
+
let memoryCheckInterval;
|
|
6
|
+
let prevCpus;
|
|
7
|
+
let lastCpuUsage = 0;
|
|
4
8
|
const cli = '\u001B[32m';
|
|
5
9
|
const er = '\u001B[38;5;9m';
|
|
6
10
|
const rs = '\u001B[40;0m';
|
|
11
|
+
const db = '\u001B[38;5;245m';
|
|
12
|
+
const CYAN = '\u001B[36m';
|
|
13
|
+
const YELLOW = '\u001B[33m';
|
|
14
|
+
const BRIGHT = '\u001B[1m';
|
|
7
15
|
async function main() {
|
|
16
|
+
if (process.argv.includes('-memorycheck'))
|
|
17
|
+
await startMemoryCheck();
|
|
18
|
+
if (process.argv.includes('-inspector'))
|
|
19
|
+
await startInspector();
|
|
8
20
|
if (process.argv.includes('-debug'))
|
|
9
21
|
console.log(cli + `CLI: ${process.argv.includes('-edge') ? 'MatterbridgeEdge' : 'Matterbridge'}.loadInstance() called` + rs);
|
|
10
22
|
instance = await Matterbridge.loadInstance(true);
|
|
@@ -12,6 +24,90 @@ async function main() {
|
|
|
12
24
|
if (process.argv.includes('-debug'))
|
|
13
25
|
console.log(cli + `CLI: ${process.argv.includes('-edge') ? 'MatterbridgeEdge' : 'Matterbridge'}.loadInstance() exited` + rs);
|
|
14
26
|
}
|
|
27
|
+
async function startMemoryCheck() {
|
|
28
|
+
const os = await import('node:os');
|
|
29
|
+
console.log(cli + `CLI: Memory check started` + rs);
|
|
30
|
+
prevCpus = os.cpus();
|
|
31
|
+
const formatMemoryUsage = (bytes) => {
|
|
32
|
+
if (bytes >= 1024 ** 3) {
|
|
33
|
+
return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
|
|
34
|
+
}
|
|
35
|
+
else if (bytes >= 1024 ** 2) {
|
|
36
|
+
return `${(bytes / 1024 ** 2).toFixed(2)} MB`;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const interval = () => {
|
|
43
|
+
const currCpus = os.cpus();
|
|
44
|
+
let cpuUsageLog;
|
|
45
|
+
if (currCpus.length !== prevCpus.length) {
|
|
46
|
+
prevCpus = currCpus;
|
|
47
|
+
cpuUsageLog = lastCpuUsage.toFixed(2);
|
|
48
|
+
}
|
|
49
|
+
let totalIdle = 0, totalTick = 0;
|
|
50
|
+
prevCpus.forEach((prevCpu, i) => {
|
|
51
|
+
const currCpu = currCpus[i];
|
|
52
|
+
const idleDiff = currCpu.times.idle - prevCpu.times.idle;
|
|
53
|
+
const totalDiff = Object.keys(currCpu.times).reduce((acc, key) => acc + (currCpu.times[key] - prevCpu.times[key]), 0);
|
|
54
|
+
totalIdle += idleDiff;
|
|
55
|
+
totalTick += totalDiff;
|
|
56
|
+
});
|
|
57
|
+
const cpuUsage = 100 - (totalIdle / totalTick) * 100;
|
|
58
|
+
if (totalTick === 0 || isNaN(cpuUsage) || !isFinite(cpuUsage) || cpuUsage <= 0) {
|
|
59
|
+
cpuUsageLog = lastCpuUsage.toFixed(2);
|
|
60
|
+
}
|
|
61
|
+
prevCpus = currCpus;
|
|
62
|
+
lastCpuUsage = cpuUsage;
|
|
63
|
+
cpuUsageLog = cpuUsage.toFixed(2);
|
|
64
|
+
const memoryUsageRaw = process.memoryUsage();
|
|
65
|
+
const memoryUsage = {
|
|
66
|
+
rss: formatMemoryUsage(memoryUsageRaw.rss),
|
|
67
|
+
heapTotal: formatMemoryUsage(memoryUsageRaw.heapTotal),
|
|
68
|
+
heapUsed: formatMemoryUsage(memoryUsageRaw.heapUsed),
|
|
69
|
+
external: formatMemoryUsage(memoryUsageRaw.external),
|
|
70
|
+
arrayBuffers: formatMemoryUsage(memoryUsageRaw.arrayBuffers),
|
|
71
|
+
};
|
|
72
|
+
console.log(`${YELLOW}${BRIGHT}Cpu usage:${db} ${CYAN}${cpuUsageLog.padStart(6, ' ')} %${db} ${YELLOW}${BRIGHT}Memory usage:${db} rss ${CYAN}${memoryUsage.rss}${db} heapTotal ${CYAN}${memoryUsage.heapTotal}${db} heapUsed ${CYAN}${memoryUsage.heapUsed}${db} external ${memoryUsage.external} arrayBuffers ${memoryUsage.arrayBuffers}` +
|
|
73
|
+
rs);
|
|
74
|
+
};
|
|
75
|
+
interval();
|
|
76
|
+
memoryCheckInterval = setInterval(interval, 1000);
|
|
77
|
+
}
|
|
78
|
+
async function stopMemoryCheck() {
|
|
79
|
+
console.log(cli + `CLI: Stopping memory check in 5 minute` + rs);
|
|
80
|
+
instance = undefined;
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
console.log(cli + `CLI: Memory check stopped` + rs);
|
|
83
|
+
clearInterval(memoryCheckInterval);
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}, 5 * 60 * 1000);
|
|
86
|
+
}
|
|
87
|
+
async function startInspector() {
|
|
88
|
+
const { Session } = await import('node:inspector');
|
|
89
|
+
session = new Session();
|
|
90
|
+
session.connect();
|
|
91
|
+
session.post('HeapProfiler.startSampling', {}, (err) => {
|
|
92
|
+
if (err)
|
|
93
|
+
console.error(err);
|
|
94
|
+
else
|
|
95
|
+
console.log(cli + `CLI: Heap sampling started` + rs);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async function stopInspector() {
|
|
99
|
+
const { writeFileSync } = await import('node:fs');
|
|
100
|
+
session.post('HeapProfiler.stopSampling', (err, result) => {
|
|
101
|
+
if (err) {
|
|
102
|
+
console.error(err);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const profile = JSON.stringify(result.profile, null, 2);
|
|
106
|
+
writeFileSync('heap-sampling-profile.heapsampling.json', profile);
|
|
107
|
+
console.log(cli + `CLI: Heap sampling profile saved to heap-sampling-profile.heapsnapshot` + rs);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
15
111
|
function registerHandlers() {
|
|
16
112
|
if (instance)
|
|
17
113
|
instance.on('shutdown', async () => shutdown());
|
|
@@ -23,7 +119,14 @@ function registerHandlers() {
|
|
|
23
119
|
async function shutdown() {
|
|
24
120
|
if (process.argv.includes('-debug'))
|
|
25
121
|
console.log(cli + 'CLI: received shutdown event, exiting...' + rs);
|
|
26
|
-
process.
|
|
122
|
+
if (process.argv.includes('-inspector'))
|
|
123
|
+
await stopInspector();
|
|
124
|
+
if (process.argv.includes('-memorycheck')) {
|
|
125
|
+
await stopMemoryCheck();
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
process.exit(0);
|
|
129
|
+
}
|
|
27
130
|
}
|
|
28
131
|
async function restart() {
|
|
29
132
|
if (process.argv.includes('-debug'))
|
package/dist/frontend.js
CHANGED
|
@@ -752,17 +752,6 @@ export class Frontend {
|
|
|
752
752
|
this.log.debug(`Frontend initialized on port ${YELLOW}${this.port}${db} static ${UNDERLINE}${path.join(this.matterbridge.rootDirectory, 'frontend/build')}${UNDERLINEOFF}${rs}`);
|
|
753
753
|
}
|
|
754
754
|
async stop() {
|
|
755
|
-
if (hasParameter('memorycheck')) {
|
|
756
|
-
this.wssSendSnackbarMessage('Memory check started', getIntParameter('memorycheck') ?? 5 * 60 * 1000);
|
|
757
|
-
await new Promise((resolve) => {
|
|
758
|
-
this.log.debug(`***Memory check started for ${getIntParameter('memorycheck') ?? 5 * 60 * 1000} ms`);
|
|
759
|
-
setTimeout(() => {
|
|
760
|
-
this.wssSendSnackbarMessage('Memory check stopped', 10);
|
|
761
|
-
this.log.debug(`***Memory check stopped after ${getIntParameter('memorycheck') ?? 5 * 60 * 1000} ms`);
|
|
762
|
-
resolve();
|
|
763
|
-
}, getIntParameter('memorycheck') ?? 5 * 60 * 1000);
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
755
|
if (this.httpServer) {
|
|
767
756
|
this.httpServer.close();
|
|
768
757
|
this.httpServer.removeAllListeners();
|
|
@@ -877,12 +866,10 @@ export class Frontend {
|
|
|
877
866
|
this.wssSendMemoryUpdate(this.matterbridge.systemInformation.freeMemory, this.matterbridge.systemInformation.totalMemory, this.matterbridge.systemInformation.systemUptime, this.matterbridge.systemInformation.rss, this.matterbridge.systemInformation.heapUsed, this.matterbridge.systemInformation.heapTotal);
|
|
878
867
|
};
|
|
879
868
|
interval();
|
|
880
|
-
this.memoryInterval = setInterval(interval, getIntParameter('memoryinterval') ?? 1000);
|
|
881
|
-
this.memoryInterval.unref();
|
|
869
|
+
this.memoryInterval = setInterval(interval, getIntParameter('memoryinterval') ?? 1000).unref();
|
|
882
870
|
this.memoryTimeout = setTimeout(() => {
|
|
883
871
|
this.stopCpuMemoryDump();
|
|
884
|
-
}, getIntParameter('memorytimeout') ?? 600000);
|
|
885
|
-
this.memoryTimeout.unref();
|
|
872
|
+
}, getIntParameter('memorytimeout') ?? 600000).unref();
|
|
886
873
|
}
|
|
887
874
|
stopCpuMemoryDump() {
|
|
888
875
|
clearInterval(this.memoryInterval);
|
package/dist/matter/export.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from '@matter/main';
|
|
2
2
|
export { SemanticNamespace, ClosureTag, CompassDirectionTag, CompassLocationTag, DirectionTag, ElectricalMeasurementTag, LaundryTag, LevelTag, LocationTag, NumberTag, PositionTag, PowerSourceTag, RefrigeratorTag, RoomAirConditionerTag, SwitchesTag, } from '@matter/main';
|
|
3
3
|
export { AttributeElement, ClusterElement, ClusterModel, CommandElement, EventElement, FieldElement } from '@matter/main/model';
|
|
4
|
-
export { logEndpoint, MdnsService } from '@matter/main/protocol';
|
|
4
|
+
export { logEndpoint, MdnsService, Val } from '@matter/main/protocol';
|
package/dist/matterbridge.js
CHANGED
|
@@ -1443,6 +1443,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1443
1443
|
sanitizeFabrics(serverNode.state.commissioning.fabrics, true);
|
|
1444
1444
|
}
|
|
1445
1445
|
this.frontend.wssSendRefreshRequired();
|
|
1446
|
+
this.frontend.wssSendSnackbarMessage(`${storeId} is online`);
|
|
1446
1447
|
});
|
|
1447
1448
|
serverNode.lifecycle.offline.on(() => {
|
|
1448
1449
|
this.log.notice(`Server node for ${storeId} is offline`);
|
|
@@ -14,6 +14,10 @@ export class MatterbridgePlatform {
|
|
|
14
14
|
context;
|
|
15
15
|
selectDevice = new Map();
|
|
16
16
|
selectEntity = new Map();
|
|
17
|
+
contextReady;
|
|
18
|
+
selectDeviceContextReady;
|
|
19
|
+
selectEntityContextReady;
|
|
20
|
+
ready;
|
|
17
21
|
registeredEndpoints = new Map();
|
|
18
22
|
registeredEndpointsByName = new Map();
|
|
19
23
|
constructor(matterbridge, log, config) {
|
|
@@ -31,26 +35,28 @@ export class MatterbridgePlatform {
|
|
|
31
35
|
forgiveParseErrors: true,
|
|
32
36
|
});
|
|
33
37
|
this.log.debug(`Creating context for plugin ${this.config.name}`);
|
|
34
|
-
this.storage.createStorage('context').then((context) => {
|
|
38
|
+
this.contextReady = this.storage.createStorage('context').then((context) => {
|
|
35
39
|
this.context = context;
|
|
36
40
|
this.log.debug(`Created context for plugin ${this.config.name}`);
|
|
41
|
+
return context;
|
|
37
42
|
});
|
|
38
43
|
this.log.debug(`Loading selectDevice for plugin ${this.config.name}`);
|
|
39
|
-
this.storage.createStorage('selectDevice').then((context) => {
|
|
40
|
-
context.get('selectDevice', [])
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
+
this.selectDeviceContextReady = this.storage.createStorage('selectDevice').then(async (context) => {
|
|
45
|
+
const selectDevice = await context.get('selectDevice', []);
|
|
46
|
+
for (const device of selectDevice)
|
|
47
|
+
this.selectDevice.set(device.serial, device);
|
|
44
48
|
this.log.debug(`Loaded ${this.selectDevice.size} selectDevice for plugin ${this.config.name}`);
|
|
45
49
|
});
|
|
46
50
|
this.log.debug(`Loading selectEntity for plugin ${this.config.name}`);
|
|
47
|
-
this.storage.createStorage('selectEntity').then((context) => {
|
|
48
|
-
context.get('selectEntity', [])
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
});
|
|
51
|
+
this.selectEntityContextReady = this.storage.createStorage('selectEntity').then(async (context) => {
|
|
52
|
+
const selectEntity = await context.get('selectEntity', []);
|
|
53
|
+
for (const entity of selectEntity)
|
|
54
|
+
this.selectEntity.set(entity.name, entity);
|
|
52
55
|
this.log.debug(`Loaded ${this.selectEntity.size} selectEntity for plugin ${this.config.name}`);
|
|
53
56
|
});
|
|
57
|
+
this.ready = Promise.all([this.contextReady, this.selectDeviceContextReady, this.selectEntityContextReady]).then(() => {
|
|
58
|
+
this.log.debug(`MatterbridgePlatform for plugin ${this.config.name} is fully initialized`);
|
|
59
|
+
});
|
|
54
60
|
}
|
|
55
61
|
async onStart(reason) {
|
|
56
62
|
this.log.error('Plugins must override onStart.', reason);
|
|
@@ -77,7 +83,9 @@ export class MatterbridgePlatform {
|
|
|
77
83
|
this.selectEntity.clear();
|
|
78
84
|
this.registeredEndpoints.clear();
|
|
79
85
|
this.registeredEndpointsByName.clear();
|
|
80
|
-
this.
|
|
86
|
+
this.contextReady = undefined;
|
|
87
|
+
this.selectDeviceContextReady = undefined;
|
|
88
|
+
this.selectEntityContextReady = undefined;
|
|
81
89
|
await this.context?.close();
|
|
82
90
|
this.context = undefined;
|
|
83
91
|
await this.storage?.close();
|
|
@@ -214,16 +222,15 @@ export class MatterbridgePlatform {
|
|
|
214
222
|
endpointMap.set(device.uniqueId, device.maybeNumber);
|
|
215
223
|
}
|
|
216
224
|
for (const child of device.getChildEndpoints()) {
|
|
217
|
-
|
|
218
|
-
if (!childId || !child.maybeNumber)
|
|
225
|
+
if (!child.maybeId || !child.maybeNumber)
|
|
219
226
|
continue;
|
|
220
|
-
if (endpointMap.has(device.uniqueId + separator +
|
|
221
|
-
this.log.warn(`Child endpoint number for device ${CYAN}${device.deviceName}${wr}.${CYAN}${
|
|
222
|
-
endpointMap.set(device.uniqueId + separator +
|
|
227
|
+
if (endpointMap.has(device.uniqueId + separator + child.id) && endpointMap.get(device.uniqueId + separator + child.id) !== child.maybeNumber) {
|
|
228
|
+
this.log.warn(`Child endpoint number for device ${CYAN}${device.deviceName}${wr}.${CYAN}${child.id}${wr} changed from ${CYAN}${endpointMap.get(device.uniqueId + separator + child.id)}${wr} to ${CYAN}${child.maybeNumber}${wr}`);
|
|
229
|
+
endpointMap.set(device.uniqueId + separator + child.id, child.maybeNumber);
|
|
223
230
|
}
|
|
224
|
-
if (!endpointMap.has(device.uniqueId + separator +
|
|
225
|
-
this.log.debug(`Setting child endpoint number for device ${CYAN}${device.uniqueId}${db}.${CYAN}${
|
|
226
|
-
endpointMap.set(device.uniqueId + separator +
|
|
231
|
+
if (!endpointMap.has(device.uniqueId + separator + child.id)) {
|
|
232
|
+
this.log.debug(`Setting child endpoint number for device ${CYAN}${device.uniqueId}${db}.${CYAN}${child.id}${db} to ${CYAN}${child.maybeNumber}${db}`);
|
|
233
|
+
endpointMap.set(device.uniqueId + separator + child.id, child.maybeNumber);
|
|
227
234
|
}
|
|
228
235
|
}
|
|
229
236
|
}
|
package/dist/pluginManager.js
CHANGED
|
@@ -463,7 +463,7 @@ export class PluginManager {
|
|
|
463
463
|
}
|
|
464
464
|
}
|
|
465
465
|
catch (err) {
|
|
466
|
-
this.log.error(`Failed to load plugin ${plg}${plugin.name}${er}: ${err}`);
|
|
466
|
+
this.log.error(`Failed to load plugin ${plg}${plugin.name}${er}: ${err instanceof Error ? err.message : err}`);
|
|
467
467
|
plugin.error = true;
|
|
468
468
|
}
|
|
469
469
|
return undefined;
|
|
@@ -493,7 +493,7 @@ export class PluginManager {
|
|
|
493
493
|
}
|
|
494
494
|
catch (err) {
|
|
495
495
|
plugin.error = true;
|
|
496
|
-
this.log.error(`Failed to start plugin ${plg}${plugin.name}${er}: ${err}`);
|
|
496
|
+
this.log.error(`Failed to start plugin ${plg}${plugin.name}${er}: ${err instanceof Error ? err.message : err}`);
|
|
497
497
|
}
|
|
498
498
|
return undefined;
|
|
499
499
|
}
|
|
@@ -543,7 +543,7 @@ export class PluginManager {
|
|
|
543
543
|
this.log.debug(`Plugin ${plg}${plugin.name}${db} not configured`);
|
|
544
544
|
}
|
|
545
545
|
if (!plugin.platform) {
|
|
546
|
-
this.log.debug(
|
|
546
|
+
this.log.debug(`Plugin ${plg}${plugin.name}${db} no platform found`);
|
|
547
547
|
return undefined;
|
|
548
548
|
}
|
|
549
549
|
this.log.info(`Shutting down plugin ${plg}${plugin.name}${nf}: ${reason}...`);
|
|
@@ -565,7 +565,7 @@ export class PluginManager {
|
|
|
565
565
|
return plugin;
|
|
566
566
|
}
|
|
567
567
|
catch (err) {
|
|
568
|
-
this.log.error(`Failed to shut down plugin ${plg}${plugin.name}${er}: ${err}`);
|
|
568
|
+
this.log.error(`Failed to shut down plugin ${plg}${plugin.name}${er}: ${err instanceof Error ? err.message : err}`);
|
|
569
569
|
}
|
|
570
570
|
return undefined;
|
|
571
571
|
}
|
|
@@ -585,35 +585,31 @@ export class PluginManager {
|
|
|
585
585
|
return config;
|
|
586
586
|
}
|
|
587
587
|
catch (err) {
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
return config;
|
|
604
|
-
}
|
|
605
|
-
catch (err) {
|
|
606
|
-
this.log.error(`Error creating config file ${configFile} for plugin ${plg}${plugin.name}${er}: ${err}`);
|
|
607
|
-
return config;
|
|
608
|
-
}
|
|
588
|
+
const nodeErr = err;
|
|
589
|
+
if (nodeErr.code === 'ENOENT') {
|
|
590
|
+
let config;
|
|
591
|
+
if (plugin.name === 'matterbridge-zigbee2mqtt')
|
|
592
|
+
config = zigbee2mqtt_config;
|
|
593
|
+
else if (plugin.name === 'matterbridge-somfy-tahoma')
|
|
594
|
+
config = somfytahoma_config;
|
|
595
|
+
else if (plugin.name === 'matterbridge-shelly')
|
|
596
|
+
config = shelly_config;
|
|
597
|
+
else
|
|
598
|
+
config = { name: plugin.name, type: plugin.type, debug: false, unregisterOnShutdown: false };
|
|
599
|
+
try {
|
|
600
|
+
await fs.writeFile(configFile, JSON.stringify(config, null, 2), 'utf8');
|
|
601
|
+
this.log.debug(`Created config file ${configFile} for plugin ${plg}${plugin.name}${db}.`);
|
|
602
|
+
return config;
|
|
609
603
|
}
|
|
610
|
-
|
|
611
|
-
this.log.error(`Error
|
|
612
|
-
return
|
|
604
|
+
catch (err) {
|
|
605
|
+
this.log.error(`Error creating config file ${configFile} for plugin ${plg}${plugin.name}${er}: ${err instanceof Error ? err.message : err}`);
|
|
606
|
+
return config;
|
|
613
607
|
}
|
|
614
608
|
}
|
|
615
|
-
|
|
616
|
-
|
|
609
|
+
else {
|
|
610
|
+
this.log.error(`Error accessing config file ${configFile} for plugin ${plg}${plugin.name}${er}: ${err instanceof Error ? err.message : err}`);
|
|
611
|
+
return { name: plugin.name, type: plugin.type, debug: false, unregisterOnShutdown: false };
|
|
612
|
+
}
|
|
617
613
|
}
|
|
618
614
|
}
|
|
619
615
|
async saveConfigFromPlugin(plugin) {
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 296.2 296.2">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="lg1" x1="16.6" y1="16.6" x2="279.6" y2="279.6" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop offset="0" stop-color="#00b48d" />
|
|
5
|
+
<stop offset=".1" stop-color="#3faa77" />
|
|
6
|
+
<stop offset=".3" stop-color="#234148" />
|
|
7
|
+
<stop offset=".7" stop-color="#203b44" />
|
|
8
|
+
<stop offset=".9" stop-color="#ad2e6e" />
|
|
9
|
+
<stop offset="1" stop-color="#c81b74" />
|
|
10
|
+
</linearGradient>
|
|
11
|
+
<linearGradient id="lg2" x1="31.1" y1="31.1" x2="265.1" y2="265.1" gradientUnits="userSpaceOnUse">
|
|
12
|
+
<stop offset="0" stop-color="#00b48d" />
|
|
13
|
+
<stop offset=".2" stop-color="#285251" />
|
|
14
|
+
<stop offset=".4" stop-color="#234148" />
|
|
15
|
+
<stop offset=".8" stop-color="#203b44" />
|
|
16
|
+
<stop offset=".9" stop-color="#a8316c" />
|
|
17
|
+
<stop offset="1" stop-color="#c81b74" />
|
|
18
|
+
</linearGradient>
|
|
19
|
+
<linearGradient id="lg3" x1="116.2" y1="143.9" x2="139.8" y2="143.9"
|
|
20
|
+
gradientUnits="userSpaceOnUse">
|
|
21
|
+
<stop offset="0" stop-color="#8bc751" />
|
|
22
|
+
<stop offset="1" stop-color="#0db14b" />
|
|
23
|
+
</linearGradient>
|
|
24
|
+
<linearGradient id="lg4" x1="136.1" y1="100.8" x2="159.6" y2="100.8"
|
|
25
|
+
xlink:href="#lg3" />
|
|
26
|
+
<linearGradient id="lg5" x1="155.3" y1="143.9" x2="178.9" y2="143.9"
|
|
27
|
+
xlink:href="#lg3" />
|
|
28
|
+
<linearGradient id="lg6" x1="46.8" y1="25.7" x2="89.6" y2="74.8" gradientUnits="userSpaceOnUse">
|
|
29
|
+
<stop offset="0" stop-color="#b1d34a" />
|
|
30
|
+
<stop offset="1" stop-color="#50b848" />
|
|
31
|
+
</linearGradient>
|
|
32
|
+
</defs>
|
|
33
|
+
<rect width="296.2" height="296.2" rx="56.7" ry="56.7" style="fill:url(#lg1)" />
|
|
34
|
+
<rect x="16.3" y="16.3" width="263.6" height="263.6" rx="50.5" ry="50.5" style="fill:url(#lg2)" />
|
|
35
|
+
<circle cx="128" cy="143.9" r="11.8" style="fill:url(#lg3)" />
|
|
36
|
+
<circle cx="147.8" cy="100.8" r="11.8" style="fill:url(#lg4)" />
|
|
37
|
+
<path
|
|
38
|
+
d="m244.6 114.5.4-.5L160 33a17 17 0 0 0-24.7-.5l-86.4 83.3a15 15 0 0 0 9.2 26.9h19.3v-4.7l-13.7-12.7v-.1l83.7-80.8 84.2 81-13.9 12.8v4.5h19.5a15 15 0 0 0 7.4-28.1Z"
|
|
39
|
+
style="fill:url(#lg3)" />
|
|
40
|
+
<circle cx="167.1" cy="143.9" r="11.8" style="fill:url(#lg5)" />
|
|
41
|
+
<path fill="#fff" d="M219 89.3V35.5a10.5 10.5 0 1 0-21 0v33.7l21 20Z" />
|
|
42
|
+
<path
|
|
43
|
+
d="M91.4 73.3H83a37 37 0 0 0-14.5-28.4L65 50.2c.1 0 12.6 9 11.7 25.4-5.3-.4-11.2-1.9-16.3-5.3-11.8-7.8-16-23.7-11.9-46 8.7 1.5 34 7 43 22.8 4.1 7.3 4.1 16.1 0 26.2Z"
|
|
44
|
+
style="fill:url(#lg6)" />
|
|
45
|
+
<path
|
|
46
|
+
d="M65.9 80a49.6 49.6 0 0 0 17.8 2.2l16.6-16c1.6-8.3.5-15.7-3.3-22.4C84.6 22 47.8 17.5 46.2 17.4l-3-.4-.6 3c-3.8 18.4-5.9 50.6 23.2 60ZM48.4 24.4c8.7 1.5 34 7 43 22.8 4.1 7.3 4.1 16.1 0 26.2H83a37 37 0 0 0-14.5-28.4l-3.7 5.3c.1 0 12.6 9 11.7 25.4-5.3-.4-11.2-1.9-16.3-5.3-11.9-7.8-16-23.7-11.9-46Z"
|
|
47
|
+
fill="#1e5857" />
|
|
48
|
+
<path fill="#fff"
|
|
49
|
+
d="M250.5 90.5a17.4 17.4 0 1 1 0-34.8 17.4 17.4 0 0 1 0 34.8Zm0-22.7a5.4 5.4 0 0 0 0 10.7 5.3 5.3 0 0 0 0-10.7ZM258.8 148.2a15.9 15.9 0 0 0-9.6 28.5c-.8 4.2-5.4 4.6-5.4 4.6h-26v-43l13.6-13-1.8-2-82.2-79-81.2 78.3-2.5 2.6 13.7 13v42.9H53a21.5 21.5 0 1 0 11.7 15h12.6v18.8c0 7.8 6.4 14.1 14.1 14.1h29.3v14.8H64a10.6 10.6 0 0 0-17.7 8 10.6 10.6 0 0 0 17.6 8h157.6a16.3 16.3 0 1 0 0-16h-84.8V229h66.8c7.8 0 14.2-6.3 14.2-14.1v-19.2h27.6c14.3 0 17.8-12.8 18.5-16.6a15.9 15.9 0 0 0-5-30.9ZM43.7 210.8a10.3 10.3 0 1 1 0-20.6 10.3 10.3 0 0 1 0 20.6Zm192 36a5 5 0 1 1 0 10 5 5 0 0 1 0-10Zm-77-34.8h-22v-34h22v34Zm8.4-79.8c2.7 0 5.2 1 7.2 2.5v-10.4L188 137s2.6 1.3 4.6 1.3h6.7v68c0 3.2-2.6 5.7-5.7 5.7h-19v-34h1.4a7.5 7.5 0 0 0 0-15H120a7.5 7.5 0 0 0 0 15h.7v34h-19.3a5.7 5.7 0 0 1-5.7-5.6v-68.1h6.7c2 0 4.6-1.3 4.6-1.3l13.7-12.7v10.4a11.7 11.7 0 0 1 16 1.6v-13a14.9 14.9 0 0 0-25-10.8s-.1.2-.1.2l-.5.5-6.9 7H92.5l55-53.2 55.1 53.2h-11.8l-7-7c0-.2-.2-.3-.4-.5l-.2-.2a14.8 14.8 0 0 0-25 10.9v12.9c2.2-2.5 5.3-4.1 8.9-4.1Zm91.7 36.7a4.9 4.9 0 1 1 0-9.7 4.9 4.9 0 0 1 0 9.7Z" />
|
|
50
|
+
</svg>
|