matterbridge 3.3.1-dev-20251009-edb969d → 3.3.1-dev-20251011-c8b30f8
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/dist/cli.js +44 -16
- package/dist/cliEmitter.js +3 -3
- package/dist/cliHistory.js +5 -1
- package/dist/frontend.js +61 -19
- package/dist/matterbridge.js +8 -11
- package/dist/matterbridgeTypes.js +2 -0
- package/frontend/build/assets/index.js +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import { inspect } from 'node:util';
|
|
5
5
|
import { AnsiLogger, BRIGHT, CYAN, db, RED, YELLOW } from 'node-ansi-logger';
|
|
6
|
-
import { cliEmitter,
|
|
6
|
+
import { cliEmitter, setLastOsCpuUsage, setLastProcessCpuUsage } from './cliEmitter.js';
|
|
7
7
|
import { history, historyIndex, historySize, setHistoryIndex } from './cliHistory.js';
|
|
8
8
|
import { getIntParameter, hasParameter } from './utils/commandLine.js';
|
|
9
9
|
import { Matterbridge } from './matterbridge.js';
|
|
@@ -21,6 +21,8 @@ let peakProcessCpu = 0;
|
|
|
21
21
|
let peakRss = 0;
|
|
22
22
|
let peakHeapUsed = 0;
|
|
23
23
|
let peakHeapTotal = 0;
|
|
24
|
+
let peakExternal = 0;
|
|
25
|
+
let peakArrayBuffers = 0;
|
|
24
26
|
const log = new AnsiLogger({ logName: 'Cli', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
25
27
|
const formatCpuUsage = (percent) => {
|
|
26
28
|
return `${percent.toFixed(2).padStart(5, ' ')} %`;
|
|
@@ -60,7 +62,7 @@ async function startCpuMemoryCheck() {
|
|
|
60
62
|
const systemUptime = formatOsUpTime(Math.floor(os.uptime()));
|
|
61
63
|
const processUptime = formatOsUpTime(Math.floor(process.uptime()));
|
|
62
64
|
cliEmitter.emit('uptime', systemUptime, processUptime);
|
|
63
|
-
const
|
|
65
|
+
const totalMemory = formatMemoryUsage(os.totalmem());
|
|
64
66
|
const freeMemory = formatMemoryUsage(os.freemem());
|
|
65
67
|
const memoryUsageRaw = process.memoryUsage();
|
|
66
68
|
const rss = formatMemoryUsage(memoryUsageRaw.rss);
|
|
@@ -83,7 +85,17 @@ async function startCpuMemoryCheck() {
|
|
|
83
85
|
log.debug(`****${RED}${BRIGHT}HeapTotal peak detected.${db} Peak heapTotal from ${CYAN}${formatMemoryUsage(peakHeapTotal)}${db} to ${CYAN}${formatMemoryUsage(memoryUsageRaw.heapTotal)}${db}`);
|
|
84
86
|
peakHeapTotal = memoryUsageRaw.heapTotal;
|
|
85
87
|
}
|
|
86
|
-
|
|
88
|
+
if (memoryUsageRaw.external > peakExternal) {
|
|
89
|
+
if (peakExternal && trace)
|
|
90
|
+
log.debug(`****${RED}${BRIGHT}External peak detected.${db} Peak external from ${CYAN}${formatMemoryUsage(peakExternal)}${db} to ${CYAN}${formatMemoryUsage(memoryUsageRaw.external)}${db}`);
|
|
91
|
+
peakExternal = memoryUsageRaw.external;
|
|
92
|
+
}
|
|
93
|
+
if (memoryUsageRaw.arrayBuffers > peakArrayBuffers) {
|
|
94
|
+
if (peakArrayBuffers && trace)
|
|
95
|
+
log.debug(`****${RED}${BRIGHT}ArrayBuffers peak detected.${db} Peak arrayBuffers from ${CYAN}${formatMemoryUsage(peakArrayBuffers)}${db} to ${CYAN}${formatMemoryUsage(memoryUsageRaw.arrayBuffers)}${db}`);
|
|
96
|
+
peakArrayBuffers = memoryUsageRaw.arrayBuffers;
|
|
97
|
+
}
|
|
98
|
+
cliEmitter.emit('memory', totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers);
|
|
87
99
|
const currCpus = os.cpus();
|
|
88
100
|
if (currCpus.length !== prevCpus.length) {
|
|
89
101
|
prevCpus = currCpus;
|
|
@@ -98,16 +110,16 @@ async function startCpuMemoryCheck() {
|
|
|
98
110
|
totalIdle += idleDiff;
|
|
99
111
|
totalTick += totalDiff;
|
|
100
112
|
});
|
|
101
|
-
const
|
|
102
|
-
if (totalTick === 0 || isNaN(
|
|
113
|
+
const osCpuUsage = 100 - (totalIdle / totalTick) * 100;
|
|
114
|
+
if (totalTick === 0 || isNaN(osCpuUsage) || !isFinite(osCpuUsage) || osCpuUsage <= 0) {
|
|
103
115
|
log.debug(`Cpu check failed, using previous cpus`);
|
|
104
116
|
}
|
|
105
117
|
else {
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
peakCpu =
|
|
118
|
+
setLastOsCpuUsage(osCpuUsage);
|
|
119
|
+
if (osCpuUsage > peakCpu) {
|
|
120
|
+
peakCpu = osCpuUsage;
|
|
109
121
|
if (peakCpu && trace)
|
|
110
|
-
log.debug(`****${RED}${BRIGHT}Cpu peak detected.${db} Peak cpu from ${CYAN}${formatCpuUsage(peakCpu)}${db} to ${CYAN}${formatCpuUsage(
|
|
122
|
+
log.debug(`****${RED}${BRIGHT}Cpu peak detected.${db} Peak cpu from ${CYAN}${formatCpuUsage(peakCpu)}${db} to ${CYAN}${formatCpuUsage(osCpuUsage)}${db}`);
|
|
111
123
|
}
|
|
112
124
|
}
|
|
113
125
|
prevCpus = currCpus;
|
|
@@ -115,7 +127,7 @@ async function startCpuMemoryCheck() {
|
|
|
115
127
|
const userMs = diff.user / 1000;
|
|
116
128
|
const systemMs = diff.system / 1000;
|
|
117
129
|
const totalMs = userMs + systemMs;
|
|
118
|
-
const processCpuUsage = Number(((totalMs / memoryCheckIntervalMs) * 100).toFixed(2));
|
|
130
|
+
const processCpuUsage = Number((((totalMs / memoryCheckIntervalMs) * 100) / currCpus.length).toFixed(2));
|
|
119
131
|
if (processCpuUsage > peakProcessCpu) {
|
|
120
132
|
peakProcessCpu = processCpuUsage;
|
|
121
133
|
if (peakProcessCpu && trace)
|
|
@@ -123,9 +135,10 @@ async function startCpuMemoryCheck() {
|
|
|
123
135
|
}
|
|
124
136
|
prevProcessCpu = process.cpuUsage();
|
|
125
137
|
setLastProcessCpuUsage(processCpuUsage);
|
|
126
|
-
cliEmitter.emit('cpu',
|
|
138
|
+
cliEmitter.emit('cpu', osCpuUsage, processCpuUsage);
|
|
127
139
|
const entry = history[historyIndex];
|
|
128
|
-
entry.
|
|
140
|
+
entry.timestamp = Date.now();
|
|
141
|
+
entry.cpu = osCpuUsage;
|
|
129
142
|
entry.peakCpu = peakCpu;
|
|
130
143
|
entry.processCpu = processCpuUsage;
|
|
131
144
|
entry.peakProcessCpu = peakProcessCpu;
|
|
@@ -135,16 +148,25 @@ async function startCpuMemoryCheck() {
|
|
|
135
148
|
entry.peakHeapUsed = peakHeapUsed;
|
|
136
149
|
entry.heapTotal = memoryUsageRaw.heapTotal;
|
|
137
150
|
entry.peakHeapTotal = peakHeapTotal;
|
|
138
|
-
entry.timestamp = Date.now();
|
|
139
151
|
setHistoryIndex((historyIndex + 1) % historySize);
|
|
140
152
|
if (trace)
|
|
141
|
-
log.debug(`***${YELLOW}${BRIGHT}Host cpu:${db}
|
|
153
|
+
log.debug(`***${YELLOW}${BRIGHT}Host cpu:${db} ` +
|
|
154
|
+
`${CYAN}${formatCpuUsage(osCpuUsage)}${db} (peak ${formatCpuUsage(peakCpu)}) ` +
|
|
155
|
+
`${YELLOW}${BRIGHT}Process cpu:${db} ` +
|
|
156
|
+
`${CYAN}${formatCpuUsage(processCpuUsage)}${db} (peak ${formatCpuUsage(peakProcessCpu)}) ` +
|
|
157
|
+
`${YELLOW}${BRIGHT}Process memory:${db} ` +
|
|
158
|
+
`rss ${CYAN}${rss}${db} (peak ${formatMemoryUsage(peakRss)}) ` +
|
|
159
|
+
`heapUsed ${CYAN}${heapUsed}${db} (peak ${formatMemoryUsage(peakHeapUsed)}) ` +
|
|
160
|
+
`heapTotal ${CYAN}${heapTotal}${db} (peak ${formatMemoryUsage(peakHeapTotal)}) ` +
|
|
161
|
+
`external ${CYAN}${external}${db} (peak ${formatMemoryUsage(peakExternal)}) ` +
|
|
162
|
+
`arrayBuffers ${CYAN}${arrayBuffers}${db} (peak ${formatMemoryUsage(peakArrayBuffers)})`);
|
|
142
163
|
};
|
|
143
164
|
clearInterval(memoryCheckInterval);
|
|
144
165
|
memoryCheckInterval = setInterval(interval, memoryCheckIntervalMs).unref();
|
|
145
166
|
clearTimeout(memoryPeakResetTimeout);
|
|
146
167
|
memoryPeakResetTimeout = setTimeout(() => {
|
|
147
|
-
|
|
168
|
+
if (trace)
|
|
169
|
+
log.debug(`****${RED}${BRIGHT}Cpu and memory peaks reset after first 5 minutes.${db}`);
|
|
148
170
|
peakCpu = 0;
|
|
149
171
|
peakProcessCpu = 0;
|
|
150
172
|
peakRss = 0;
|
|
@@ -154,7 +176,13 @@ async function startCpuMemoryCheck() {
|
|
|
154
176
|
}
|
|
155
177
|
async function stopCpuMemoryCheck() {
|
|
156
178
|
if (trace) {
|
|
157
|
-
log.debug(`***Cpu memory check stopped.
|
|
179
|
+
log.debug(`***Cpu memory check stopped. ` +
|
|
180
|
+
`Peak cpu: ${CYAN}${peakCpu.toFixed(2)} %${db}. ` +
|
|
181
|
+
`Peak rss: ${CYAN}${formatMemoryUsage(peakRss)}${db}. ` +
|
|
182
|
+
`Peak heapUsed: ${CYAN}${formatMemoryUsage(peakHeapUsed)}${db}. ` +
|
|
183
|
+
`Peak heapTotal: ${CYAN}${formatMemoryUsage(peakHeapTotal)}${db}. ` +
|
|
184
|
+
`Peak external: ${CYAN}${formatMemoryUsage(peakExternal)}${db}. ` +
|
|
185
|
+
`Peak arrayBuffers: ${CYAN}${formatMemoryUsage(peakArrayBuffers)}${db}.`);
|
|
158
186
|
}
|
|
159
187
|
clearInterval(memoryCheckInterval);
|
|
160
188
|
clearTimeout(memoryPeakResetTimeout);
|
package/dist/cliEmitter.js
CHANGED
|
@@ -2,10 +2,10 @@ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
|
|
|
2
2
|
console.log('\u001B[32mCli emitter loaded.\u001B[40;0m');
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
4
|
export const cliEmitter = new EventEmitter();
|
|
5
|
-
export let
|
|
5
|
+
export let lastOsCpuUsage = 0;
|
|
6
6
|
export let lastProcessCpuUsage = 0;
|
|
7
|
-
export function
|
|
8
|
-
|
|
7
|
+
export function setLastOsCpuUsage(val) {
|
|
8
|
+
lastOsCpuUsage = val;
|
|
9
9
|
}
|
|
10
10
|
export function setLastProcessCpuUsage(val) {
|
|
11
11
|
lastProcessCpuUsage = val;
|
package/dist/cliHistory.js
CHANGED
|
@@ -14,6 +14,7 @@ export function setHistoryIndex(index) {
|
|
|
14
14
|
historyIndex = index;
|
|
15
15
|
}
|
|
16
16
|
export const history = Array.from({ length: historySize }, () => ({
|
|
17
|
+
timestamp: 0,
|
|
17
18
|
cpu: 0,
|
|
18
19
|
peakCpu: 0,
|
|
19
20
|
processCpu: 0,
|
|
@@ -24,7 +25,10 @@ export const history = Array.from({ length: historySize }, () => ({
|
|
|
24
25
|
peakHeapUsed: 0,
|
|
25
26
|
heapTotal: 0,
|
|
26
27
|
peakHeapTotal: 0,
|
|
27
|
-
|
|
28
|
+
external: 0,
|
|
29
|
+
peakExternal: 0,
|
|
30
|
+
arrayBuffers: 0,
|
|
31
|
+
peakArrayBuffers: 0,
|
|
28
32
|
}));
|
|
29
33
|
export function generateHistoryPage(options = {}) {
|
|
30
34
|
const pageTitle = options.pageTitle ?? 'Matterbridge CPU & Memory History';
|
package/dist/frontend.js
CHANGED
|
@@ -3,20 +3,21 @@ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import EventEmitter from 'node:events';
|
|
6
|
-
import express from 'express';
|
|
7
|
-
import WebSocket, { WebSocketServer } from 'ws';
|
|
8
|
-
import multer from 'multer';
|
|
9
6
|
import { AnsiLogger, stringify, debugStringify, CYAN, db, er, nf, rs, UNDERLINE, UNDERLINEOFF, YELLOW, nt, wr } from 'node-ansi-logger';
|
|
10
7
|
import { Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, Lifecycle, LogDestination, Diagnostic, Time, FabricIndex } from '@matter/main';
|
|
11
8
|
import { BridgedDeviceBasicInformation } from '@matter/main/clusters/bridged-device-basic-information';
|
|
12
9
|
import { PowerSource } from '@matter/main/clusters/power-source';
|
|
13
10
|
import { DeviceAdvertiser, DeviceCommissioner, FabricManager } from '@matter/main/protocol';
|
|
14
11
|
import { CommissioningOptions } from '@matter/main/types';
|
|
15
|
-
import { MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg } from './matterbridgeTypes.js';
|
|
16
|
-
import {
|
|
12
|
+
import { MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, MATTERBRIDGE_DIAGNOSTIC_FILE, MATTERBRIDGE_HISTORY_FILE, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg } from './matterbridgeTypes.js';
|
|
13
|
+
import { isValidArray, isValidNumber, isValidObject, isValidString, isValidBoolean } from './utils/isvalid.js';
|
|
14
|
+
import { createZip } from './utils/createZip.js';
|
|
15
|
+
import { hasParameter } from './utils/commandLine.js';
|
|
16
|
+
import { withTimeout, wait } from './utils/wait.js';
|
|
17
|
+
import { inspectError } from './utils/error.js';
|
|
17
18
|
import { formatMemoryUsage, formatOsUpTime } from './utils/network.js';
|
|
18
19
|
import { capitalizeFirstLetter, getAttribute } from './matterbridgeEndpointHelpers.js';
|
|
19
|
-
import { cliEmitter,
|
|
20
|
+
import { cliEmitter, lastOsCpuUsage, lastProcessCpuUsage } from './cliEmitter.js';
|
|
20
21
|
import { generateHistoryPage } from './cliHistory.js';
|
|
21
22
|
import { BroadcastServer } from './broadcastServer.js';
|
|
22
23
|
export class Frontend extends EventEmitter {
|
|
@@ -94,9 +95,11 @@ export class Frontend extends EventEmitter {
|
|
|
94
95
|
async start(port = 8283) {
|
|
95
96
|
this.port = port;
|
|
96
97
|
this.log.debug(`Initializing the frontend ${hasParameter('ssl') ? 'https' : 'http'} server on port ${YELLOW}${this.port}${db}`);
|
|
98
|
+
const multer = await import('multer');
|
|
97
99
|
const uploadDir = path.join(this.matterbridge.matterbridgeDirectory, 'uploads');
|
|
98
|
-
const upload = multer({ dest: uploadDir });
|
|
99
|
-
|
|
100
|
+
const upload = multer.default({ dest: uploadDir });
|
|
101
|
+
const express = await import('express');
|
|
102
|
+
this.expressApp = express.default();
|
|
100
103
|
this.expressApp.use(express.static(path.join(this.matterbridge.rootDirectory, 'frontend/build')));
|
|
101
104
|
if (!hasParameter('ssl')) {
|
|
102
105
|
const http = await import('node:http');
|
|
@@ -245,8 +248,9 @@ export class Frontend extends EventEmitter {
|
|
|
245
248
|
return;
|
|
246
249
|
});
|
|
247
250
|
}
|
|
251
|
+
const ws = await import('ws');
|
|
248
252
|
this.log.debug(`Creating WebSocketServer...`);
|
|
249
|
-
this.webSocketServer = new WebSocketServer(hasParameter('ssl') ? { server: this.httpsServer } : { server: this.httpServer });
|
|
253
|
+
this.webSocketServer = new ws.WebSocketServer(hasParameter('ssl') ? { server: this.httpsServer } : { server: this.httpServer });
|
|
250
254
|
this.webSocketServer.on('connection', (ws, request) => {
|
|
251
255
|
const clientIp = request.socket.remoteAddress;
|
|
252
256
|
let callbackLogLevel = "notice";
|
|
@@ -419,11 +423,11 @@ export class Frontend extends EventEmitter {
|
|
|
419
423
|
serverNodes.push(device.serverNode);
|
|
420
424
|
}
|
|
421
425
|
const fs = await import('node:fs');
|
|
422
|
-
if (fs.existsSync(path.join(this.matterbridge.matterbridgeDirectory,
|
|
423
|
-
fs.unlinkSync(path.join(this.matterbridge.matterbridgeDirectory,
|
|
426
|
+
if (fs.existsSync(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_DIAGNOSTIC_FILE)))
|
|
427
|
+
fs.unlinkSync(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_DIAGNOSTIC_FILE));
|
|
424
428
|
const diagnosticDestination = LogDestination({ name: 'diagnostic', level: MatterLogLevel.INFO, format: MatterLogFormat.formats.plain });
|
|
425
429
|
diagnosticDestination.write = async (text, _message) => {
|
|
426
|
-
await fs.promises.appendFile(path.join(this.matterbridge.matterbridgeDirectory,
|
|
430
|
+
await fs.promises.appendFile(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_DIAGNOSTIC_FILE), text + '\n', { encoding: 'utf8' });
|
|
427
431
|
};
|
|
428
432
|
Logger.destinations.diagnostic = diagnosticDestination;
|
|
429
433
|
if (!diagnosticDestination.context) {
|
|
@@ -440,15 +444,28 @@ export class Frontend extends EventEmitter {
|
|
|
440
444
|
await wait(500);
|
|
441
445
|
try {
|
|
442
446
|
const fs = await import('node:fs');
|
|
443
|
-
const data = await fs.promises.readFile(path.join(this.matterbridge.matterbridgeDirectory,
|
|
447
|
+
const data = await fs.promises.readFile(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_DIAGNOSTIC_FILE), 'utf8');
|
|
444
448
|
res.type('text/plain');
|
|
445
449
|
res.send(data.slice(29));
|
|
446
450
|
}
|
|
447
451
|
catch (error) {
|
|
448
|
-
this.log.error(`Error reading diagnostic log file ${
|
|
452
|
+
this.log.error(`Error reading diagnostic log file ${MATTERBRIDGE_DIAGNOSTIC_FILE}: ${error instanceof Error ? error.message : error}`);
|
|
449
453
|
res.status(500).send('Error reading diagnostic log file.');
|
|
450
454
|
}
|
|
451
455
|
});
|
|
456
|
+
this.expressApp.get('/api/viewhistory', async (req, res) => {
|
|
457
|
+
this.log.debug('The frontend sent /api/viewhistory');
|
|
458
|
+
try {
|
|
459
|
+
const fs = await import('node:fs');
|
|
460
|
+
const data = await fs.promises.readFile(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_HISTORY_FILE), 'utf8');
|
|
461
|
+
res.type('text/html');
|
|
462
|
+
res.send(data);
|
|
463
|
+
}
|
|
464
|
+
catch (error) {
|
|
465
|
+
this.log.error(`Error reading history log file ${MATTERBRIDGE_HISTORY_FILE}: ${error instanceof Error ? error.message : error}`);
|
|
466
|
+
res.status(500).send('Error reading history log file. Please create the history log before loading it.');
|
|
467
|
+
}
|
|
468
|
+
});
|
|
452
469
|
this.expressApp.get('/api/shellyviewsystemlog', async (req, res) => {
|
|
453
470
|
this.log.debug('The frontend sent /api/shellyviewsystemlog');
|
|
454
471
|
try {
|
|
@@ -612,6 +629,7 @@ export class Frontend extends EventEmitter {
|
|
|
612
629
|
}
|
|
613
630
|
async stop() {
|
|
614
631
|
this.log.debug('Stopping the frontend...');
|
|
632
|
+
const ws = await import('ws');
|
|
615
633
|
if (this.expressApp) {
|
|
616
634
|
this.expressApp.removeAllListeners();
|
|
617
635
|
this.expressApp = undefined;
|
|
@@ -620,7 +638,7 @@ export class Frontend extends EventEmitter {
|
|
|
620
638
|
if (this.webSocketServer) {
|
|
621
639
|
this.log.debug('Closing WebSocket server...');
|
|
622
640
|
this.webSocketServer.clients.forEach((client) => {
|
|
623
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
641
|
+
if (client.readyState === ws.WebSocket.OPEN) {
|
|
624
642
|
client.close();
|
|
625
643
|
}
|
|
626
644
|
});
|
|
@@ -666,7 +684,7 @@ export class Frontend extends EventEmitter {
|
|
|
666
684
|
this.matterbridge.systemInformation.freeMemory = formatMemoryUsage(os.freemem());
|
|
667
685
|
this.matterbridge.systemInformation.systemUptime = formatOsUpTime(os.uptime());
|
|
668
686
|
this.matterbridge.systemInformation.processUptime = formatOsUpTime(Math.floor(process.uptime()));
|
|
669
|
-
this.matterbridge.systemInformation.cpuUsage =
|
|
687
|
+
this.matterbridge.systemInformation.cpuUsage = lastOsCpuUsage.toFixed(2) + ' %';
|
|
670
688
|
this.matterbridge.systemInformation.processCpuUsage = lastProcessCpuUsage.toFixed(2) + ' %';
|
|
671
689
|
this.matterbridge.systemInformation.rss = formatMemoryUsage(process.memoryUsage().rss);
|
|
672
690
|
this.matterbridge.systemInformation.heapTotal = formatMemoryUsage(process.memoryUsage().heapTotal);
|
|
@@ -986,7 +1004,7 @@ export class Frontend extends EventEmitter {
|
|
|
986
1004
|
async wsMessageHandler(client, message) {
|
|
987
1005
|
let data;
|
|
988
1006
|
const sendResponse = (data) => {
|
|
989
|
-
if (client.readyState ===
|
|
1007
|
+
if (client.readyState === client.OPEN) {
|
|
990
1008
|
if ('response' in data) {
|
|
991
1009
|
const { response, ...rest } = data;
|
|
992
1010
|
this.log.debug(`Sending api response message: ${debugStringify(rest)}`);
|
|
@@ -1271,7 +1289,7 @@ export class Frontend extends EventEmitter {
|
|
|
1271
1289
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1272
1290
|
}
|
|
1273
1291
|
else if (data.method === '/api/generatehistorypage') {
|
|
1274
|
-
generateHistoryPage({ outputPath: path.join(this.matterbridge.
|
|
1292
|
+
generateHistoryPage({ outputPath: path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_HISTORY_FILE), pageTitle: `Matterbridge on ${this.matterbridge.systemInformation.hostname} Cpu & Memory History` });
|
|
1275
1293
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1276
1294
|
}
|
|
1277
1295
|
else if (data.method === '/api/matter') {
|
|
@@ -1708,6 +1726,8 @@ export class Frontend extends EventEmitter {
|
|
|
1708
1726
|
}
|
|
1709
1727
|
}
|
|
1710
1728
|
wssSendLogMessage(level, time, name, message) {
|
|
1729
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1730
|
+
return;
|
|
1711
1731
|
if (!level || !time || !name || !message)
|
|
1712
1732
|
return;
|
|
1713
1733
|
message = message.replace(/\x1B\[[0-9;]*[m|s|u|K]/g, '');
|
|
@@ -1732,10 +1752,14 @@ export class Frontend extends EventEmitter {
|
|
|
1732
1752
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'log', success: true, response: { level, time, name, message } });
|
|
1733
1753
|
}
|
|
1734
1754
|
wssSendRefreshRequired(changed, params) {
|
|
1755
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1756
|
+
return;
|
|
1735
1757
|
this.log.debug('Sending a refresh required message to all connected clients');
|
|
1736
1758
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'refresh_required', success: true, response: { changed, ...params } });
|
|
1737
1759
|
}
|
|
1738
1760
|
wssSendRestartRequired(snackbar = true, fixed = false) {
|
|
1761
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1762
|
+
return;
|
|
1739
1763
|
this.log.debug('Sending a restart required message to all connected clients');
|
|
1740
1764
|
this.matterbridge.restartRequired = true;
|
|
1741
1765
|
this.matterbridge.fixedRestartRequired = fixed;
|
|
@@ -1744,6 +1768,8 @@ export class Frontend extends EventEmitter {
|
|
|
1744
1768
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'restart_required', success: true, response: { fixed } });
|
|
1745
1769
|
}
|
|
1746
1770
|
wssSendRestartNotRequired(snackbar = true) {
|
|
1771
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1772
|
+
return;
|
|
1747
1773
|
this.log.debug('Sending a restart not required message to all connected clients');
|
|
1748
1774
|
this.matterbridge.restartRequired = false;
|
|
1749
1775
|
if (snackbar === true)
|
|
@@ -1751,43 +1777,59 @@ export class Frontend extends EventEmitter {
|
|
|
1751
1777
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'restart_not_required', success: true });
|
|
1752
1778
|
}
|
|
1753
1779
|
wssSendUpdateRequired(devVersion = false) {
|
|
1780
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1781
|
+
return;
|
|
1754
1782
|
this.log.debug('Sending an update required message to all connected clients');
|
|
1755
1783
|
this.matterbridge.updateRequired = true;
|
|
1756
1784
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'update_required', success: true, response: { devVersion } });
|
|
1757
1785
|
}
|
|
1758
1786
|
wssSendCpuUpdate(cpuUsage, processCpuUsage) {
|
|
1787
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1788
|
+
return;
|
|
1759
1789
|
if (hasParameter('debug'))
|
|
1760
1790
|
this.log.debug('Sending a cpu update message to all connected clients');
|
|
1761
1791
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'cpu_update', success: true, response: { cpuUsage: Math.round(cpuUsage * 100) / 100, processCpuUsage: Math.round(processCpuUsage * 100) / 100 } });
|
|
1762
1792
|
}
|
|
1763
1793
|
wssSendMemoryUpdate(totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers) {
|
|
1794
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1795
|
+
return;
|
|
1764
1796
|
if (hasParameter('debug'))
|
|
1765
1797
|
this.log.debug('Sending a memory update message to all connected clients');
|
|
1766
1798
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'memory_update', success: true, response: { totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers } });
|
|
1767
1799
|
}
|
|
1768
1800
|
wssSendUptimeUpdate(systemUptime, processUptime) {
|
|
1801
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1802
|
+
return;
|
|
1769
1803
|
if (hasParameter('debug'))
|
|
1770
1804
|
this.log.debug('Sending a uptime update message to all connected clients');
|
|
1771
1805
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'uptime_update', success: true, response: { systemUptime, processUptime } });
|
|
1772
1806
|
}
|
|
1773
1807
|
wssSendSnackbarMessage(message, timeout = 5, severity = 'info') {
|
|
1808
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1809
|
+
return;
|
|
1774
1810
|
this.log.debug('Sending a snackbar message to all connected clients');
|
|
1775
1811
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'snackbar', success: true, response: { message, timeout, severity } });
|
|
1776
1812
|
}
|
|
1777
1813
|
wssSendCloseSnackbarMessage(message) {
|
|
1814
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1815
|
+
return;
|
|
1778
1816
|
this.log.debug('Sending a close snackbar message to all connected clients');
|
|
1779
1817
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'close_snackbar', success: true, response: { message } });
|
|
1780
1818
|
}
|
|
1781
1819
|
wssSendAttributeChangedMessage(plugin, serialNumber, uniqueId, number, id, cluster, attribute, value) {
|
|
1820
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1821
|
+
return;
|
|
1782
1822
|
this.log.debug('Sending an attribute update message to all connected clients');
|
|
1783
1823
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'state_update', success: true, response: { plugin, serialNumber, uniqueId, number, id, cluster, attribute, value } });
|
|
1784
1824
|
}
|
|
1785
1825
|
wssBroadcastMessage(msg) {
|
|
1826
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1827
|
+
return;
|
|
1786
1828
|
const stringifiedMsg = JSON.stringify(msg);
|
|
1787
1829
|
if (msg.method !== 'log')
|
|
1788
1830
|
this.log.debug(`Sending a broadcast message: ${debugStringify(msg)}`);
|
|
1789
1831
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1790
|
-
if (client.readyState ===
|
|
1832
|
+
if (client.readyState === client.OPEN) {
|
|
1791
1833
|
client.send(stringifiedMsg);
|
|
1792
1834
|
}
|
|
1793
1835
|
});
|
package/dist/matterbridge.js
CHANGED
|
@@ -871,26 +871,23 @@ export class Matterbridge extends EventEmitter {
|
|
|
871
871
|
this.log.debug(`Command Line Arguments: ${cmdArgs}`);
|
|
872
872
|
}
|
|
873
873
|
async setLogLevel(logLevel) {
|
|
874
|
-
|
|
875
|
-
this.log.logLevel = logLevel;
|
|
874
|
+
this.log.logLevel = logLevel;
|
|
876
875
|
this.frontend.logLevel = logLevel;
|
|
877
876
|
MatterbridgeEndpoint.logLevel = logLevel;
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
if (this.plugins)
|
|
881
|
-
this.plugins.logLevel = logLevel;
|
|
877
|
+
this.devices.logLevel = logLevel;
|
|
878
|
+
this.plugins.logLevel = logLevel;
|
|
882
879
|
for (const plugin of this.plugins) {
|
|
883
880
|
if (!plugin.platform || !plugin.platform.log || !plugin.platform.config)
|
|
884
881
|
continue;
|
|
885
|
-
plugin.platform.log.logLevel = plugin.platform.config.debug === true ? "debug" :
|
|
886
|
-
await plugin.platform.onChangeLoggerLevel(plugin.platform.config.debug === true ? "debug" :
|
|
882
|
+
plugin.platform.log.logLevel = plugin.platform.config.debug === true ? "debug" : logLevel;
|
|
883
|
+
await plugin.platform.onChangeLoggerLevel(plugin.platform.config.debug === true ? "debug" : logLevel);
|
|
887
884
|
}
|
|
888
885
|
let callbackLogLevel = "notice";
|
|
889
|
-
if (
|
|
886
|
+
if (logLevel === "info" || Logger.level === MatterLogLevel.INFO)
|
|
890
887
|
callbackLogLevel = "info";
|
|
891
|
-
if (
|
|
888
|
+
if (logLevel === "debug" || Logger.level === MatterLogLevel.DEBUG)
|
|
892
889
|
callbackLogLevel = "debug";
|
|
893
|
-
AnsiLogger.
|
|
890
|
+
AnsiLogger.setGlobalCallbackLevel(callbackLogLevel);
|
|
894
891
|
this.log.debug(`WebSocketServer logger global callback set to ${callbackLogLevel}`);
|
|
895
892
|
}
|
|
896
893
|
getLogLevel() {
|
|
@@ -5,3 +5,5 @@ export const MATTERBRIDGE_LOGGER_FILE = 'matterbridge.log';
|
|
|
5
5
|
export const MATTER_LOGGER_FILE = 'matter.log';
|
|
6
6
|
export const NODE_STORAGE_DIR = 'storage';
|
|
7
7
|
export const MATTER_STORAGE_NAME = 'matterstorage';
|
|
8
|
+
export const MATTERBRIDGE_DIAGNOSTIC_FILE = 'diagnostic.log';
|
|
9
|
+
export const MATTERBRIDGE_HISTORY_FILE = 'history.html';
|