matterbridge 2.1.5 → 2.1.6-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README-DOCKER.md +17 -7
- package/dist/cli.js +0 -26
- package/dist/cluster/export.js +0 -2
- package/dist/defaultConfigSchema.js +0 -23
- package/dist/deviceManager.js +1 -94
- package/dist/frontend.js +55 -280
- package/dist/index.js +0 -28
- package/dist/logger/export.js +0 -1
- package/dist/matter/behaviors.js +0 -2
- package/dist/matter/clusters.js +0 -2
- package/dist/matter/devices.js +0 -2
- package/dist/matter/endpoints.js +0 -2
- package/dist/matter/export.js +0 -2
- package/dist/matter/types.js +0 -2
- package/dist/matterbridge.js +68 -765
- package/dist/matterbridgeAccessoryPlatform.js +0 -33
- package/dist/matterbridgeBehaviors.js +1 -32
- package/dist/matterbridgeDeviceTypes.js +11 -112
- package/dist/matterbridgeDynamicPlatform.js +0 -33
- package/dist/matterbridgeEndpoint.js +6 -690
- package/dist/matterbridgeEndpointHelpers.js +9 -117
- package/dist/matterbridgePlatform.js +41 -123
- package/dist/matterbridgeTypes.js +0 -24
- package/dist/pluginManager.js +3 -230
- package/dist/storage/export.js +0 -1
- package/dist/utils/colorUtils.js +2 -205
- package/dist/utils/export.js +0 -1
- package/dist/utils/utils.js +10 -264
- package/frontend/build/asset-manifest.json +3 -3
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/js/{main.cd192588.js → main.a241d4f0.js} +9 -9
- package/frontend/build/static/js/main.a241d4f0.js.map +1 -0
- package/npm-shrinkwrap.json +47 -47
- package/package.json +2 -3
- package/dist/cli.d.ts +0 -25
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cluster/export.d.ts +0 -2
- package/dist/cluster/export.d.ts.map +0 -1
- package/dist/cluster/export.js.map +0 -1
- package/dist/defaultConfigSchema.d.ts +0 -27
- package/dist/defaultConfigSchema.d.ts.map +0 -1
- package/dist/defaultConfigSchema.js.map +0 -1
- package/dist/deviceManager.d.ts +0 -114
- package/dist/deviceManager.d.ts.map +0 -1
- package/dist/deviceManager.js.map +0 -1
- package/dist/frontend.d.ts +0 -143
- package/dist/frontend.d.ts.map +0 -1
- package/dist/frontend.js.map +0 -1
- package/dist/index.d.ts +0 -35
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger/export.d.ts +0 -2
- package/dist/logger/export.d.ts.map +0 -1
- package/dist/logger/export.js.map +0 -1
- package/dist/matter/behaviors.d.ts +0 -2
- package/dist/matter/behaviors.d.ts.map +0 -1
- package/dist/matter/behaviors.js.map +0 -1
- package/dist/matter/clusters.d.ts +0 -2
- package/dist/matter/clusters.d.ts.map +0 -1
- package/dist/matter/clusters.js.map +0 -1
- package/dist/matter/devices.d.ts +0 -2
- package/dist/matter/devices.d.ts.map +0 -1
- package/dist/matter/devices.js.map +0 -1
- package/dist/matter/endpoints.d.ts +0 -2
- package/dist/matter/endpoints.d.ts.map +0 -1
- package/dist/matter/endpoints.js.map +0 -1
- package/dist/matter/export.d.ts +0 -5
- package/dist/matter/export.d.ts.map +0 -1
- package/dist/matter/export.js.map +0 -1
- package/dist/matter/types.d.ts +0 -3
- package/dist/matter/types.d.ts.map +0 -1
- package/dist/matter/types.js.map +0 -1
- package/dist/matterbridge.d.ts +0 -409
- package/dist/matterbridge.d.ts.map +0 -1
- package/dist/matterbridge.js.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.d.ts +0 -39
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
- package/dist/matterbridgeBehaviors.d.ts +0 -1056
- package/dist/matterbridgeBehaviors.d.ts.map +0 -1
- package/dist/matterbridgeBehaviors.js.map +0 -1
- package/dist/matterbridgeDeviceTypes.d.ts +0 -177
- package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
- package/dist/matterbridgeDeviceTypes.js.map +0 -1
- package/dist/matterbridgeDynamicPlatform.d.ts +0 -39
- package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
- package/dist/matterbridgeDynamicPlatform.js.map +0 -1
- package/dist/matterbridgeEndpoint.d.ts +0 -835
- package/dist/matterbridgeEndpoint.d.ts.map +0 -1
- package/dist/matterbridgeEndpoint.js.map +0 -1
- package/dist/matterbridgeEndpointHelpers.d.ts +0 -2275
- package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
- package/dist/matterbridgeEndpointHelpers.js.map +0 -1
- package/dist/matterbridgePlatform.d.ts +0 -159
- package/dist/matterbridgePlatform.d.ts.map +0 -1
- package/dist/matterbridgePlatform.js.map +0 -1
- package/dist/matterbridgeTypes.d.ts +0 -169
- package/dist/matterbridgeTypes.d.ts.map +0 -1
- package/dist/matterbridgeTypes.js.map +0 -1
- package/dist/pluginManager.d.ts +0 -236
- package/dist/pluginManager.d.ts.map +0 -1
- package/dist/pluginManager.js.map +0 -1
- package/dist/storage/export.d.ts +0 -2
- package/dist/storage/export.d.ts.map +0 -1
- package/dist/storage/export.js.map +0 -1
- package/dist/utils/colorUtils.d.ts +0 -61
- package/dist/utils/colorUtils.d.ts.map +0 -1
- package/dist/utils/colorUtils.js.map +0 -1
- package/dist/utils/export.d.ts +0 -3
- package/dist/utils/export.d.ts.map +0 -1
- package/dist/utils/export.js.map +0 -1
- package/dist/utils/utils.d.ts +0 -231
- package/dist/utils/utils.d.ts.map +0 -1
- package/dist/utils/utils.js.map +0 -1
- package/frontend/build/static/js/main.cd192588.js.map +0 -1
- /package/frontend/build/static/js/{main.cd192588.js.LICENSE.txt → main.a241d4f0.js.LICENSE.txt} +0 -0
package/dist/frontend.js
CHANGED
|
@@ -1,28 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file contains the class Frontend.
|
|
3
|
-
*
|
|
4
|
-
* @file frontend.ts
|
|
5
|
-
* @author Luca Liguori
|
|
6
|
-
* @date 2025-01-13
|
|
7
|
-
* @version 1.0.2
|
|
8
|
-
*
|
|
9
|
-
* Copyright 2025, 2026, 2027 Luca Liguori.
|
|
10
|
-
*
|
|
11
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
-
* you may not use this file except in compliance with the License.
|
|
13
|
-
* You may obtain a copy of the License at
|
|
14
|
-
*
|
|
15
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
-
*
|
|
17
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
-
* See the License for the specific language governing permissions and
|
|
21
|
-
* limitations under the License. *
|
|
22
|
-
*/
|
|
23
|
-
// @matter
|
|
24
1
|
import { EndpointServer, Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat } from '@matter/main';
|
|
25
|
-
// Node modules
|
|
26
2
|
import { createServer } from 'http';
|
|
27
3
|
import https from 'https';
|
|
28
4
|
import express from 'express';
|
|
@@ -30,47 +6,15 @@ import WebSocket, { WebSocketServer } from 'ws';
|
|
|
30
6
|
import os from 'os';
|
|
31
7
|
import path from 'path';
|
|
32
8
|
import { promises as fs } from 'fs';
|
|
33
|
-
// AnsiLogger module
|
|
34
9
|
import { AnsiLogger, CYAN, db, debugStringify, er, nf, rs, stringify, UNDERLINE, UNDERLINEOFF, wr, YELLOW } from './logger/export.js';
|
|
35
|
-
// Matterbridge
|
|
36
10
|
import { createZip, deepCopy, getIntParameter, hasParameter, isValidNumber, isValidObject, isValidString } from './utils/utils.js';
|
|
37
11
|
import { plg } from './matterbridgeTypes.js';
|
|
38
|
-
import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
|
|
39
|
-
/**
|
|
40
|
-
* Websocket message ID for logging.
|
|
41
|
-
* @constant {number}
|
|
42
|
-
*/
|
|
43
12
|
export const WS_ID_LOG = 0;
|
|
44
|
-
/**
|
|
45
|
-
* Websocket message ID indicating a refresh is needed.
|
|
46
|
-
* @constant {number}
|
|
47
|
-
*/
|
|
48
13
|
export const WS_ID_REFRESH_NEEDED = 1;
|
|
49
|
-
/**
|
|
50
|
-
* Websocket message ID indicating a restart is needed.
|
|
51
|
-
* @constant {number}
|
|
52
|
-
*/
|
|
53
14
|
export const WS_ID_RESTART_NEEDED = 2;
|
|
54
|
-
/**
|
|
55
|
-
* Websocket message ID indicating a cpu update.
|
|
56
|
-
* @constant {number}
|
|
57
|
-
*/
|
|
58
15
|
export const WS_ID_CPU_UPDATE = 3;
|
|
59
|
-
/**
|
|
60
|
-
* Websocket message ID indicating a memory update.
|
|
61
|
-
* @constant {number}
|
|
62
|
-
*/
|
|
63
16
|
export const WS_ID_MEMORY_UPDATE = 4;
|
|
64
|
-
/**
|
|
65
|
-
* Websocket message ID indicating a memory update.
|
|
66
|
-
* @constant {number}
|
|
67
|
-
*/
|
|
68
17
|
export const WS_ID_SNACKBAR = 5;
|
|
69
|
-
/**
|
|
70
|
-
* Initializes the frontend of Matterbridge.
|
|
71
|
-
*
|
|
72
|
-
* @param port The port number to run the frontend server on. Default is 8283.
|
|
73
|
-
*/
|
|
74
18
|
export class Frontend {
|
|
75
19
|
matterbridge;
|
|
76
20
|
log;
|
|
@@ -87,7 +31,7 @@ export class Frontend {
|
|
|
87
31
|
memoryTimeout;
|
|
88
32
|
constructor(matterbridge) {
|
|
89
33
|
this.matterbridge = matterbridge;
|
|
90
|
-
this.log = new AnsiLogger({ logName: 'Frontend', logTimestampFormat: 4
|
|
34
|
+
this.log = new AnsiLogger({ logName: 'Frontend', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
91
35
|
}
|
|
92
36
|
set logLevel(logLevel) {
|
|
93
37
|
this.log.logLevel = logLevel;
|
|
@@ -95,21 +39,10 @@ export class Frontend {
|
|
|
95
39
|
async start(port = 8283) {
|
|
96
40
|
this.port = port;
|
|
97
41
|
this.log.debug(`Initializing the frontend ${hasParameter('ssl') ? 'https' : 'http'} server on port ${YELLOW}${this.port}${db}`);
|
|
98
|
-
// Create the express app that serves the frontend
|
|
99
42
|
this.expressApp = express();
|
|
100
|
-
// Log all requests to the server for debugging
|
|
101
|
-
/*
|
|
102
|
-
this.expressApp.use((req, res, next) => {
|
|
103
|
-
this.log.debug(`Received request on expressApp: ${req.method} ${req.url}`);
|
|
104
|
-
next();
|
|
105
|
-
});
|
|
106
|
-
*/
|
|
107
|
-
// Serve static files from '/static' endpoint
|
|
108
43
|
this.expressApp.use(express.static(path.join(this.matterbridge.rootDirectory, 'frontend/build')));
|
|
109
44
|
if (!hasParameter('ssl')) {
|
|
110
|
-
// Create an HTTP server and attach the express app
|
|
111
45
|
this.httpServer = createServer(this.expressApp);
|
|
112
|
-
// Listen on the specified port
|
|
113
46
|
if (hasParameter('ingress')) {
|
|
114
47
|
this.httpServer.listen(this.port, '0.0.0.0', () => {
|
|
115
48
|
this.log.info(`The frontend http server is listening on ${UNDERLINE}http://0.0.0.0:${this.port}${UNDERLINEOFF}${rs}`);
|
|
@@ -123,7 +56,6 @@ export class Frontend {
|
|
|
123
56
|
this.log.info(`The frontend http server is listening on ${UNDERLINE}http://[${this.matterbridge.systemInformation.ipv6Address}]:${this.port}${UNDERLINEOFF}${rs}`);
|
|
124
57
|
});
|
|
125
58
|
}
|
|
126
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
59
|
this.httpServer.on('error', (error) => {
|
|
128
60
|
this.log.error(`Frontend http server error listening on ${this.port}`);
|
|
129
61
|
switch (error.code) {
|
|
@@ -139,7 +71,6 @@ export class Frontend {
|
|
|
139
71
|
});
|
|
140
72
|
}
|
|
141
73
|
else {
|
|
142
|
-
// Load the SSL certificate, the private key and optionally the CA certificate
|
|
143
74
|
let cert;
|
|
144
75
|
try {
|
|
145
76
|
cert = await fs.readFile(path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pem'), 'utf8');
|
|
@@ -167,9 +98,7 @@ export class Frontend {
|
|
|
167
98
|
this.log.info(`CA certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/ca.pem')} not loaded: ${error}`);
|
|
168
99
|
}
|
|
169
100
|
const serverOptions = { cert, key, ca };
|
|
170
|
-
// Create an HTTPS server with the SSL certificate and private key (ca is optional) and attach the express app
|
|
171
101
|
this.httpsServer = https.createServer(serverOptions, this.expressApp);
|
|
172
|
-
// Listen on the specified port
|
|
173
102
|
if (hasParameter('ingress')) {
|
|
174
103
|
this.httpsServer.listen(this.port, '0.0.0.0', () => {
|
|
175
104
|
this.log.info(`The frontend https server is listening on ${UNDERLINE}https://0.0.0.0:${this.port}${UNDERLINEOFF}${rs}`);
|
|
@@ -183,7 +112,6 @@ export class Frontend {
|
|
|
183
112
|
this.log.info(`The frontend https server is listening on ${UNDERLINE}https://[${this.matterbridge.systemInformation.ipv6Address}]:${this.port}${UNDERLINEOFF}${rs}`);
|
|
184
113
|
});
|
|
185
114
|
}
|
|
186
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
187
115
|
this.httpsServer.on('error', (error) => {
|
|
188
116
|
this.log.error(`Frontend https server error listening on ${this.port}`);
|
|
189
117
|
switch (error.code) {
|
|
@@ -200,18 +128,16 @@ export class Frontend {
|
|
|
200
128
|
}
|
|
201
129
|
if (this.initializeError)
|
|
202
130
|
return;
|
|
203
|
-
// Create a WebSocket server and attach it to the http or https server
|
|
204
131
|
const wssPort = this.port;
|
|
205
132
|
const wssHost = hasParameter('ssl') ? `wss://${this.matterbridge.systemInformation.ipv4Address}:${wssPort}` : `ws://${this.matterbridge.systemInformation.ipv4Address}:${wssPort}`;
|
|
206
133
|
this.webSocketServer = new WebSocketServer(hasParameter('ssl') ? { server: this.httpsServer } : { server: this.httpServer });
|
|
207
134
|
this.webSocketServer.on('connection', (ws, request) => {
|
|
208
135
|
const clientIp = request.socket.remoteAddress;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
callbackLogLevel = "debug" /* LogLevel.DEBUG */;
|
|
136
|
+
let callbackLogLevel = "notice";
|
|
137
|
+
if (this.matterbridge.matterbridgeInformation.loggerLevel === "info" || this.matterbridge.matterbridgeInformation.matterLoggerLevel === MatterLogLevel.INFO)
|
|
138
|
+
callbackLogLevel = "info";
|
|
139
|
+
if (this.matterbridge.matterbridgeInformation.loggerLevel === "debug" || this.matterbridge.matterbridgeInformation.matterLoggerLevel === MatterLogLevel.DEBUG)
|
|
140
|
+
callbackLogLevel = "debug";
|
|
215
141
|
AnsiLogger.setGlobalCallback(this.wssSendMessage.bind(this), callbackLogLevel);
|
|
216
142
|
this.log.debug(`WebSocketServer logger global callback set to ${callbackLogLevel}`);
|
|
217
143
|
this.log.info(`WebSocketServer client "${clientIp}" connected to Matterbridge`);
|
|
@@ -245,11 +171,9 @@ export class Frontend {
|
|
|
245
171
|
this.webSocketServer.on('error', (ws, error) => {
|
|
246
172
|
this.log.error(`WebSocketServer error: ${error}`);
|
|
247
173
|
});
|
|
248
|
-
// Start the memory dump interval
|
|
249
174
|
if (hasParameter('memorydump')) {
|
|
250
175
|
this.startCpuMemoryDump();
|
|
251
176
|
}
|
|
252
|
-
// Endpoint to validate login code
|
|
253
177
|
this.expressApp.post('/api/login', express.json(), async (req, res) => {
|
|
254
178
|
const { password } = req.body;
|
|
255
179
|
this.log.debug('The frontend sent /api/login', password);
|
|
@@ -268,27 +192,23 @@ export class Frontend {
|
|
|
268
192
|
this.log.warn('/api/login error wrong password');
|
|
269
193
|
res.json({ valid: false });
|
|
270
194
|
}
|
|
271
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
272
195
|
}
|
|
273
196
|
catch (error) {
|
|
274
197
|
this.log.error('/api/login error getting password');
|
|
275
198
|
res.json({ valid: false });
|
|
276
199
|
}
|
|
277
200
|
});
|
|
278
|
-
// Endpoint to provide health check
|
|
279
201
|
this.expressApp.get('/health', (req, res) => {
|
|
280
202
|
this.log.debug('Express received /health');
|
|
281
203
|
const healthStatus = {
|
|
282
|
-
status: 'ok',
|
|
283
|
-
uptime: process.uptime(),
|
|
284
|
-
timestamp: new Date().toISOString(),
|
|
204
|
+
status: 'ok',
|
|
205
|
+
uptime: process.uptime(),
|
|
206
|
+
timestamp: new Date().toISOString(),
|
|
285
207
|
};
|
|
286
208
|
res.status(200).json(healthStatus);
|
|
287
209
|
});
|
|
288
|
-
// Endpoint to provide memory usage details
|
|
289
210
|
this.expressApp.get('/memory', async (req, res) => {
|
|
290
211
|
this.log.debug('Express received /memory');
|
|
291
|
-
// Memory usage from process
|
|
292
212
|
const memoryUsageRaw = process.memoryUsage();
|
|
293
213
|
const memoryUsage = {
|
|
294
214
|
rss: this.formatMemoryUsage(memoryUsageRaw.rss),
|
|
@@ -297,13 +217,10 @@ export class Frontend {
|
|
|
297
217
|
external: this.formatMemoryUsage(memoryUsageRaw.external),
|
|
298
218
|
arrayBuffers: this.formatMemoryUsage(memoryUsageRaw.arrayBuffers),
|
|
299
219
|
};
|
|
300
|
-
// V8 heap statistics
|
|
301
220
|
const { default: v8 } = await import('node:v8');
|
|
302
221
|
const heapStatsRaw = v8.getHeapStatistics();
|
|
303
222
|
const heapSpacesRaw = v8.getHeapSpaceStatistics();
|
|
304
|
-
// Format heapStats
|
|
305
223
|
const heapStats = Object.fromEntries(Object.entries(heapStatsRaw).map(([key, value]) => [key, this.formatMemoryUsage(value)]));
|
|
306
|
-
// Format heapSpaces
|
|
307
224
|
const heapSpaces = heapSpacesRaw.map((space) => ({
|
|
308
225
|
...space,
|
|
309
226
|
space_size: this.formatMemoryUsage(space.space_size),
|
|
@@ -313,23 +230,6 @@ export class Frontend {
|
|
|
313
230
|
}));
|
|
314
231
|
const { default: module } = await import('module');
|
|
315
232
|
const loadedModules = module._cache ? Object.keys(module._cache).sort() : [];
|
|
316
|
-
/*
|
|
317
|
-
if (req.query.heapdump === 'true') {
|
|
318
|
-
const { default: heapdump } = await import('heapdump');
|
|
319
|
-
const filename = `heapdump-${Date.now()}.heapsnapshot`;
|
|
320
|
-
|
|
321
|
-
heapdump.writeSnapshot(filename, (err, dumpFilename) => {
|
|
322
|
-
if (err) {
|
|
323
|
-
this.log.error(`Heap dump error: ${err.message}`);
|
|
324
|
-
return res.status(500).json({ error: 'Heap dump failed', details: err.message });
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
this.log.info(`Heap dump written to ${dumpFilename}`);
|
|
328
|
-
return res.status(200).json({ ...memoryReport, heapdump: dumpFilename });
|
|
329
|
-
});
|
|
330
|
-
return; // Exit early since heapdump response is handled inside callback
|
|
331
|
-
}
|
|
332
|
-
*/
|
|
333
233
|
const memoryReport = {
|
|
334
234
|
memoryUsage,
|
|
335
235
|
heapStats,
|
|
@@ -338,7 +238,6 @@ export class Frontend {
|
|
|
338
238
|
};
|
|
339
239
|
res.status(200).json(memoryReport);
|
|
340
240
|
});
|
|
341
|
-
// Endpoint to start advertising the server node
|
|
342
241
|
this.expressApp.get('/api/advertise', express.json(), async (req, res) => {
|
|
343
242
|
const pairingCodes = await this.matterbridge.advertiseServerNode(this.matterbridge.serverNode);
|
|
344
243
|
if (pairingCodes) {
|
|
@@ -349,24 +248,18 @@ export class Frontend {
|
|
|
349
248
|
res.status(500).json({ error: 'Failed to generate pairing codes' });
|
|
350
249
|
}
|
|
351
250
|
});
|
|
352
|
-
// Endpoint to provide settings
|
|
353
251
|
this.expressApp.get('/api/settings', express.json(), async (req, res) => {
|
|
354
252
|
this.log.debug('The frontend sent /api/settings');
|
|
355
253
|
res.json(await this.getApiSettings());
|
|
356
254
|
});
|
|
357
|
-
// Endpoint to provide plugins
|
|
358
255
|
this.expressApp.get('/api/plugins', async (req, res) => {
|
|
359
256
|
this.log.debug('The frontend sent /api/plugins');
|
|
360
|
-
|
|
361
|
-
// this.log.debug('Response:', debugStringify(response));
|
|
362
|
-
res.json(response);
|
|
257
|
+
res.json(this.getBaseRegisteredPlugins());
|
|
363
258
|
});
|
|
364
|
-
// Endpoint to provide devices
|
|
365
259
|
this.expressApp.get('/api/devices', (req, res) => {
|
|
366
260
|
this.log.debug('The frontend sent /api/devices');
|
|
367
261
|
const devices = [];
|
|
368
262
|
this.matterbridge.devices.forEach(async (device) => {
|
|
369
|
-
// Check if the device has the required properties
|
|
370
263
|
if (!device.plugin || !device.name || !device.deviceName || !device.serialNumber || !device.uniqueId)
|
|
371
264
|
return;
|
|
372
265
|
const cluster = this.getClusterTextFromDevice(device);
|
|
@@ -382,10 +275,8 @@ export class Frontend {
|
|
|
382
275
|
cluster: cluster,
|
|
383
276
|
});
|
|
384
277
|
});
|
|
385
|
-
// this.log.debug('Response:', debugStringify(data));
|
|
386
278
|
res.json(devices);
|
|
387
279
|
});
|
|
388
|
-
// Endpoint to provide the cluster servers of the devices
|
|
389
280
|
this.expressApp.get('/api/devices_clusters/:selectedPluginName/:selectedDeviceEndpoint', (req, res) => {
|
|
390
281
|
const selectedPluginName = req.params.selectedPluginName;
|
|
391
282
|
const selectedDeviceEndpoint = parseInt(req.params.selectedDeviceEndpoint, 10);
|
|
@@ -458,7 +349,6 @@ export class Frontend {
|
|
|
458
349
|
});
|
|
459
350
|
res.json(data);
|
|
460
351
|
});
|
|
461
|
-
// Endpoint to view the log
|
|
462
352
|
this.expressApp.get('/api/view-log', async (req, res) => {
|
|
463
353
|
this.log.debug('The frontend sent /api/log');
|
|
464
354
|
try {
|
|
@@ -471,12 +361,10 @@ export class Frontend {
|
|
|
471
361
|
res.status(500).send('Error reading log file');
|
|
472
362
|
}
|
|
473
363
|
});
|
|
474
|
-
// Endpoint to download the matterbridge log
|
|
475
364
|
this.expressApp.get('/api/download-mblog', async (req, res) => {
|
|
476
365
|
this.log.debug('The frontend sent /api/download-mblog');
|
|
477
366
|
try {
|
|
478
367
|
await fs.access(path.join(this.matterbridge.matterbridgeDirectory, this.matterbridge.matterbrideLoggerFile), fs.constants.F_OK);
|
|
479
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
480
368
|
}
|
|
481
369
|
catch (error) {
|
|
482
370
|
fs.appendFile(path.join(this.matterbridge.matterbridgeDirectory, this.matterbridge.matterbrideLoggerFile), 'Enable the log on file in the settings to enable the file logger');
|
|
@@ -488,12 +376,10 @@ export class Frontend {
|
|
|
488
376
|
}
|
|
489
377
|
});
|
|
490
378
|
});
|
|
491
|
-
// Endpoint to download the matter log
|
|
492
379
|
this.expressApp.get('/api/download-mjlog', async (req, res) => {
|
|
493
380
|
this.log.debug('The frontend sent /api/download-mjlog');
|
|
494
381
|
try {
|
|
495
382
|
await fs.access(path.join(this.matterbridge.matterbridgeDirectory, this.matterbridge.matterLoggerFile), fs.constants.F_OK);
|
|
496
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
497
383
|
}
|
|
498
384
|
catch (error) {
|
|
499
385
|
fs.appendFile(path.join(this.matterbridge.matterbridgeDirectory, this.matterbridge.matterLoggerFile), 'Enable the log on file in the settings to enable the file logger');
|
|
@@ -505,7 +391,6 @@ export class Frontend {
|
|
|
505
391
|
}
|
|
506
392
|
});
|
|
507
393
|
});
|
|
508
|
-
// Endpoint to download the matter storage file
|
|
509
394
|
this.expressApp.get('/api/download-mjstorage', async (req, res) => {
|
|
510
395
|
this.log.debug('The frontend sent /api/download-mjstorage');
|
|
511
396
|
await createZip(path.join(os.tmpdir(), `matterbridge.${this.matterbridge.matterStorageName}.zip`), path.join(this.matterbridge.matterbridgeDirectory, this.matterbridge.matterStorageName));
|
|
@@ -516,7 +401,6 @@ export class Frontend {
|
|
|
516
401
|
}
|
|
517
402
|
});
|
|
518
403
|
});
|
|
519
|
-
// Endpoint to download the matterbridge storage directory
|
|
520
404
|
this.expressApp.get('/api/download-mbstorage', async (req, res) => {
|
|
521
405
|
this.log.debug('The frontend sent /api/download-mbstorage');
|
|
522
406
|
await createZip(path.join(os.tmpdir(), `matterbridge.${this.matterbridge.nodeStorageName}.zip`), path.join(this.matterbridge.matterbridgeDirectory, this.matterbridge.nodeStorageName));
|
|
@@ -527,7 +411,6 @@ export class Frontend {
|
|
|
527
411
|
}
|
|
528
412
|
});
|
|
529
413
|
});
|
|
530
|
-
// Endpoint to download the matterbridge plugin directory
|
|
531
414
|
this.expressApp.get('/api/download-pluginstorage', async (req, res) => {
|
|
532
415
|
this.log.debug('The frontend sent /api/download-pluginstorage');
|
|
533
416
|
await createZip(path.join(os.tmpdir(), `matterbridge.pluginstorage.zip`), this.matterbridge.matterbridgePluginDirectory);
|
|
@@ -538,11 +421,9 @@ export class Frontend {
|
|
|
538
421
|
}
|
|
539
422
|
});
|
|
540
423
|
});
|
|
541
|
-
// Endpoint to download the matterbridge plugin config files
|
|
542
424
|
this.expressApp.get('/api/download-pluginconfig', async (req, res) => {
|
|
543
425
|
this.log.debug('The frontend sent /api/download-pluginconfig');
|
|
544
426
|
await createZip(path.join(os.tmpdir(), `matterbridge.pluginconfig.zip`), path.relative(process.cwd(), path.join(this.matterbridge.matterbridgeDirectory, '*.config.json')));
|
|
545
|
-
// await createZip(path.join(os.tmpdir(), `matterbridge.pluginconfig.zip`), path.relative(process.cwd(), path.join(this.matterbridge.matterbridgeDirectory, 'certs', '*.*')), path.relative(process.cwd(), path.join(this.matterbridge.matterbridgeDirectory, '*.config.json')));
|
|
546
427
|
res.download(path.join(os.tmpdir(), `matterbridge.pluginconfig.zip`), `matterbridge.pluginconfig.zip`, (error) => {
|
|
547
428
|
if (error) {
|
|
548
429
|
this.log.error(`Error downloading file matterbridge.pluginstorage.zip: ${error instanceof Error ? error.message : error}`);
|
|
@@ -550,7 +431,6 @@ export class Frontend {
|
|
|
550
431
|
}
|
|
551
432
|
});
|
|
552
433
|
});
|
|
553
|
-
// Endpoint to download the matterbridge plugin config files
|
|
554
434
|
this.expressApp.get('/api/download-backup', async (req, res) => {
|
|
555
435
|
this.log.debug('The frontend sent /api/download-backup');
|
|
556
436
|
res.download(path.join(os.tmpdir(), `matterbridge.backup.zip`), `matterbridge.backup.zip`, (error) => {
|
|
@@ -560,7 +440,6 @@ export class Frontend {
|
|
|
560
440
|
}
|
|
561
441
|
});
|
|
562
442
|
});
|
|
563
|
-
// Endpoint to receive commands
|
|
564
443
|
this.expressApp.post('/api/command/:command/:param', express.json(), async (req, res) => {
|
|
565
444
|
const command = req.params.command;
|
|
566
445
|
let param = req.params.param;
|
|
@@ -570,15 +449,13 @@ export class Frontend {
|
|
|
570
449
|
return;
|
|
571
450
|
}
|
|
572
451
|
this.log.debug(`Received frontend command: ${command}:${param}`);
|
|
573
|
-
// Handle the command setpassword from Settings
|
|
574
452
|
if (command === 'setpassword') {
|
|
575
|
-
const password = param.slice(1, -1);
|
|
453
|
+
const password = param.slice(1, -1);
|
|
576
454
|
this.log.debug('setpassword', param, password);
|
|
577
455
|
await this.matterbridge.nodeContext?.set('password', password);
|
|
578
456
|
res.json({ message: 'Command received' });
|
|
579
457
|
return;
|
|
580
458
|
}
|
|
581
|
-
// Handle the command setbridgemode from Settings
|
|
582
459
|
if (command === 'setbridgemode') {
|
|
583
460
|
this.log.debug(`setbridgemode: ${param}`);
|
|
584
461
|
this.wssSendRestartRequired();
|
|
@@ -586,7 +463,6 @@ export class Frontend {
|
|
|
586
463
|
res.json({ message: 'Command received' });
|
|
587
464
|
return;
|
|
588
465
|
}
|
|
589
|
-
// Handle the command backup from Settings
|
|
590
466
|
if (command === 'backup') {
|
|
591
467
|
this.log.notice(`Prepairing the backup...`);
|
|
592
468
|
await createZip(path.join(os.tmpdir(), `matterbridge.backup.zip`), path.join(this.matterbridge.matterbridgeDirectory), path.join(this.matterbridge.matterbridgePluginDirectory));
|
|
@@ -595,42 +471,31 @@ export class Frontend {
|
|
|
595
471
|
res.json({ message: 'Command received' });
|
|
596
472
|
return;
|
|
597
473
|
}
|
|
598
|
-
// Handle the command setmbloglevel from Settings
|
|
599
474
|
if (command === 'setmbloglevel') {
|
|
600
475
|
this.log.debug('Matterbridge log level:', param);
|
|
601
476
|
if (param === 'Debug') {
|
|
602
|
-
this.log.logLevel = "debug"
|
|
477
|
+
this.log.logLevel = "debug";
|
|
603
478
|
}
|
|
604
479
|
else if (param === 'Info') {
|
|
605
|
-
this.log.logLevel = "info"
|
|
480
|
+
this.log.logLevel = "info";
|
|
606
481
|
}
|
|
607
482
|
else if (param === 'Notice') {
|
|
608
|
-
this.log.logLevel = "notice"
|
|
483
|
+
this.log.logLevel = "notice";
|
|
609
484
|
}
|
|
610
485
|
else if (param === 'Warn') {
|
|
611
|
-
this.log.logLevel = "warn"
|
|
486
|
+
this.log.logLevel = "warn";
|
|
612
487
|
}
|
|
613
488
|
else if (param === 'Error') {
|
|
614
|
-
this.log.logLevel = "error"
|
|
489
|
+
this.log.logLevel = "error";
|
|
615
490
|
}
|
|
616
491
|
else if (param === 'Fatal') {
|
|
617
|
-
this.log.logLevel = "fatal"
|
|
492
|
+
this.log.logLevel = "fatal";
|
|
618
493
|
}
|
|
619
494
|
await this.matterbridge.nodeContext?.set('matterbridgeLogLevel', this.log.logLevel);
|
|
620
|
-
this.matterbridge.
|
|
621
|
-
MatterbridgeEndpoint.logLevel = this.log.logLevel;
|
|
622
|
-
this.matterbridge.devices.logLevel = this.log.logLevel;
|
|
623
|
-
this.matterbridge.plugins.logLevel = this.log.logLevel;
|
|
624
|
-
for (const plugin of this.matterbridge.plugins) {
|
|
625
|
-
if (!plugin.platform || !plugin.platform.config)
|
|
626
|
-
continue;
|
|
627
|
-
plugin.platform.log.logLevel = plugin.platform.config.debug ? "debug" /* LogLevel.DEBUG */ : this.log.logLevel;
|
|
628
|
-
await plugin.platform.onChangeLoggerLevel(plugin.platform.config.debug ? "debug" /* LogLevel.DEBUG */ : this.log.logLevel);
|
|
629
|
-
}
|
|
495
|
+
await this.matterbridge.setLogLevel(this.log.logLevel);
|
|
630
496
|
res.json({ message: 'Command received' });
|
|
631
497
|
return;
|
|
632
498
|
}
|
|
633
|
-
// Handle the command setmbloglevel from Settings
|
|
634
499
|
if (command === 'setmjloglevel') {
|
|
635
500
|
this.log.debug('Matter.js log level:', param);
|
|
636
501
|
if (param === 'Debug') {
|
|
@@ -655,34 +520,30 @@ export class Frontend {
|
|
|
655
520
|
res.json({ message: 'Command received' });
|
|
656
521
|
return;
|
|
657
522
|
}
|
|
658
|
-
// Handle the command setmdnsinterface from Settings
|
|
659
523
|
if (command === 'setmdnsinterface') {
|
|
660
|
-
param = param.slice(1, -1);
|
|
524
|
+
param = param.slice(1, -1);
|
|
661
525
|
this.matterbridge.matterbridgeInformation.mattermdnsinterface = param;
|
|
662
526
|
this.log.debug('Matter.js mdns interface:', param === '' ? 'All interfaces' : param);
|
|
663
527
|
await this.matterbridge.nodeContext?.set('mattermdnsinterface', param);
|
|
664
528
|
res.json({ message: 'Command received' });
|
|
665
529
|
return;
|
|
666
530
|
}
|
|
667
|
-
// Handle the command setipv4address from Settings
|
|
668
531
|
if (command === 'setipv4address') {
|
|
669
|
-
param = param.slice(1, -1);
|
|
532
|
+
param = param.slice(1, -1);
|
|
670
533
|
this.matterbridge.matterbridgeInformation.matteripv4address = param;
|
|
671
534
|
this.log.debug('Matter.js ipv4 address:', param === '' ? 'All ipv4 addresses' : param);
|
|
672
535
|
await this.matterbridge.nodeContext?.set('matteripv4address', param);
|
|
673
536
|
res.json({ message: 'Command received' });
|
|
674
537
|
return;
|
|
675
538
|
}
|
|
676
|
-
// Handle the command setipv6address from Settings
|
|
677
539
|
if (command === 'setipv6address') {
|
|
678
|
-
param = param.slice(1, -1);
|
|
540
|
+
param = param.slice(1, -1);
|
|
679
541
|
this.matterbridge.matterbridgeInformation.matteripv6address = param;
|
|
680
542
|
this.log.debug('Matter.js ipv6 address:', param === '' ? 'All ipv6 addresses' : param);
|
|
681
543
|
await this.matterbridge.nodeContext?.set('matteripv6address', param);
|
|
682
544
|
res.json({ message: 'Command received' });
|
|
683
545
|
return;
|
|
684
546
|
}
|
|
685
|
-
// Handle the command setmatterport from Settings
|
|
686
547
|
if (command === 'setmatterport') {
|
|
687
548
|
const port = Math.min(Math.max(parseInt(param), 5540), 5560);
|
|
688
549
|
this.matterbridge.matterbridgeInformation.matterPort = port;
|
|
@@ -691,7 +552,6 @@ export class Frontend {
|
|
|
691
552
|
res.json({ message: 'Command received' });
|
|
692
553
|
return;
|
|
693
554
|
}
|
|
694
|
-
// Handle the command setmatterdiscriminator from Settings
|
|
695
555
|
if (command === 'setmatterdiscriminator') {
|
|
696
556
|
const discriminator = Math.min(Math.max(parseInt(param), 1000), 4095);
|
|
697
557
|
this.matterbridge.matterbridgeInformation.matterDiscriminator = discriminator;
|
|
@@ -700,7 +560,6 @@ export class Frontend {
|
|
|
700
560
|
res.json({ message: 'Command received' });
|
|
701
561
|
return;
|
|
702
562
|
}
|
|
703
|
-
// Handle the command setmatterpasscode from Settings
|
|
704
563
|
if (command === 'setmatterpasscode') {
|
|
705
564
|
const passcode = Math.min(Math.max(parseInt(param), 10000000), 90000000);
|
|
706
565
|
this.matterbridge.matterbridgeInformation.matterPasscode = passcode;
|
|
@@ -709,20 +568,17 @@ export class Frontend {
|
|
|
709
568
|
res.json({ message: 'Command received' });
|
|
710
569
|
return;
|
|
711
570
|
}
|
|
712
|
-
// Handle the command setmbloglevel from Settings
|
|
713
571
|
if (command === 'setmblogfile') {
|
|
714
572
|
this.log.debug('Matterbridge file log:', param);
|
|
715
573
|
this.matterbridge.matterbridgeInformation.fileLogger = param === 'true';
|
|
716
574
|
await this.matterbridge.nodeContext?.set('matterbridgeFileLog', param === 'true');
|
|
717
|
-
// Create the file logger for matterbridge
|
|
718
575
|
if (param === 'true')
|
|
719
|
-
AnsiLogger.setGlobalLogfile(path.join(this.matterbridge.matterbridgeDirectory, this.matterbridge.matterbrideLoggerFile), "debug"
|
|
576
|
+
AnsiLogger.setGlobalLogfile(path.join(this.matterbridge.matterbridgeDirectory, this.matterbridge.matterbrideLoggerFile), "debug", true);
|
|
720
577
|
else
|
|
721
578
|
AnsiLogger.setGlobalLogfile(undefined);
|
|
722
579
|
res.json({ message: 'Command received' });
|
|
723
580
|
return;
|
|
724
581
|
}
|
|
725
|
-
// Handle the command setmbloglevel from Settings
|
|
726
582
|
if (command === 'setmjlogfile') {
|
|
727
583
|
this.log.debug('Matter file log:', param);
|
|
728
584
|
this.matterbridge.matterbridgeInformation.matterFileLogger = param === 'true';
|
|
@@ -749,48 +605,40 @@ export class Frontend {
|
|
|
749
605
|
res.json({ message: 'Command received' });
|
|
750
606
|
return;
|
|
751
607
|
}
|
|
752
|
-
// Handle the command unregister from Settings
|
|
753
608
|
if (command === 'unregister') {
|
|
754
609
|
await this.matterbridge.unregisterAndShutdownProcess();
|
|
755
610
|
res.json({ message: 'Command received' });
|
|
756
611
|
return;
|
|
757
612
|
}
|
|
758
|
-
// Handle the command reset from Settings
|
|
759
613
|
if (command === 'reset') {
|
|
760
614
|
await this.matterbridge.shutdownProcessAndReset();
|
|
761
615
|
res.json({ message: 'Command received' });
|
|
762
616
|
return;
|
|
763
617
|
}
|
|
764
|
-
// Handle the command factoryreset from Settings
|
|
765
618
|
if (command === 'factoryreset') {
|
|
766
619
|
await this.matterbridge.shutdownProcessAndFactoryReset();
|
|
767
620
|
res.json({ message: 'Command received' });
|
|
768
621
|
return;
|
|
769
622
|
}
|
|
770
|
-
// Handle the command shutdown from Header
|
|
771
623
|
if (command === 'shutdown') {
|
|
772
624
|
await this.matterbridge.shutdownProcess();
|
|
773
625
|
res.json({ message: 'Command received' });
|
|
774
626
|
return;
|
|
775
627
|
}
|
|
776
|
-
// Handle the command restart from Header
|
|
777
628
|
if (command === 'restart') {
|
|
778
629
|
await this.matterbridge.restartProcess();
|
|
779
630
|
res.json({ message: 'Command received' });
|
|
780
631
|
return;
|
|
781
632
|
}
|
|
782
|
-
// Handle the command update from Header
|
|
783
633
|
if (command === 'update') {
|
|
784
634
|
await this.matterbridge.updateProcess();
|
|
785
635
|
this.wssSendRestartRequired();
|
|
786
636
|
res.json({ message: 'Command received' });
|
|
787
637
|
return;
|
|
788
638
|
}
|
|
789
|
-
// Handle the command saveconfig from Home
|
|
790
639
|
if (command === 'saveconfig') {
|
|
791
640
|
param = param.replace(/\*/g, '\\');
|
|
792
641
|
this.log.info(`Saving config for plugin ${plg}${param}${nf}...`);
|
|
793
|
-
// console.log('Req.body:', JSON.stringify(req.body, null, 2));
|
|
794
642
|
if (!this.matterbridge.plugins.has(param)) {
|
|
795
643
|
this.log.warn(`Plugin ${plg}${param}${wr} not found in matterbridge`);
|
|
796
644
|
}
|
|
@@ -804,58 +652,54 @@ export class Frontend {
|
|
|
804
652
|
res.json({ message: 'Command received' });
|
|
805
653
|
return;
|
|
806
654
|
}
|
|
807
|
-
// Handle the command installplugin from Home
|
|
808
655
|
if (command === 'installplugin') {
|
|
809
656
|
param = param.replace(/\*/g, '\\');
|
|
810
657
|
this.log.info(`Installing plugin ${plg}${param}${nf}...`);
|
|
658
|
+
this.wssSendSnackbarMessage(`Installing package ${param}`);
|
|
811
659
|
try {
|
|
812
660
|
await this.matterbridge.spawnCommand('npm', ['install', '-g', param, '--omit=dev', '--verbose']);
|
|
813
661
|
this.log.info(`Plugin ${plg}${param}${nf} installed. Full restart required.`);
|
|
814
|
-
|
|
662
|
+
this.wssSendSnackbarMessage(`Installed package ${param}`);
|
|
815
663
|
}
|
|
816
664
|
catch (error) {
|
|
817
665
|
this.log.error(`Error installing plugin ${plg}${param}${er}`);
|
|
666
|
+
this.wssSendSnackbarMessage(`Package ${param} not installed`);
|
|
818
667
|
}
|
|
668
|
+
this.wssSendSnackbarMessage(`Restart required`, 0);
|
|
819
669
|
this.wssSendRestartRequired();
|
|
820
670
|
param = param.split('@')[0];
|
|
821
|
-
// Also add the plugin to matterbridge so no return!
|
|
822
671
|
if (param === 'matterbridge') {
|
|
823
|
-
// If we used the command installplugin to install a dev or a specific version of matterbridge we don't want to add it to matterbridge
|
|
824
672
|
res.json({ message: 'Command received' });
|
|
825
673
|
return;
|
|
826
674
|
}
|
|
827
675
|
}
|
|
828
|
-
// Handle the command addplugin from Home
|
|
829
676
|
if (command === 'addplugin' || command === 'installplugin') {
|
|
830
677
|
param = param.replace(/\*/g, '\\');
|
|
831
678
|
const plugin = await this.matterbridge.plugins.add(param);
|
|
832
679
|
if (plugin) {
|
|
833
680
|
if (this.matterbridge.bridgeMode === 'childbridge') {
|
|
834
|
-
// We don't know now if the plugin is a dynamic platform or an accessory platform so we create the server node and the aggregator node
|
|
835
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
836
681
|
this.matterbridge.createDynamicPlugin(plugin, true);
|
|
837
682
|
}
|
|
838
|
-
this.matterbridge.plugins.load(plugin, true, 'The plugin has been added', true)
|
|
683
|
+
this.matterbridge.plugins.load(plugin, true, 'The plugin has been added', true).then(() => {
|
|
684
|
+
this.wssSendRefreshRequired();
|
|
685
|
+
});
|
|
839
686
|
}
|
|
840
687
|
res.json({ message: 'Command received' });
|
|
841
|
-
this.wssSendRefreshRequired();
|
|
842
688
|
return;
|
|
843
689
|
}
|
|
844
|
-
// Handle the command removeplugin from Home
|
|
845
690
|
if (command === 'removeplugin') {
|
|
846
691
|
if (!this.matterbridge.plugins.has(param)) {
|
|
847
692
|
this.log.warn(`Plugin ${plg}${param}${wr} not found in matterbridge`);
|
|
848
693
|
}
|
|
849
694
|
else {
|
|
850
695
|
const plugin = this.matterbridge.plugins.get(param);
|
|
851
|
-
await this.matterbridge.plugins.shutdown(plugin, 'The plugin has been removed.', true);
|
|
696
|
+
await this.matterbridge.plugins.shutdown(plugin, 'The plugin has been removed.', true);
|
|
852
697
|
await this.matterbridge.plugins.remove(param);
|
|
853
698
|
}
|
|
854
699
|
res.json({ message: 'Command received' });
|
|
855
700
|
this.wssSendRefreshRequired();
|
|
856
701
|
return;
|
|
857
702
|
}
|
|
858
|
-
// Handle the command enableplugin from Home
|
|
859
703
|
if (command === 'enableplugin') {
|
|
860
704
|
if (!this.matterbridge.plugins.has(param)) {
|
|
861
705
|
this.log.warn(`Plugin ${plg}${param}${wr} not found in matterbridge`);
|
|
@@ -873,17 +717,17 @@ export class Frontend {
|
|
|
873
717
|
plugin.addedDevices = undefined;
|
|
874
718
|
await this.matterbridge.plugins.enable(param);
|
|
875
719
|
if (this.matterbridge.bridgeMode === 'childbridge' && plugin.type === 'DynamicPlatform') {
|
|
876
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
877
720
|
this.matterbridge.createDynamicPlugin(plugin, true);
|
|
878
721
|
}
|
|
879
|
-
this.matterbridge.plugins.load(plugin, true, 'The plugin has been enabled', true)
|
|
722
|
+
this.matterbridge.plugins.load(plugin, true, 'The plugin has been enabled', true).then(() => {
|
|
723
|
+
this.wssSendRefreshRequired();
|
|
724
|
+
});
|
|
880
725
|
}
|
|
881
726
|
}
|
|
882
727
|
res.json({ message: 'Command received' });
|
|
883
728
|
this.wssSendRefreshRequired();
|
|
884
729
|
return;
|
|
885
730
|
}
|
|
886
|
-
// Handle the command disableplugin from Home
|
|
887
731
|
if (command === 'disableplugin') {
|
|
888
732
|
if (!this.matterbridge.plugins.has(param)) {
|
|
889
733
|
this.log.warn(`Plugin ${plg}${param}${wr} not found in matterbridge`);
|
|
@@ -891,7 +735,7 @@ export class Frontend {
|
|
|
891
735
|
else {
|
|
892
736
|
const plugin = this.matterbridge.plugins.get(param);
|
|
893
737
|
if (plugin && plugin.enabled) {
|
|
894
|
-
await this.matterbridge.plugins.shutdown(plugin, 'The plugin has been disabled.', true);
|
|
738
|
+
await this.matterbridge.plugins.shutdown(plugin, 'The plugin has been disabled.', true);
|
|
895
739
|
await this.matterbridge.plugins.disable(param);
|
|
896
740
|
}
|
|
897
741
|
}
|
|
@@ -900,7 +744,6 @@ export class Frontend {
|
|
|
900
744
|
return;
|
|
901
745
|
}
|
|
902
746
|
});
|
|
903
|
-
// Fallback for routing (must be the last route)
|
|
904
747
|
this.expressApp.get('*', (req, res) => {
|
|
905
748
|
this.log.debug('The frontend sent:', req.url);
|
|
906
749
|
this.log.debug('Response send file:', path.join(this.matterbridge.rootDirectory, 'frontend/build/index.html'));
|
|
@@ -909,7 +752,6 @@ export class Frontend {
|
|
|
909
752
|
this.log.debug(`Frontend initialized on port ${YELLOW}${this.port}${db} static ${UNDERLINE}${path.join(this.matterbridge.rootDirectory, 'frontend/build')}${UNDERLINEOFF}${rs}`);
|
|
910
753
|
}
|
|
911
754
|
async stop() {
|
|
912
|
-
// Start the memory check. This will not allow the process to exit but will log the memory usage for 5 minutes.
|
|
913
755
|
if (hasParameter('memorycheck')) {
|
|
914
756
|
this.wssSendSnackbarMessage('Memory check started', getIntParameter('memorycheck') ?? 5 * 60 * 1000);
|
|
915
757
|
await new Promise((resolve) => {
|
|
@@ -921,29 +763,24 @@ export class Frontend {
|
|
|
921
763
|
}, getIntParameter('memorycheck') ?? 5 * 60 * 1000);
|
|
922
764
|
});
|
|
923
765
|
}
|
|
924
|
-
// Close the http server
|
|
925
766
|
if (this.httpServer) {
|
|
926
767
|
this.httpServer.close();
|
|
927
768
|
this.httpServer.removeAllListeners();
|
|
928
769
|
this.httpServer = undefined;
|
|
929
770
|
this.log.debug('Frontend http server closed successfully');
|
|
930
771
|
}
|
|
931
|
-
// Close the https server
|
|
932
772
|
if (this.httpsServer) {
|
|
933
773
|
this.httpsServer.close();
|
|
934
774
|
this.httpsServer.removeAllListeners();
|
|
935
775
|
this.httpsServer = undefined;
|
|
936
776
|
this.log.debug('Frontend https server closed successfully');
|
|
937
777
|
}
|
|
938
|
-
// Remove listeners from the express app
|
|
939
778
|
if (this.expressApp) {
|
|
940
779
|
this.expressApp.removeAllListeners();
|
|
941
780
|
this.expressApp = undefined;
|
|
942
781
|
this.log.debug('Frontend app closed successfully');
|
|
943
782
|
}
|
|
944
|
-
// Close the WebSocket server
|
|
945
783
|
if (this.webSocketServer) {
|
|
946
|
-
// Close all active connections
|
|
947
784
|
this.webSocketServer.clients.forEach((client) => {
|
|
948
785
|
if (client.readyState === WebSocket.OPEN) {
|
|
949
786
|
client.close();
|
|
@@ -959,12 +796,10 @@ export class Frontend {
|
|
|
959
796
|
});
|
|
960
797
|
this.webSocketServer = undefined;
|
|
961
798
|
}
|
|
962
|
-
// Stop the memory dump interval
|
|
963
799
|
if (hasParameter('memorydump')) {
|
|
964
800
|
this.stopCpuMemoryDump();
|
|
965
801
|
}
|
|
966
802
|
}
|
|
967
|
-
// Function to format bytes to KB, MB, or GB
|
|
968
803
|
formatMemoryUsage = (bytes) => {
|
|
969
804
|
if (bytes >= 1024 ** 3) {
|
|
970
805
|
return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
|
|
@@ -976,7 +811,6 @@ export class Frontend {
|
|
|
976
811
|
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
977
812
|
}
|
|
978
813
|
};
|
|
979
|
-
// Function to format system uptime with only the most significant unit
|
|
980
814
|
formatOsUpTime = () => {
|
|
981
815
|
const seconds = os.uptime();
|
|
982
816
|
if (seconds >= 86400) {
|
|
@@ -996,12 +830,11 @@ export class Frontend {
|
|
|
996
830
|
getCpuUsage = () => {
|
|
997
831
|
const currCpus = os.cpus();
|
|
998
832
|
if (currCpus.length !== this.prevCpus.length) {
|
|
999
|
-
this.prevCpus = deepCopy(currCpus);
|
|
833
|
+
this.prevCpus = deepCopy(currCpus);
|
|
1000
834
|
this.log.debug(`***Cpu usage reset. Current cpus: ${currCpus.length}. Previous cpus: ${this.prevCpus.length}.`);
|
|
1001
835
|
return this.lastCpuUsage.toFixed(2);
|
|
1002
836
|
}
|
|
1003
837
|
let totalIdle = 0, totalTick = 0;
|
|
1004
|
-
// Get the cpu usage
|
|
1005
838
|
this.prevCpus.forEach((prevCpu, i) => {
|
|
1006
839
|
const currCpu = currCpus[i];
|
|
1007
840
|
const idleDiff = currCpu.times.idle - prevCpu.times.idle;
|
|
@@ -1022,9 +855,7 @@ export class Frontend {
|
|
|
1022
855
|
clearInterval(this.memoryInterval);
|
|
1023
856
|
clearTimeout(this.memoryTimeout);
|
|
1024
857
|
const interval = () => {
|
|
1025
|
-
// Get the cpu usage
|
|
1026
858
|
const cpuUsage = this.getCpuUsage();
|
|
1027
|
-
// Get the memory usage
|
|
1028
859
|
const memoryUsageRaw = process.memoryUsage();
|
|
1029
860
|
this.memoryData.push({ ...memoryUsageRaw, cpu: cpuUsage });
|
|
1030
861
|
const memoryUsage = {
|
|
@@ -1035,7 +866,6 @@ export class Frontend {
|
|
|
1035
866
|
arrayBuffers: this.formatMemoryUsage(memoryUsageRaw.arrayBuffers),
|
|
1036
867
|
};
|
|
1037
868
|
this.log.debug(`***Cpu usage: ${CYAN}${cpuUsage.padStart(6, ' ')} %${db} - Memory usage: rss ${CYAN}${memoryUsage.rss}${db} heapTotal ${CYAN}${memoryUsage.heapTotal}${db} heapUsed ${CYAN}${memoryUsage.heapUsed}${db} external ${memoryUsage.external} arrayBuffers ${memoryUsage.arrayBuffers}`);
|
|
1038
|
-
// Update the system information
|
|
1039
869
|
this.matterbridge.systemInformation.freeMemory = this.formatMemoryUsage(os.freemem());
|
|
1040
870
|
this.matterbridge.systemInformation.totalMemory = this.formatMemoryUsage(os.totalmem());
|
|
1041
871
|
this.matterbridge.systemInformation.systemUptime = this.formatOsUpTime();
|
|
@@ -1047,7 +877,7 @@ export class Frontend {
|
|
|
1047
877
|
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);
|
|
1048
878
|
};
|
|
1049
879
|
interval();
|
|
1050
|
-
this.memoryInterval = setInterval(interval, getIntParameter('memoryinterval') ?? 1000);
|
|
880
|
+
this.memoryInterval = setInterval(interval, getIntParameter('memoryinterval') ?? 1000);
|
|
1051
881
|
this.memoryInterval.unref();
|
|
1052
882
|
this.memoryTimeout = setTimeout(() => {
|
|
1053
883
|
this.stopCpuMemoryDump();
|
|
@@ -1067,18 +897,12 @@ export class Frontend {
|
|
|
1067
897
|
external: this.formatMemoryUsage(memory.external),
|
|
1068
898
|
arrayBuffers: this.formatMemoryUsage(memory.arrayBuffers),
|
|
1069
899
|
};
|
|
1070
|
-
// eslint-disable-next-line no-console
|
|
1071
900
|
console.log(`${YELLOW}Cpu usage:${db} ${CYAN}${memory.cpu.padStart(6, ' ')} %${db} - ${YELLOW}Memory usage:${db} rss ${CYAN}${memoryUsage.rss}${db} heapTotal ${CYAN}${memoryUsage.heapTotal}${db} heapUsed ${CYAN}${memoryUsage.heapUsed}${db} external ${memoryUsage.external} arrayBuffers ${memoryUsage.arrayBuffers}${rs}`);
|
|
1072
901
|
}
|
|
1073
902
|
this.memoryData = [];
|
|
1074
903
|
this.prevCpus = [];
|
|
1075
904
|
}
|
|
1076
|
-
/**
|
|
1077
|
-
* Retrieves the api settings data.
|
|
1078
|
-
* @returns {Promise<object>} A promise that resolve in the api settings object.
|
|
1079
|
-
*/
|
|
1080
905
|
async getApiSettings() {
|
|
1081
|
-
// Update the system information
|
|
1082
906
|
this.matterbridge.systemInformation.totalMemory = this.formatMemoryUsage(os.totalmem());
|
|
1083
907
|
this.matterbridge.systemInformation.freeMemory = this.formatMemoryUsage(os.freemem());
|
|
1084
908
|
this.matterbridge.systemInformation.systemUptime = this.formatOsUpTime();
|
|
@@ -1086,7 +910,6 @@ export class Frontend {
|
|
|
1086
910
|
this.matterbridge.systemInformation.rss = this.formatMemoryUsage(process.memoryUsage().rss);
|
|
1087
911
|
this.matterbridge.systemInformation.heapTotal = this.formatMemoryUsage(process.memoryUsage().heapTotal);
|
|
1088
912
|
this.matterbridge.systemInformation.heapUsed = this.formatMemoryUsage(process.memoryUsage().heapUsed);
|
|
1089
|
-
// Update the matterbridge information
|
|
1090
913
|
this.matterbridge.matterbridgeInformation.bridgeMode = this.matterbridge.bridgeMode;
|
|
1091
914
|
this.matterbridge.matterbridgeInformation.restartMode = this.matterbridge.restartMode;
|
|
1092
915
|
this.matterbridge.matterbridgeInformation.loggerLevel = this.matterbridge.log.logLevel;
|
|
@@ -1105,11 +928,6 @@ export class Frontend {
|
|
|
1105
928
|
this.matterbridge.matterbridgeInformation.profile = this.matterbridge.profile;
|
|
1106
929
|
return { systemInformation: this.matterbridge.systemInformation, matterbridgeInformation: this.matterbridge.matterbridgeInformation };
|
|
1107
930
|
}
|
|
1108
|
-
/**
|
|
1109
|
-
* Retrieves the cluster text description from a given device.
|
|
1110
|
-
* @param {MatterbridgeDevice} device - The MatterbridgeDevice object.
|
|
1111
|
-
* @returns {string} The attributes description of the cluster servers in the device.
|
|
1112
|
-
*/
|
|
1113
931
|
getClusterTextFromDevice(device) {
|
|
1114
932
|
const getAttribute = (device, cluster, attribute) => {
|
|
1115
933
|
let value = undefined;
|
|
@@ -1148,7 +966,6 @@ export class Frontend {
|
|
|
1148
966
|
};
|
|
1149
967
|
let attributes = '';
|
|
1150
968
|
device.forEachAttribute((clusterName, clusterId, attributeName, attributeId, attributeValue) => {
|
|
1151
|
-
// console.log(`${device.deviceName} => Cluster: ${clusterName}-${clusterId} Attribute: ${attributeName}-${attributeId} Value(${typeof attributeValue}): ${attributeValue}`);
|
|
1152
969
|
if (typeof attributeValue === 'undefined')
|
|
1153
970
|
return;
|
|
1154
971
|
if (clusterName === 'onOff' && attributeName === 'onOff')
|
|
@@ -1226,13 +1043,8 @@ export class Frontend {
|
|
|
1226
1043
|
if (clusterName === 'userLabel' && attributeName === 'labelList')
|
|
1227
1044
|
attributes += `${getUserLabel(device)} `;
|
|
1228
1045
|
});
|
|
1229
|
-
// console.log(`${device.deviceName}.forEachAttribute: ${attributes}`);
|
|
1230
1046
|
return attributes.trimStart().trimEnd();
|
|
1231
1047
|
}
|
|
1232
|
-
/**
|
|
1233
|
-
* Retrieves the base registered plugins sanitized for res.json().
|
|
1234
|
-
* @returns {BaseRegisteredPlugin[]} An array of BaseRegisteredPlugin.
|
|
1235
|
-
*/
|
|
1236
1048
|
getBaseRegisteredPlugins() {
|
|
1237
1049
|
const baseRegisteredPlugins = [];
|
|
1238
1050
|
for (const plugin of this.matterbridge.plugins) {
|
|
@@ -1263,14 +1075,6 @@ export class Frontend {
|
|
|
1263
1075
|
}
|
|
1264
1076
|
return baseRegisteredPlugins;
|
|
1265
1077
|
}
|
|
1266
|
-
/**
|
|
1267
|
-
* Handles incoming websocket messages for the Matterbridge.
|
|
1268
|
-
*
|
|
1269
|
-
* @param {Matterbridge} this - The Matterbridge instance.
|
|
1270
|
-
* @param {WebSocket} client - The websocket client that sent the message.
|
|
1271
|
-
* @param {WebSocket.RawData} message - The raw data of the message received from the client.
|
|
1272
|
-
* @returns {Promise<void>} A promise that resolves when the message has been handled.
|
|
1273
|
-
*/
|
|
1274
1078
|
async wsMessageHandler(client, message) {
|
|
1275
1079
|
let data;
|
|
1276
1080
|
try {
|
|
@@ -1308,13 +1112,27 @@ export class Frontend {
|
|
|
1308
1112
|
client.send(JSON.stringify({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Wrong parameter packageName in /api/install' }));
|
|
1309
1113
|
return;
|
|
1310
1114
|
}
|
|
1115
|
+
this.wssSendSnackbarMessage(`Installing package ${data.params.packageName}`);
|
|
1311
1116
|
this.matterbridge
|
|
1312
1117
|
.spawnCommand('npm', ['install', '-g', data.params.packageName, '--omit=dev', '--verbose'])
|
|
1313
1118
|
.then((response) => {
|
|
1314
1119
|
client.send(JSON.stringify({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, response }));
|
|
1120
|
+
this.wssSendSnackbarMessage(`Installed package ${data.params.packageName}`);
|
|
1121
|
+
if (data.params.restart !== true) {
|
|
1122
|
+
this.wssSendSnackbarMessage(`Restart required`, 0);
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
if (this.matterbridge.restartMode !== '') {
|
|
1126
|
+
this.wssSendSnackbarMessage(`Restarting matterbridge...`, 0);
|
|
1127
|
+
this.matterbridge.shutdownProcess();
|
|
1128
|
+
}
|
|
1129
|
+
else
|
|
1130
|
+
this.wssSendSnackbarMessage(`Restart required`, 0);
|
|
1131
|
+
}
|
|
1315
1132
|
})
|
|
1316
1133
|
.catch((error) => {
|
|
1317
1134
|
client.send(JSON.stringify({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: error instanceof Error ? error.message : error }));
|
|
1135
|
+
this.wssSendSnackbarMessage(`Package ${data.params.packageName} not installed`);
|
|
1318
1136
|
});
|
|
1319
1137
|
return;
|
|
1320
1138
|
}
|
|
@@ -1323,6 +1141,7 @@ export class Frontend {
|
|
|
1323
1141
|
client.send(JSON.stringify({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Wrong parameter packageName in /api/uninstall' }));
|
|
1324
1142
|
return;
|
|
1325
1143
|
}
|
|
1144
|
+
this.wssSendSnackbarMessage(`Uninstalling package ${data.params.packageName}`);
|
|
1326
1145
|
this.matterbridge
|
|
1327
1146
|
.spawnCommand('npm', ['uninstall', '-g', data.params.packageName, '--verbose'])
|
|
1328
1147
|
.then((response) => {
|
|
@@ -1330,14 +1149,18 @@ export class Frontend {
|
|
|
1330
1149
|
})
|
|
1331
1150
|
.catch((error) => {
|
|
1332
1151
|
client.send(JSON.stringify({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: error instanceof Error ? error.message : error }));
|
|
1152
|
+
this.wssSendSnackbarMessage(`Uninstalled package ${data.params.packageName}`);
|
|
1153
|
+
this.wssSendSnackbarMessage(`Restart required`, 0);
|
|
1333
1154
|
});
|
|
1334
1155
|
return;
|
|
1335
1156
|
}
|
|
1336
1157
|
else if (data.method === '/api/restart') {
|
|
1158
|
+
this.wssSendSnackbarMessage(`Restarting matterbridge...`, 0);
|
|
1337
1159
|
await this.matterbridge.restartProcess();
|
|
1338
1160
|
return;
|
|
1339
1161
|
}
|
|
1340
1162
|
else if (data.method === '/api/shutdown') {
|
|
1163
|
+
this.wssSendSnackbarMessage(`Shutting down matterbridge...`, 0);
|
|
1341
1164
|
await this.matterbridge.shutdownProcess();
|
|
1342
1165
|
return;
|
|
1343
1166
|
}
|
|
@@ -1358,10 +1181,8 @@ export class Frontend {
|
|
|
1358
1181
|
else if (data.method === '/api/devices') {
|
|
1359
1182
|
const devices = [];
|
|
1360
1183
|
this.matterbridge.devices.forEach(async (device) => {
|
|
1361
|
-
// Filter by pluginName if provided
|
|
1362
1184
|
if (data.params.pluginName && data.params.pluginName !== device.plugin)
|
|
1363
1185
|
return;
|
|
1364
|
-
// Check if the device has the required properties
|
|
1365
1186
|
if (!device.plugin || !device.name || !device.deviceName || !device.serialNumber || !device.uniqueId)
|
|
1366
1187
|
return;
|
|
1367
1188
|
const cluster = this.getClusterTextFromDevice(device);
|
|
@@ -1444,7 +1265,6 @@ export class Frontend {
|
|
|
1444
1265
|
});
|
|
1445
1266
|
endpointServer.getChildEndpoints().forEach((childEndpoint) => {
|
|
1446
1267
|
deviceTypes = [];
|
|
1447
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1448
1268
|
const name = childEndpoint.endpoint?.id;
|
|
1449
1269
|
const clusterServers = childEndpoint.getAllClusterServers();
|
|
1450
1270
|
clusterServers.forEach((clusterServer) => {
|
|
@@ -1527,114 +1347,70 @@ export class Frontend {
|
|
|
1527
1347
|
return;
|
|
1528
1348
|
}
|
|
1529
1349
|
}
|
|
1530
|
-
/**
|
|
1531
|
-
* Sends a WebSocket message to all connected clients. The function is called by AnsiLogger.setGlobalCallback.
|
|
1532
|
-
*
|
|
1533
|
-
* @param {string} level - The logger level of the message: debug info notice warn error fatal...
|
|
1534
|
-
* @param {string} time - The time string of the message
|
|
1535
|
-
* @param {string} name - The logger name of the message
|
|
1536
|
-
* @param {string} message - The content of the message.
|
|
1537
|
-
*/
|
|
1538
1350
|
wssSendMessage(level, time, name, message) {
|
|
1539
1351
|
if (!level || !time || !name || !message)
|
|
1540
1352
|
return;
|
|
1541
|
-
// Remove ANSI escape codes from the message
|
|
1542
|
-
// eslint-disable-next-line no-control-regex
|
|
1543
1353
|
message = message.replace(/\x1B\[[0-9;]*[m|s|u|K]/g, '');
|
|
1544
|
-
// Remove leading asterisks from the message
|
|
1545
1354
|
message = message.replace(/^\*+/, '');
|
|
1546
|
-
// Replace all occurrences of \t and \n
|
|
1547
1355
|
message = message.replace(/[\t\n]/g, '');
|
|
1548
|
-
// Remove non-printable characters
|
|
1549
|
-
// eslint-disable-next-line no-control-regex
|
|
1550
1356
|
message = message.replace(/[\x00-\x1F\x7F]/g, '');
|
|
1551
|
-
// Replace all occurrences of \" with "
|
|
1552
1357
|
message = message.replace(/\\"/g, '"');
|
|
1553
|
-
// Define the maximum allowed length for continuous characters without a space
|
|
1554
1358
|
const maxContinuousLength = 100;
|
|
1555
1359
|
const keepStartLength = 20;
|
|
1556
1360
|
const keepEndLength = 20;
|
|
1557
|
-
// Split the message into words
|
|
1558
1361
|
message = message
|
|
1559
1362
|
.split(' ')
|
|
1560
1363
|
.map((word) => {
|
|
1561
|
-
// If the word length exceeds the max continuous length, insert spaces and truncate
|
|
1562
1364
|
if (word.length > maxContinuousLength) {
|
|
1563
1365
|
return word.slice(0, keepStartLength) + ' ... ' + word.slice(-keepEndLength);
|
|
1564
1366
|
}
|
|
1565
1367
|
return word;
|
|
1566
1368
|
})
|
|
1567
1369
|
.join(' ');
|
|
1568
|
-
// Send the message to all connected clients
|
|
1569
1370
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1570
1371
|
if (client.readyState === WebSocket.OPEN) {
|
|
1571
1372
|
client.send(JSON.stringify({ id: WS_ID_LOG, src: 'Matterbridge', level, time, name, message }));
|
|
1572
1373
|
}
|
|
1573
1374
|
});
|
|
1574
1375
|
}
|
|
1575
|
-
/**
|
|
1576
|
-
* Sends a need to refresh WebSocket message to all connected clients.
|
|
1577
|
-
*
|
|
1578
|
-
*/
|
|
1579
1376
|
wssSendRefreshRequired() {
|
|
1580
1377
|
this.log.debug('Sending a refresh required message to all connected clients');
|
|
1581
1378
|
this.matterbridge.matterbridgeInformation.refreshRequired = true;
|
|
1582
|
-
// Send the message to all connected clients
|
|
1583
1379
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1584
1380
|
if (client.readyState === WebSocket.OPEN) {
|
|
1585
1381
|
client.send(JSON.stringify({ id: WS_ID_REFRESH_NEEDED, src: 'Matterbridge', dst: 'Frontend', method: 'refresh_required', params: {} }));
|
|
1586
1382
|
}
|
|
1587
1383
|
});
|
|
1588
1384
|
}
|
|
1589
|
-
/**
|
|
1590
|
-
* Sends a need to restart WebSocket message to all connected clients.
|
|
1591
|
-
*
|
|
1592
|
-
*/
|
|
1593
1385
|
wssSendRestartRequired() {
|
|
1594
1386
|
this.log.debug('Sending a restart required message to all connected clients');
|
|
1595
1387
|
this.matterbridge.matterbridgeInformation.restartRequired = true;
|
|
1596
|
-
// Send the message to all connected clients
|
|
1597
1388
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1598
1389
|
if (client.readyState === WebSocket.OPEN) {
|
|
1599
1390
|
client.send(JSON.stringify({ id: WS_ID_RESTART_NEEDED, src: 'Matterbridge', dst: 'Frontend', method: 'restart_required', params: {} }));
|
|
1600
1391
|
}
|
|
1601
1392
|
});
|
|
1602
1393
|
}
|
|
1603
|
-
/**
|
|
1604
|
-
* Sends a memory update message to all connected clients.
|
|
1605
|
-
*
|
|
1606
|
-
*/
|
|
1607
1394
|
wssSendCpuUpdate(cpuUsed) {
|
|
1608
1395
|
this.log.debug('Sending a memory update message to all connected clients');
|
|
1609
1396
|
this.matterbridge.matterbridgeInformation.restartRequired = true;
|
|
1610
|
-
// Send the message to all connected clients
|
|
1611
1397
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1612
1398
|
if (client.readyState === WebSocket.OPEN) {
|
|
1613
1399
|
client.send(JSON.stringify({ id: WS_ID_CPU_UPDATE, src: 'Matterbridge', dst: 'Frontend', method: 'cpu_update', params: { cpuUsed } }));
|
|
1614
1400
|
}
|
|
1615
1401
|
});
|
|
1616
1402
|
}
|
|
1617
|
-
/**
|
|
1618
|
-
* Sends a cpu update message to all connected clients.
|
|
1619
|
-
*
|
|
1620
|
-
*/
|
|
1621
1403
|
wssSendMemoryUpdate(freeMemory, totalMemory, systemUptime, rss, heapUsed, heapTotal) {
|
|
1622
1404
|
this.log.debug('Sending a cpu update message to all connected clients');
|
|
1623
1405
|
this.matterbridge.matterbridgeInformation.restartRequired = true;
|
|
1624
|
-
// Send the message to all connected clients
|
|
1625
1406
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1626
1407
|
if (client.readyState === WebSocket.OPEN) {
|
|
1627
1408
|
client.send(JSON.stringify({ id: WS_ID_MEMORY_UPDATE, src: 'Matterbridge', dst: 'Frontend', method: 'memory_update', params: { freeMemory, totalMemory, systemUptime, rss, heapUsed, heapTotal } }));
|
|
1628
1409
|
}
|
|
1629
1410
|
});
|
|
1630
1411
|
}
|
|
1631
|
-
/**
|
|
1632
|
-
* Sends a cpu update message to all connected clients.
|
|
1633
|
-
*
|
|
1634
|
-
*/
|
|
1635
1412
|
wssSendSnackbarMessage(message, timeout = 5) {
|
|
1636
1413
|
this.log.debug('Sending a snackbar message to all connected clients');
|
|
1637
|
-
// Send the message to all connected clients
|
|
1638
1414
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1639
1415
|
if (client.readyState === WebSocket.OPEN) {
|
|
1640
1416
|
client.send(JSON.stringify({ id: WS_ID_SNACKBAR, src: 'Matterbridge', dst: 'Frontend', method: 'memory_update', params: { message, timeout } }));
|
|
@@ -1642,4 +1418,3 @@ export class Frontend {
|
|
|
1642
1418
|
});
|
|
1643
1419
|
}
|
|
1644
1420
|
}
|
|
1645
|
-
//# sourceMappingURL=frontend.js.map
|