matterbridge 3.3.0-dev-20251004-43d8106 → 3.3.1-dev-20251007-4e5eaac
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 +29 -3
- package/README.md +9 -1
- package/dist/broadcastServer.js +73 -0
- package/dist/broadcastServerTypes.js +1 -0
- package/dist/deviceManager.js +44 -5
- package/dist/frontend.js +150 -190
- package/dist/helpers.js +4 -4
- package/dist/index.js +0 -12
- package/dist/matterbridge.js +112 -117
- package/dist/matterbridgePlatform.js +1 -1
- package/dist/pluginManager.js +130 -5
- package/dist/shelly.js +4 -4
- package/dist/update.js +0 -2
- package/dist/utils/network.js +71 -38
- package/dist/utils/spawn.js +5 -6
- package/frontend/build/assets/index.js +4 -7
- package/frontend/build/assets/vendor_mui.js +1 -1
- package/frontend/package.json +1 -1
- package/npm-shrinkwrap.json +44 -44
- package/package.json +2 -2
- package/dist/globalMatterbridge.js +0 -23
package/dist/frontend.js
CHANGED
|
@@ -8,15 +8,17 @@ import { appendFile } from 'node:fs/promises';
|
|
|
8
8
|
import express from 'express';
|
|
9
9
|
import WebSocket, { WebSocketServer } from 'ws';
|
|
10
10
|
import multer from 'multer';
|
|
11
|
-
import { AnsiLogger, stringify, debugStringify, CYAN, db, er, nf, rs, UNDERLINE, UNDERLINEOFF, YELLOW, nt } from 'node-ansi-logger';
|
|
11
|
+
import { AnsiLogger, stringify, debugStringify, CYAN, db, er, nf, rs, UNDERLINE, UNDERLINEOFF, YELLOW, nt, wr } from 'node-ansi-logger';
|
|
12
12
|
import { Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, Lifecycle, LogDestination, Diagnostic, Time, FabricIndex } from '@matter/main';
|
|
13
13
|
import { BridgedDeviceBasicInformation, PowerSource } from '@matter/main/clusters';
|
|
14
14
|
import { DeviceAdvertiser, DeviceCommissioner, FabricManager } from '@matter/main/protocol';
|
|
15
15
|
import { CommissioningOptions } from '@matter/main/types';
|
|
16
|
+
import { MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg } from './matterbridgeTypes.js';
|
|
16
17
|
import { createZip, isValidArray, isValidNumber, isValidObject, isValidString, isValidBoolean, withTimeout, hasParameter, wait, inspectError } from './utils/export.js';
|
|
17
|
-
import {
|
|
18
|
+
import { formatMemoryUsage, formatOsUpTime } from './utils/network.js';
|
|
18
19
|
import { capitalizeFirstLetter, getAttribute } from './matterbridgeEndpointHelpers.js';
|
|
19
20
|
import { cliEmitter, lastCpuUsage } from './cliEmitter.js';
|
|
21
|
+
import { BroadcastServer } from './broadcastServer.js';
|
|
20
22
|
export class Frontend extends EventEmitter {
|
|
21
23
|
matterbridge;
|
|
22
24
|
log;
|
|
@@ -26,11 +28,55 @@ export class Frontend extends EventEmitter {
|
|
|
26
28
|
httpServer;
|
|
27
29
|
httpsServer;
|
|
28
30
|
webSocketServer;
|
|
31
|
+
server;
|
|
29
32
|
constructor(matterbridge) {
|
|
30
33
|
super();
|
|
31
34
|
this.matterbridge = matterbridge;
|
|
32
35
|
this.log = new AnsiLogger({ logName: 'Frontend', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
33
36
|
this.log.logNameColor = '\x1b[38;5;97m';
|
|
37
|
+
this.server = new BroadcastServer('plugins', this.log);
|
|
38
|
+
this.server.on('broadcast_message', this.msgHandler.bind(this));
|
|
39
|
+
}
|
|
40
|
+
destroy() {
|
|
41
|
+
this.server.close();
|
|
42
|
+
}
|
|
43
|
+
async msgHandler(msg) {
|
|
44
|
+
if (this.server.isWorkerRequest(msg, msg.type)) {
|
|
45
|
+
this.log.debug(`**Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
46
|
+
switch (msg.type) {
|
|
47
|
+
default:
|
|
48
|
+
this.log.warn(`Unknown broadcast request ${CYAN}${msg.type}${wr} from ${CYAN}${msg.src}${wr}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (this.server.isWorkerResponse(msg, msg.type)) {
|
|
52
|
+
this.log.debug(`**Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
53
|
+
switch (msg.type) {
|
|
54
|
+
case 'plugins_install':
|
|
55
|
+
this.wssSendCloseSnackbarMessage(`Installing package ${msg.response.packageName}...`);
|
|
56
|
+
if (msg.response.success) {
|
|
57
|
+
this.wssSendRestartRequired(true, true);
|
|
58
|
+
this.wssSendRefreshRequired('plugins');
|
|
59
|
+
this.wssSendSnackbarMessage(`Installed package ${msg.response.packageName}`, 5, 'success');
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.wssSendSnackbarMessage(`Package ${msg.response.packageName} not installed`, 10, 'error');
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
case 'plugins_uninstall':
|
|
66
|
+
this.wssSendCloseSnackbarMessage(`Uninstalling package ${msg.response.packageName}...`);
|
|
67
|
+
if (msg.response.success) {
|
|
68
|
+
this.wssSendRestartRequired(true, true);
|
|
69
|
+
this.wssSendRefreshRequired('plugins');
|
|
70
|
+
this.wssSendSnackbarMessage(`Uninstalled package ${msg.response.packageName}`, 5, 'success');
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this.wssSendSnackbarMessage(`Package ${msg.response.packageName} not uninstalled`, 10, 'error');
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
default:
|
|
77
|
+
this.log.warn(`Unknown broadcast response ${CYAN}${msg.type}${wr} from ${CYAN}${msg.src}${wr}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
34
80
|
}
|
|
35
81
|
set logLevel(logLevel) {
|
|
36
82
|
this.log.logLevel = logLevel;
|
|
@@ -42,15 +88,6 @@ export class Frontend extends EventEmitter {
|
|
|
42
88
|
const upload = multer({ dest: uploadDir });
|
|
43
89
|
this.expressApp = express();
|
|
44
90
|
this.expressApp.use(express.static(path.join(this.matterbridge.rootDirectory, 'frontend/build')));
|
|
45
|
-
try {
|
|
46
|
-
this.log.debug(`Reading frontend package.json...`);
|
|
47
|
-
const frontendJson = await fs.readFile(path.join(this.matterbridge.rootDirectory, 'frontend/package.json'), 'utf8');
|
|
48
|
-
this.matterbridge.matterbridgeInformation.frontendVersion = JSON.parse(frontendJson)?.version;
|
|
49
|
-
this.log.debug(`Frontend version ${CYAN}${this.matterbridge.matterbridgeInformation.frontendVersion}${db}`);
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
this.log.error(`Failed to read frontend package.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
53
|
-
}
|
|
54
91
|
if (!hasParameter('ssl')) {
|
|
55
92
|
try {
|
|
56
93
|
this.log.debug(`Creating HTTP server...`);
|
|
@@ -195,16 +232,14 @@ export class Frontend extends EventEmitter {
|
|
|
195
232
|
return;
|
|
196
233
|
});
|
|
197
234
|
}
|
|
198
|
-
|
|
199
|
-
const wssHost = hasParameter('ssl') ? `wss://${this.matterbridge.systemInformation.ipv4Address}:${wssPort}` : `ws://${this.matterbridge.systemInformation.ipv4Address}:${wssPort}`;
|
|
200
|
-
this.log.debug(`Creating WebSocketServer on host ${CYAN}${wssHost}${db}...`);
|
|
235
|
+
this.log.debug(`Creating WebSocketServer...`);
|
|
201
236
|
this.webSocketServer = new WebSocketServer(hasParameter('ssl') ? { server: this.httpsServer } : { server: this.httpServer });
|
|
202
237
|
this.webSocketServer.on('connection', (ws, request) => {
|
|
203
238
|
const clientIp = request.socket.remoteAddress;
|
|
204
239
|
let callbackLogLevel = "notice";
|
|
205
|
-
if (this.matterbridge.
|
|
240
|
+
if (this.matterbridge.getLogLevel() === "info" || Logger.level === MatterLogLevel.INFO)
|
|
206
241
|
callbackLogLevel = "info";
|
|
207
|
-
if (this.matterbridge.
|
|
242
|
+
if (this.matterbridge.getLogLevel() === "debug" || Logger.level === MatterLogLevel.DEBUG)
|
|
208
243
|
callbackLogLevel = "debug";
|
|
209
244
|
AnsiLogger.setGlobalCallback(this.wssSendLogMessage.bind(this), callbackLogLevel);
|
|
210
245
|
this.log.debug(`WebSocketServer logger global callback set to ${callbackLogLevel}`);
|
|
@@ -234,8 +269,8 @@ export class Frontend extends EventEmitter {
|
|
|
234
269
|
this.log.debug(`WebSocketServer closed`);
|
|
235
270
|
});
|
|
236
271
|
this.webSocketServer.on('listening', () => {
|
|
237
|
-
this.log.info(`The WebSocketServer is listening
|
|
238
|
-
this.emit('websocket_server_listening',
|
|
272
|
+
this.log.info(`The WebSocketServer is listening`);
|
|
273
|
+
this.emit('websocket_server_listening', hasParameter('ssl') ? 'wss' : 'ws');
|
|
239
274
|
});
|
|
240
275
|
this.webSocketServer.on('error', (ws, error) => {
|
|
241
276
|
this.log.error(`WebSocketServer error: ${error}`);
|
|
@@ -287,22 +322,22 @@ export class Frontend extends EventEmitter {
|
|
|
287
322
|
this.log.debug('Express received /memory');
|
|
288
323
|
const memoryUsageRaw = process.memoryUsage();
|
|
289
324
|
const memoryUsage = {
|
|
290
|
-
rss:
|
|
291
|
-
heapTotal:
|
|
292
|
-
heapUsed:
|
|
293
|
-
external:
|
|
294
|
-
arrayBuffers:
|
|
325
|
+
rss: formatMemoryUsage(memoryUsageRaw.rss),
|
|
326
|
+
heapTotal: formatMemoryUsage(memoryUsageRaw.heapTotal),
|
|
327
|
+
heapUsed: formatMemoryUsage(memoryUsageRaw.heapUsed),
|
|
328
|
+
external: formatMemoryUsage(memoryUsageRaw.external),
|
|
329
|
+
arrayBuffers: formatMemoryUsage(memoryUsageRaw.arrayBuffers),
|
|
295
330
|
};
|
|
296
331
|
const { default: v8 } = await import('node:v8');
|
|
297
332
|
const heapStatsRaw = v8.getHeapStatistics();
|
|
298
333
|
const heapSpacesRaw = v8.getHeapSpaceStatistics();
|
|
299
|
-
const heapStats = Object.fromEntries(Object.entries(heapStatsRaw).map(([key, value]) => [key,
|
|
334
|
+
const heapStats = Object.fromEntries(Object.entries(heapStatsRaw).map(([key, value]) => [key, formatMemoryUsage(value)]));
|
|
300
335
|
const heapSpaces = heapSpacesRaw.map((space) => ({
|
|
301
336
|
...space,
|
|
302
|
-
space_size:
|
|
303
|
-
space_used_size:
|
|
304
|
-
space_available_size:
|
|
305
|
-
physical_space_size:
|
|
337
|
+
space_size: formatMemoryUsage(space.space_size),
|
|
338
|
+
space_used_size: formatMemoryUsage(space.space_used_size),
|
|
339
|
+
space_available_size: formatMemoryUsage(space.space_available_size),
|
|
340
|
+
physical_space_size: formatMemoryUsage(space.physical_space_size),
|
|
306
341
|
}));
|
|
307
342
|
const { createRequire } = await import('node:module');
|
|
308
343
|
const require = createRequire(import.meta.url);
|
|
@@ -321,12 +356,11 @@ export class Frontend extends EventEmitter {
|
|
|
321
356
|
});
|
|
322
357
|
this.expressApp.get('/api/plugins', async (req, res) => {
|
|
323
358
|
this.log.debug('The frontend sent /api/plugins');
|
|
324
|
-
res.json(this.getPlugins());
|
|
359
|
+
res.json(this.matterbridge.hasCleanupStarted ? [] : this.getPlugins());
|
|
325
360
|
});
|
|
326
361
|
this.expressApp.get('/api/devices', async (req, res) => {
|
|
327
362
|
this.log.debug('The frontend sent /api/devices');
|
|
328
|
-
|
|
329
|
-
res.json(devices);
|
|
363
|
+
res.json(this.matterbridge.hasCleanupStarted ? [] : this.getDevices());
|
|
330
364
|
});
|
|
331
365
|
this.expressApp.get('/api/view-mblog', async (req, res) => {
|
|
332
366
|
this.log.debug('The frontend sent /api/view-mblog');
|
|
@@ -531,7 +565,7 @@ export class Frontend extends EventEmitter {
|
|
|
531
565
|
this.log.info(`File ${plg}${filename}${nf} uploaded successfully`);
|
|
532
566
|
if (filename.endsWith('.tgz')) {
|
|
533
567
|
const { spawnCommand } = await import('./utils/spawn.js');
|
|
534
|
-
await spawnCommand(this.matterbridge, 'npm', ['install', '-g', filePath, '--omit=dev', '--verbose'], filename);
|
|
568
|
+
await spawnCommand(this.matterbridge, 'npm', ['install', '-g', filePath, '--omit=dev', '--verbose'], 'install', filename);
|
|
535
569
|
this.log.info(`Plugin package ${plg}${filename}${nf} installed successfully. Full restart required.`);
|
|
536
570
|
this.wssSendCloseSnackbarMessage(`Installing package ${filename}. Please wait...`);
|
|
537
571
|
this.wssSendSnackbarMessage(`Installed package ${filename}`, 10, 'success');
|
|
@@ -605,53 +639,49 @@ export class Frontend extends EventEmitter {
|
|
|
605
639
|
}
|
|
606
640
|
this.log.debug('Frontend stopped successfully');
|
|
607
641
|
}
|
|
608
|
-
formatMemoryUsage = (bytes) => {
|
|
609
|
-
if (bytes >= 1024 ** 3) {
|
|
610
|
-
return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
|
|
611
|
-
}
|
|
612
|
-
else if (bytes >= 1024 ** 2) {
|
|
613
|
-
return `${(bytes / 1024 ** 2).toFixed(2)} MB`;
|
|
614
|
-
}
|
|
615
|
-
else {
|
|
616
|
-
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
617
|
-
}
|
|
618
|
-
};
|
|
619
|
-
formatOsUpTime = (seconds) => {
|
|
620
|
-
if (seconds >= 86400) {
|
|
621
|
-
const days = Math.floor(seconds / 86400);
|
|
622
|
-
return `${days} day${days !== 1 ? 's' : ''}`;
|
|
623
|
-
}
|
|
624
|
-
if (seconds >= 3600) {
|
|
625
|
-
const hours = Math.floor(seconds / 3600);
|
|
626
|
-
return `${hours} hour${hours !== 1 ? 's' : ''}`;
|
|
627
|
-
}
|
|
628
|
-
if (seconds >= 60) {
|
|
629
|
-
const minutes = Math.floor(seconds / 60);
|
|
630
|
-
return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
|
|
631
|
-
}
|
|
632
|
-
return `${seconds} second${seconds !== 1 ? 's' : ''}`;
|
|
633
|
-
};
|
|
634
642
|
async getApiSettings() {
|
|
635
|
-
this.matterbridge.systemInformation.totalMemory =
|
|
636
|
-
this.matterbridge.systemInformation.freeMemory =
|
|
637
|
-
this.matterbridge.systemInformation.systemUptime =
|
|
638
|
-
this.matterbridge.systemInformation.processUptime =
|
|
643
|
+
this.matterbridge.systemInformation.totalMemory = formatMemoryUsage(os.totalmem());
|
|
644
|
+
this.matterbridge.systemInformation.freeMemory = formatMemoryUsage(os.freemem());
|
|
645
|
+
this.matterbridge.systemInformation.systemUptime = formatOsUpTime(os.uptime());
|
|
646
|
+
this.matterbridge.systemInformation.processUptime = formatOsUpTime(Math.floor(process.uptime()));
|
|
639
647
|
this.matterbridge.systemInformation.cpuUsage = lastCpuUsage.toFixed(2) + ' %';
|
|
640
|
-
this.matterbridge.systemInformation.rss =
|
|
641
|
-
this.matterbridge.systemInformation.heapTotal =
|
|
642
|
-
this.matterbridge.systemInformation.heapUsed =
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
648
|
+
this.matterbridge.systemInformation.rss = formatMemoryUsage(process.memoryUsage().rss);
|
|
649
|
+
this.matterbridge.systemInformation.heapTotal = formatMemoryUsage(process.memoryUsage().heapTotal);
|
|
650
|
+
this.matterbridge.systemInformation.heapUsed = formatMemoryUsage(process.memoryUsage().heapUsed);
|
|
651
|
+
const info = {
|
|
652
|
+
homeDirectory: this.matterbridge.homeDirectory,
|
|
653
|
+
rootDirectory: this.matterbridge.rootDirectory,
|
|
654
|
+
matterbridgeDirectory: this.matterbridge.matterbridgeDirectory,
|
|
655
|
+
matterbridgePluginDirectory: this.matterbridge.matterbridgePluginDirectory,
|
|
656
|
+
matterbridgeCertDirectory: this.matterbridge.matterbridgeCertDirectory,
|
|
657
|
+
globalModulesDirectory: this.matterbridge.globalModulesDirectory,
|
|
658
|
+
matterbridgeVersion: this.matterbridge.matterbridgeVersion,
|
|
659
|
+
matterbridgeLatestVersion: this.matterbridge.matterbridgeLatestVersion,
|
|
660
|
+
matterbridgeDevVersion: this.matterbridge.matterbridgeDevVersion,
|
|
661
|
+
frontendVersion: this.matterbridge.frontendVersion,
|
|
662
|
+
bridgeMode: this.matterbridge.bridgeMode,
|
|
663
|
+
restartMode: this.matterbridge.restartMode,
|
|
664
|
+
virtualMode: this.matterbridge.virtualMode,
|
|
665
|
+
profile: this.matterbridge.profile,
|
|
666
|
+
readOnly: this.matterbridge.readOnly,
|
|
667
|
+
shellyBoard: this.matterbridge.shellyBoard,
|
|
668
|
+
shellySysUpdate: this.matterbridge.shellySysUpdate,
|
|
669
|
+
shellyMainUpdate: this.matterbridge.shellyMainUpdate,
|
|
670
|
+
loggerLevel: await this.matterbridge.getLogLevel(),
|
|
671
|
+
fileLogger: this.matterbridge.fileLogger,
|
|
672
|
+
matterLoggerLevel: Logger.level,
|
|
673
|
+
matterFileLogger: this.matterbridge.matterFileLogger,
|
|
674
|
+
matterMdnsInterface: this.matterbridge.mdnsInterface,
|
|
675
|
+
matterIpv4Address: this.matterbridge.ipv4Address,
|
|
676
|
+
matterIpv6Address: this.matterbridge.ipv6Address,
|
|
677
|
+
matterPort: (await this.matterbridge.nodeContext?.get('matterport', 5540)) ?? 5540,
|
|
678
|
+
matterDiscriminator: await this.matterbridge.nodeContext?.get('matterdiscriminator'),
|
|
679
|
+
matterPasscode: await this.matterbridge.nodeContext?.get('matterpasscode'),
|
|
680
|
+
restartRequired: this.matterbridge.restartRequired,
|
|
681
|
+
fixedRestartRequired: this.matterbridge.fixedRestartRequired,
|
|
682
|
+
updateRequired: this.matterbridge.updateRequired,
|
|
683
|
+
};
|
|
684
|
+
return { systemInformation: this.matterbridge.systemInformation, matterbridgeInformation: info };
|
|
655
685
|
}
|
|
656
686
|
getReachability(device) {
|
|
657
687
|
if (!device.lifecycle.isReady || device.construction.status !== Lifecycle.Status.Active)
|
|
@@ -802,11 +832,9 @@ export class Frontend extends EventEmitter {
|
|
|
802
832
|
return attributes.trimStart().trimEnd();
|
|
803
833
|
}
|
|
804
834
|
getPlugins() {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
for (const plugin of this.matterbridge.plugins) {
|
|
809
|
-
baseRegisteredPlugins.push({
|
|
835
|
+
const plugins = [];
|
|
836
|
+
for (const plugin of this.matterbridge.plugins.array()) {
|
|
837
|
+
plugins.push({
|
|
810
838
|
path: plugin.path,
|
|
811
839
|
type: plugin.type,
|
|
812
840
|
name: plugin.name,
|
|
@@ -834,11 +862,9 @@ export class Frontend extends EventEmitter {
|
|
|
834
862
|
matter: plugin.serverNode ? this.matterbridge.getServerNodeData(plugin.serverNode) : undefined,
|
|
835
863
|
});
|
|
836
864
|
}
|
|
837
|
-
return
|
|
865
|
+
return plugins;
|
|
838
866
|
}
|
|
839
867
|
getDevices(pluginName) {
|
|
840
|
-
if (this.matterbridge.hasCleanupStarted)
|
|
841
|
-
return [];
|
|
842
868
|
const devices = [];
|
|
843
869
|
for (const device of this.matterbridge.devices.array()) {
|
|
844
870
|
if (pluginName && pluginName !== device.plugin)
|
|
@@ -972,95 +998,24 @@ export class Frontend extends EventEmitter {
|
|
|
972
998
|
}
|
|
973
999
|
}
|
|
974
1000
|
else if (data.method === '/api/install') {
|
|
975
|
-
|
|
976
|
-
|
|
1001
|
+
if (isValidString(data.params.packageName, 14) && isValidBoolean(data.params.restart)) {
|
|
1002
|
+
this.wssSendSnackbarMessage(`Installing package ${data.params.packageName}...`, 0);
|
|
1003
|
+
this.server.request({ type: 'plugins_install', src: this.server.name, dst: 'plugins', params: { packageName: data.params.packageName } });
|
|
1004
|
+
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1005
|
+
}
|
|
1006
|
+
else {
|
|
977
1007
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Wrong parameter in /api/install' });
|
|
978
|
-
return;
|
|
979
1008
|
}
|
|
980
|
-
this.wssSendSnackbarMessage(`Installing package ${data.params.packageName}...`, 0);
|
|
981
|
-
const { spawnCommand } = await import('./utils/spawn.js');
|
|
982
|
-
spawnCommand(this.matterbridge, 'npm', ['install', '-g', data.params.packageName, '--omit=dev', '--verbose'], data.params.packageName)
|
|
983
|
-
.then((_response) => {
|
|
984
|
-
sendResponse({ id: localData.id, method: localData.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
985
|
-
this.wssSendCloseSnackbarMessage(`Installing package ${localData.params.packageName}...`);
|
|
986
|
-
this.wssSendSnackbarMessage(`Installed package ${localData.params.packageName}`, 5, 'success');
|
|
987
|
-
const packageName = localData.params.packageName.replace(/@.*$/, '');
|
|
988
|
-
if (localData.params.restart === false && packageName !== 'matterbridge') {
|
|
989
|
-
this.matterbridge.plugins
|
|
990
|
-
.add(packageName)
|
|
991
|
-
.then((plugin) => {
|
|
992
|
-
if (plugin) {
|
|
993
|
-
this.wssSendSnackbarMessage(`Added plugin ${packageName}`, 5, 'success');
|
|
994
|
-
if (this.matterbridge.bridgeMode === 'childbridge')
|
|
995
|
-
this.wssSendRestartRequired(true, true);
|
|
996
|
-
this.matterbridge.plugins
|
|
997
|
-
.load(plugin, true, 'The plugin has been added', true)
|
|
998
|
-
.then(() => {
|
|
999
|
-
this.wssSendSnackbarMessage(`Started plugin ${packageName}`, 5, 'success');
|
|
1000
|
-
this.wssSendRefreshRequired('plugins');
|
|
1001
|
-
this.wssSendRefreshRequired('devices');
|
|
1002
|
-
return;
|
|
1003
|
-
})
|
|
1004
|
-
.catch((_error) => {
|
|
1005
|
-
});
|
|
1006
|
-
}
|
|
1007
|
-
else {
|
|
1008
|
-
this.matterbridge.matterbridgeInformation.fixedRestartRequired = true;
|
|
1009
|
-
this.wssSendRefreshRequired('plugins');
|
|
1010
|
-
this.wssSendRestartRequired(true, true);
|
|
1011
|
-
}
|
|
1012
|
-
return;
|
|
1013
|
-
})
|
|
1014
|
-
.catch((_error) => {
|
|
1015
|
-
});
|
|
1016
|
-
}
|
|
1017
|
-
else {
|
|
1018
|
-
this.matterbridge.matterbridgeInformation.fixedRestartRequired = true;
|
|
1019
|
-
if (this.matterbridge.restartMode !== '') {
|
|
1020
|
-
this.wssSendSnackbarMessage(`Restarting matterbridge...`, 0);
|
|
1021
|
-
this.matterbridge.shutdownProcess();
|
|
1022
|
-
}
|
|
1023
|
-
else {
|
|
1024
|
-
this.wssSendRestartRequired(true, true);
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
return;
|
|
1028
|
-
})
|
|
1029
|
-
.catch((error) => {
|
|
1030
|
-
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: error instanceof Error ? error.message : error });
|
|
1031
|
-
this.wssSendCloseSnackbarMessage(`Installing package ${localData.params.packageName}...`);
|
|
1032
|
-
this.wssSendSnackbarMessage(`Package ${localData.params.packageName} not installed`, 10, 'error');
|
|
1033
|
-
});
|
|
1034
1009
|
}
|
|
1035
1010
|
else if (data.method === '/api/uninstall') {
|
|
1036
|
-
|
|
1037
|
-
|
|
1011
|
+
if (isValidString(data.params.packageName, 14)) {
|
|
1012
|
+
this.wssSendSnackbarMessage(`Uninstalling package ${data.params.packageName}...`, 0);
|
|
1013
|
+
this.server.request({ type: 'plugins_uninstall', src: this.server.name, dst: 'plugins', params: { packageName: data.params.packageName } });
|
|
1014
|
+
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1015
|
+
}
|
|
1016
|
+
else {
|
|
1038
1017
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Wrong parameter packageName in /api/uninstall' });
|
|
1039
|
-
return;
|
|
1040
1018
|
}
|
|
1041
|
-
const plugin = this.matterbridge.plugins.get(data.params.packageName);
|
|
1042
|
-
if (plugin) {
|
|
1043
|
-
await this.matterbridge.plugins.shutdown(plugin, 'The plugin has been removed.', true);
|
|
1044
|
-
await this.matterbridge.plugins.remove(data.params.packageName);
|
|
1045
|
-
this.wssSendSnackbarMessage(`Removed plugin ${data.params.packageName}`, 5, 'success');
|
|
1046
|
-
this.wssSendRefreshRequired('plugins');
|
|
1047
|
-
this.wssSendRefreshRequired('devices');
|
|
1048
|
-
}
|
|
1049
|
-
this.wssSendSnackbarMessage(`Uninstalling package ${data.params.packageName}...`, 0);
|
|
1050
|
-
const { spawnCommand } = await import('./utils/spawn.js');
|
|
1051
|
-
spawnCommand(this.matterbridge, 'npm', ['uninstall', '-g', data.params.packageName, '--verbose'], data.params.packageName)
|
|
1052
|
-
.then((_response) => {
|
|
1053
|
-
sendResponse({ id: localData.id, method: localData.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1054
|
-
this.wssSendCloseSnackbarMessage(`Uninstalling package ${localData.params.packageName}...`);
|
|
1055
|
-
this.wssSendSnackbarMessage(`Uninstalled package ${localData.params.packageName}`, 5, 'success');
|
|
1056
|
-
return;
|
|
1057
|
-
})
|
|
1058
|
-
.catch((error) => {
|
|
1059
|
-
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: error instanceof Error ? error.message : error });
|
|
1060
|
-
this.wssSendCloseSnackbarMessage(`Uninstalling package ${localData.params.packageName}...`);
|
|
1061
|
-
this.wssSendSnackbarMessage(`Package ${localData.params.packageName} not uninstalled`, 10, 'error');
|
|
1062
|
-
this.wssSendSnackbarMessage(`Restart required`, 0);
|
|
1063
|
-
});
|
|
1064
1019
|
}
|
|
1065
1020
|
else if (data.method === '/api/addplugin') {
|
|
1066
1021
|
const localData = data;
|
|
@@ -1333,11 +1288,11 @@ export class Frontend extends EventEmitter {
|
|
|
1333
1288
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true, response: await this.getApiSettings() });
|
|
1334
1289
|
}
|
|
1335
1290
|
else if (data.method === '/api/plugins') {
|
|
1336
|
-
const plugins = this.getPlugins();
|
|
1291
|
+
const plugins = this.matterbridge.hasCleanupStarted ? [] : this.getPlugins();
|
|
1337
1292
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true, response: plugins });
|
|
1338
1293
|
}
|
|
1339
1294
|
else if (data.method === '/api/devices') {
|
|
1340
|
-
const devices = this.getDevices(isValidString(data.params.pluginName) ? data.params.pluginName : undefined);
|
|
1295
|
+
const devices = this.matterbridge.hasCleanupStarted ? [] : this.getDevices(isValidString(data.params.pluginName) ? data.params.pluginName : undefined);
|
|
1341
1296
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true, response: devices });
|
|
1342
1297
|
}
|
|
1343
1298
|
else if (data.method === '/api/clusters') {
|
|
@@ -1461,10 +1416,10 @@ export class Frontend extends EventEmitter {
|
|
|
1461
1416
|
case 'setmblogfile':
|
|
1462
1417
|
if (isValidBoolean(data.params.value)) {
|
|
1463
1418
|
this.log.debug('Matterbridge file log:', data.params.value);
|
|
1464
|
-
this.matterbridge.
|
|
1419
|
+
this.matterbridge.fileLogger = data.params.value;
|
|
1465
1420
|
await this.matterbridge.nodeContext?.set('matterbridgeFileLog', data.params.value);
|
|
1466
1421
|
if (data.params.value)
|
|
1467
|
-
AnsiLogger.setGlobalLogfile(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_LOGGER_FILE), this.matterbridge.
|
|
1422
|
+
AnsiLogger.setGlobalLogfile(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_LOGGER_FILE), await this.matterbridge.getLogLevel(), true);
|
|
1468
1423
|
else
|
|
1469
1424
|
AnsiLogger.setGlobalLogfile(undefined);
|
|
1470
1425
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
@@ -1491,7 +1446,6 @@ export class Frontend extends EventEmitter {
|
|
|
1491
1446
|
else if (data.params.value === 'Fatal') {
|
|
1492
1447
|
Logger.level = MatterLogLevel.FATAL;
|
|
1493
1448
|
}
|
|
1494
|
-
this.matterbridge.matterbridgeInformation.matterLoggerLevel = Logger.level;
|
|
1495
1449
|
await this.matterbridge.nodeContext?.set('matterLogLevel', Logger.level);
|
|
1496
1450
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1497
1451
|
}
|
|
@@ -1499,7 +1453,7 @@ export class Frontend extends EventEmitter {
|
|
|
1499
1453
|
case 'setmjlogfile':
|
|
1500
1454
|
if (isValidBoolean(data.params.value)) {
|
|
1501
1455
|
this.log.debug('Matter file log:', data.params.value);
|
|
1502
|
-
this.matterbridge.
|
|
1456
|
+
this.matterbridge.fileLogger = data.params.value;
|
|
1503
1457
|
await this.matterbridge.nodeContext?.set('matterFileLog', data.params.value);
|
|
1504
1458
|
if (data.params.value) {
|
|
1505
1459
|
this.matterbridge.matterLog.logFilePath = path.join(this.matterbridge.matterbridgeDirectory, MATTER_LOGGER_FILE);
|
|
@@ -1514,86 +1468,92 @@ export class Frontend extends EventEmitter {
|
|
|
1514
1468
|
if (isValidString(data.params.value)) {
|
|
1515
1469
|
this.log.debug(`Matter.js mdns interface: ${data.params.value === '' ? 'all interfaces' : data.params.value}`);
|
|
1516
1470
|
this.matterbridge.mdnsInterface = data.params.value === '' ? undefined : data.params.value;
|
|
1517
|
-
this.matterbridge.matterbridgeInformation.matterMdnsInterface = this.matterbridge.mdnsInterface;
|
|
1518
1471
|
await this.matterbridge.nodeContext?.set('mattermdnsinterface', data.params.value);
|
|
1519
1472
|
this.wssSendRestartRequired();
|
|
1520
1473
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1474
|
+
this.wssSendSnackbarMessage(`Mdns interface changed to ${data.params.value === '' ? 'all interfaces' : data.params.value}`);
|
|
1521
1475
|
}
|
|
1522
1476
|
break;
|
|
1523
1477
|
case 'setipv4address':
|
|
1524
1478
|
if (isValidString(data.params.value)) {
|
|
1525
1479
|
this.log.debug(`Matter.js ipv4 address: ${data.params.value === '' ? 'all ipv4 addresses' : data.params.value}`);
|
|
1526
|
-
this.matterbridge.
|
|
1527
|
-
this.matterbridge.matterbridgeInformation.matterIpv4Address = this.matterbridge.ipv4address;
|
|
1480
|
+
this.matterbridge.ipv4Address = data.params.value === '' ? undefined : data.params.value;
|
|
1528
1481
|
await this.matterbridge.nodeContext?.set('matteripv4address', data.params.value);
|
|
1529
1482
|
this.wssSendRestartRequired();
|
|
1530
1483
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1484
|
+
this.wssSendSnackbarMessage(`IPv4 address changed to ${data.params.value === '' ? 'all ipv4 addresses' : data.params.value}`);
|
|
1531
1485
|
}
|
|
1532
1486
|
break;
|
|
1533
1487
|
case 'setipv6address':
|
|
1534
1488
|
if (isValidString(data.params.value)) {
|
|
1535
1489
|
this.log.debug(`Matter.js ipv6 address: ${data.params.value === '' ? 'all ipv6 addresses' : data.params.value}`);
|
|
1536
|
-
this.matterbridge.
|
|
1537
|
-
this.matterbridge.matterbridgeInformation.matterIpv6Address = this.matterbridge.ipv6address;
|
|
1490
|
+
this.matterbridge.ipv6Address = data.params.value === '' ? undefined : data.params.value;
|
|
1538
1491
|
await this.matterbridge.nodeContext?.set('matteripv6address', data.params.value);
|
|
1539
1492
|
this.wssSendRestartRequired();
|
|
1540
1493
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1494
|
+
this.wssSendSnackbarMessage(`IPv6 address changed to ${data.params.value === '' ? 'all ipv6 addresses' : data.params.value}`);
|
|
1541
1495
|
}
|
|
1542
1496
|
break;
|
|
1543
1497
|
case 'setmatterport':
|
|
1544
1498
|
const port = isValidString(data.params.value) ? parseInt(data.params.value) : 0;
|
|
1545
1499
|
if (isValidNumber(port, 5540, 5600)) {
|
|
1546
1500
|
this.log.debug(`Set matter commissioning port to ${CYAN}${port}${db}`);
|
|
1547
|
-
this.matterbridge.
|
|
1501
|
+
this.matterbridge.port = port;
|
|
1548
1502
|
await this.matterbridge.nodeContext?.set('matterport', port);
|
|
1549
1503
|
this.wssSendRestartRequired();
|
|
1550
1504
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1505
|
+
this.wssSendSnackbarMessage(`Matter port changed to ${port}`);
|
|
1551
1506
|
}
|
|
1552
1507
|
else {
|
|
1553
1508
|
this.log.debug(`Reset matter commissioning port to ${CYAN}5540${db}`);
|
|
1554
|
-
this.matterbridge.
|
|
1509
|
+
this.matterbridge.port = 5540;
|
|
1555
1510
|
await this.matterbridge.nodeContext?.set('matterport', 5540);
|
|
1556
1511
|
this.wssSendRestartRequired();
|
|
1557
1512
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Invalid value: reset matter commissioning port to default 5540' });
|
|
1513
|
+
this.wssSendSnackbarMessage(`Matter port reset to default 5540`, undefined, 'error');
|
|
1558
1514
|
}
|
|
1559
1515
|
break;
|
|
1560
1516
|
case 'setmatterdiscriminator':
|
|
1561
1517
|
const discriminator = isValidString(data.params.value) ? parseInt(data.params.value) : 0;
|
|
1562
1518
|
if (isValidNumber(discriminator, 0, 4095)) {
|
|
1563
1519
|
this.log.debug(`Set matter commissioning discriminator to ${CYAN}${discriminator}${db}`);
|
|
1564
|
-
this.matterbridge.
|
|
1520
|
+
this.matterbridge.discriminator = discriminator;
|
|
1565
1521
|
await this.matterbridge.nodeContext?.set('matterdiscriminator', discriminator);
|
|
1566
1522
|
this.wssSendRestartRequired();
|
|
1567
1523
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1524
|
+
this.wssSendSnackbarMessage(`Matter discriminator changed to ${discriminator}`);
|
|
1568
1525
|
}
|
|
1569
1526
|
else {
|
|
1570
1527
|
this.log.debug(`Reset matter commissioning discriminator to ${CYAN}undefined${db}`);
|
|
1571
|
-
this.matterbridge.
|
|
1528
|
+
this.matterbridge.discriminator = undefined;
|
|
1572
1529
|
await this.matterbridge.nodeContext?.remove('matterdiscriminator');
|
|
1573
1530
|
this.wssSendRestartRequired();
|
|
1574
1531
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Invalid value: reset matter commissioning discriminator to default undefined' });
|
|
1532
|
+
this.wssSendSnackbarMessage(`Matter discriminator reset to default`, undefined, 'error');
|
|
1575
1533
|
}
|
|
1576
1534
|
break;
|
|
1577
1535
|
case 'setmatterpasscode':
|
|
1578
1536
|
const passcode = isValidString(data.params.value) ? parseInt(data.params.value) : 0;
|
|
1579
1537
|
if (isValidNumber(passcode, 1, 99999998) && CommissioningOptions.FORBIDDEN_PASSCODES.includes(passcode) === false) {
|
|
1580
|
-
this.matterbridge.
|
|
1538
|
+
this.matterbridge.passcode = passcode;
|
|
1581
1539
|
this.log.debug(`Set matter commissioning passcode to ${CYAN}${passcode}${db}`);
|
|
1582
1540
|
await this.matterbridge.nodeContext?.set('matterpasscode', passcode);
|
|
1583
1541
|
this.wssSendRestartRequired();
|
|
1584
1542
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1543
|
+
this.wssSendSnackbarMessage(`Matter passcode changed to ${passcode}`);
|
|
1585
1544
|
}
|
|
1586
1545
|
else {
|
|
1587
1546
|
this.log.debug(`Reset matter commissioning passcode to ${CYAN}undefined${db}`);
|
|
1588
|
-
this.matterbridge.
|
|
1547
|
+
this.matterbridge.passcode = undefined;
|
|
1589
1548
|
await this.matterbridge.nodeContext?.remove('matterpasscode');
|
|
1590
1549
|
this.wssSendRestartRequired();
|
|
1591
1550
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Invalid value: reset matter commissioning passcode to default undefined' });
|
|
1551
|
+
this.wssSendSnackbarMessage(`Matter passcode reset to default`, undefined, 'error');
|
|
1592
1552
|
}
|
|
1593
1553
|
break;
|
|
1594
1554
|
case 'setvirtualmode':
|
|
1595
1555
|
if (isValidString(data.params.value, 1) && ['disabled', 'light', 'outlet', 'switch', 'mounted_switch'].includes(data.params.value)) {
|
|
1596
|
-
this.matterbridge.
|
|
1556
|
+
this.matterbridge.virtualMode = data.params.value;
|
|
1597
1557
|
this.log.debug(`Set matterbridge virtual mode to ${CYAN}${data.params.value}${db}`);
|
|
1598
1558
|
await this.matterbridge.nodeContext?.set('virtualmode', data.params.value);
|
|
1599
1559
|
this.wssSendRestartRequired();
|
|
@@ -1740,22 +1700,22 @@ export class Frontend extends EventEmitter {
|
|
|
1740
1700
|
}
|
|
1741
1701
|
wssSendRestartRequired(snackbar = true, fixed = false) {
|
|
1742
1702
|
this.log.debug('Sending a restart required message to all connected clients');
|
|
1743
|
-
this.matterbridge.
|
|
1744
|
-
this.matterbridge.
|
|
1703
|
+
this.matterbridge.restartRequired = true;
|
|
1704
|
+
this.matterbridge.fixedRestartRequired = fixed;
|
|
1745
1705
|
if (snackbar === true)
|
|
1746
1706
|
this.wssSendSnackbarMessage(`Restart required`, 0);
|
|
1747
1707
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'restart_required', success: true, response: { fixed } });
|
|
1748
1708
|
}
|
|
1749
1709
|
wssSendRestartNotRequired(snackbar = true) {
|
|
1750
1710
|
this.log.debug('Sending a restart not required message to all connected clients');
|
|
1751
|
-
this.matterbridge.
|
|
1711
|
+
this.matterbridge.restartRequired = false;
|
|
1752
1712
|
if (snackbar === true)
|
|
1753
1713
|
this.wssSendCloseSnackbarMessage(`Restart required`);
|
|
1754
1714
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'restart_not_required', success: true });
|
|
1755
1715
|
}
|
|
1756
1716
|
wssSendUpdateRequired(devVersion = false) {
|
|
1757
1717
|
this.log.debug('Sending an update required message to all connected clients');
|
|
1758
|
-
this.matterbridge.
|
|
1718
|
+
this.matterbridge.updateRequired = true;
|
|
1759
1719
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'update_required', success: true, response: { devVersion } });
|
|
1760
1720
|
}
|
|
1761
1721
|
wssSendCpuUpdate(cpuUsage) {
|
package/dist/helpers.js
CHANGED
|
@@ -45,15 +45,15 @@ export async function addVirtualDevice(aggregatorEndpoint, name, type, callback)
|
|
|
45
45
|
return device;
|
|
46
46
|
}
|
|
47
47
|
export async function addVirtualDevices(matterbridge, aggregatorEndpoint) {
|
|
48
|
-
if (matterbridge.
|
|
48
|
+
if (matterbridge.virtualMode !== 'disabled' && matterbridge.bridgeMode === 'bridge' && aggregatorEndpoint) {
|
|
49
49
|
matterbridge.log.notice(`Creating virtual devices for Matterbridge server node...`);
|
|
50
|
-
await addVirtualDevice(aggregatorEndpoint, 'Restart Matterbridge', matterbridge.
|
|
50
|
+
await addVirtualDevice(aggregatorEndpoint, 'Restart Matterbridge', matterbridge.virtualMode, async () => {
|
|
51
51
|
if (matterbridge.restartMode === '')
|
|
52
52
|
await matterbridge.restartProcess();
|
|
53
53
|
else
|
|
54
54
|
await matterbridge.shutdownProcess();
|
|
55
55
|
});
|
|
56
|
-
await addVirtualDevice(aggregatorEndpoint, 'Update Matterbridge', matterbridge.
|
|
56
|
+
await addVirtualDevice(aggregatorEndpoint, 'Update Matterbridge', matterbridge.virtualMode, async () => {
|
|
57
57
|
if (hasParameter('shelly')) {
|
|
58
58
|
const { getShelly } = await import('./shelly.js');
|
|
59
59
|
getShelly('/api/updates/sys/perform', 10 * 1000)
|
|
@@ -78,7 +78,7 @@ export async function addVirtualDevices(matterbridge, aggregatorEndpoint) {
|
|
|
78
78
|
}
|
|
79
79
|
});
|
|
80
80
|
if (hasParameter('shelly')) {
|
|
81
|
-
await addVirtualDevice(aggregatorEndpoint, 'Reboot Matterbridge', matterbridge.
|
|
81
|
+
await addVirtualDevice(aggregatorEndpoint, 'Reboot Matterbridge', matterbridge.virtualMode, async () => {
|
|
82
82
|
const { postShelly } = await import('./shelly.js');
|
|
83
83
|
postShelly('/api/system/reboot', {}, 60 * 1000)
|
|
84
84
|
.then(() => {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { AnsiLogger } from 'node-ansi-logger';
|
|
2
|
-
import { Matterbridge } from './matterbridge.js';
|
|
3
|
-
import { hasParameter } from './utils/commandLine.js';
|
|
4
1
|
export * from './matterbridge.js';
|
|
5
2
|
export * from './matterbridgeTypes.js';
|
|
6
3
|
export * from './matterbridgeEndpoint.js';
|
|
@@ -11,12 +8,3 @@ export * from './matterbridgePlatform.js';
|
|
|
11
8
|
export * from './matterbridgeAccessoryPlatform.js';
|
|
12
9
|
export * from './matterbridgeDynamicPlatform.js';
|
|
13
10
|
export { addVirtualDevice } from './helpers.js';
|
|
14
|
-
const log = new AnsiLogger({ logName: 'Main', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
15
|
-
async function main() {
|
|
16
|
-
log.debug('***Matterbridge.loadInstance() called');
|
|
17
|
-
await Matterbridge.loadInstance();
|
|
18
|
-
log.debug('***Matterbridge.loadInstance() exited');
|
|
19
|
-
}
|
|
20
|
-
main().catch((error) => {
|
|
21
|
-
log.error(`Matterbridge.loadInstance() failed with error: ${error instanceof Error ? error.message : error}`);
|
|
22
|
-
});
|