matterbridge 2.1.6-dev.3 → 2.1.6-dev.5
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 +6 -2
- package/dist/cli.js +129 -85
- package/dist/frontend.js +38 -98
- package/dist/index.js +6 -8
- package/dist/matterbridge.js +56 -63
- package/dist/matterbridgeEndpoint.js +1 -1
- package/dist/matterbridgeEndpointHelpers.js +2 -2
- package/dist/matterbridgePlatform.js +2 -2
- package/dist/pluginManager.js +42 -27
- package/dist/utils/colorUtils.js +1 -1
- package/dist/utils/export.js +2 -0
- package/dist/utils/isvalid.js +50 -0
- package/dist/utils/parameter.js +26 -0
- package/dist/utils/utils.js +19 -81
- package/frontend/build/asset-manifest.json +3 -3
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/js/{main.a241d4f0.js → main.be75f5a3.js} +13 -13
- package/frontend/build/static/js/main.be75f5a3.js.map +1 -0
- package/npm-shrinkwrap.json +44 -44
- package/package.json +2 -2
- package/frontend/build/static/js/main.a241d4f0.js.map +0 -1
- /package/frontend/build/static/js/{main.a241d4f0.js.LICENSE.txt → main.be75f5a3.js.LICENSE.txt} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -33,19 +33,23 @@ matterbridge-zigbee2mqtt v. 2.4.4
|
|
|
33
33
|
matterbridge-somfy-tahoma v. 1.2.3
|
|
34
34
|
matterbridge-hass v. 0.0.8
|
|
35
35
|
|
|
36
|
-
## [2.1.6] - 2025-02-
|
|
36
|
+
## [2.1.6] - 2025-02-15
|
|
37
37
|
|
|
38
38
|
### Added
|
|
39
39
|
|
|
40
|
-
- [docker]: Added health check directly
|
|
40
|
+
- [docker]: Added health check directly in the docker image. No need to change configuration.
|
|
41
41
|
- [platform]: Saving in the storage the selects for faster loading of plugins.
|
|
42
42
|
- [icon]: Added matterbridge svg icon (thanks: https://github.com/robvanoostenrijk https://github.com/stuntguy3000).
|
|
43
|
+
- [frontend]: Added processUptime.
|
|
43
44
|
- [frontend]: Frontend v.2.4.2.
|
|
45
|
+
- [PluginManager]: Refactor PluginManager to optimize memory and load time.
|
|
44
46
|
|
|
45
47
|
### Changed
|
|
46
48
|
|
|
47
49
|
- [package]: Update matter.js to 0.12.4-alpha.0-20250212-b2729c9eb
|
|
48
50
|
- [package]: Update matter.js to 0.12.4-alpha.0-20250213-1187f81eb
|
|
51
|
+
- [package]: Update matter.js to 0.12.4-alpha.0-20250215-5af08a8d6
|
|
52
|
+
- [package]: Update matter.js to 0.12.4-alpha.0-20250217-b0bba5179
|
|
49
53
|
|
|
50
54
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
51
55
|
<img src="./yellow-button.png" alt="Buy me a coffee" width="120">
|
package/dist/cli.js
CHANGED
|
@@ -1,50 +1,69 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Matterbridge } from './matterbridge.js';
|
|
3
|
-
|
|
3
|
+
import { getIntParameter, hasParameter } from './utils/export.js';
|
|
4
|
+
import { AnsiLogger, BRIGHT, CYAN, db, YELLOW } from './logger/export.js';
|
|
5
|
+
import { EventEmitter } from 'node:events';
|
|
6
|
+
export const cliEmitter = new EventEmitter();
|
|
7
|
+
export let instance;
|
|
4
8
|
let session;
|
|
5
9
|
let memoryCheckInterval;
|
|
6
10
|
let prevCpus;
|
|
7
|
-
let lastCpuUsage = 0;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
11
|
+
export let lastCpuUsage = 0;
|
|
12
|
+
let peakCpu = 0;
|
|
13
|
+
let peakRss = 0;
|
|
14
|
+
const log = new AnsiLogger({ logName: 'Cli', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
15
|
+
const formatMemoryUsage = (bytes) => {
|
|
16
|
+
if (bytes >= 1024 ** 3) {
|
|
17
|
+
return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
|
|
18
|
+
}
|
|
19
|
+
else if (bytes >= 1024 ** 2) {
|
|
20
|
+
return `${(bytes / 1024 ** 2).toFixed(2)} MB`;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const formatOsUpTime = (seconds) => {
|
|
27
|
+
if (seconds >= 86400) {
|
|
28
|
+
const days = Math.floor(seconds / 86400);
|
|
29
|
+
return `${days} day${days !== 1 ? 's' : ''}`;
|
|
30
|
+
}
|
|
31
|
+
if (seconds >= 3600) {
|
|
32
|
+
const hours = Math.floor(seconds / 3600);
|
|
33
|
+
return `${hours} hour${hours !== 1 ? 's' : ''}`;
|
|
34
|
+
}
|
|
35
|
+
if (seconds >= 60) {
|
|
36
|
+
const minutes = Math.floor(seconds / 60);
|
|
37
|
+
return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
|
|
38
|
+
}
|
|
39
|
+
return `${seconds} second${seconds !== 1 ? 's' : ''}`;
|
|
40
|
+
};
|
|
41
|
+
async function startCpuMemoryCheck() {
|
|
28
42
|
const os = await import('node:os');
|
|
29
|
-
|
|
43
|
+
log.debug(`Cpu memory check started`);
|
|
30
44
|
prevCpus = os.cpus();
|
|
31
|
-
|
|
32
|
-
if (bytes >= 1024 ** 3) {
|
|
33
|
-
return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
|
|
34
|
-
}
|
|
35
|
-
else if (bytes >= 1024 ** 2) {
|
|
36
|
-
return `${(bytes / 1024 ** 2).toFixed(2)} MB`;
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
45
|
+
clearInterval(memoryCheckInterval);
|
|
42
46
|
const interval = () => {
|
|
47
|
+
const systemUptime = formatOsUpTime(Math.floor(os.uptime()));
|
|
48
|
+
const processUptime = formatOsUpTime(Math.floor(process.uptime()));
|
|
49
|
+
cliEmitter.emit('uptime', systemUptime, processUptime);
|
|
50
|
+
const totalMememory = formatMemoryUsage(os.totalmem());
|
|
51
|
+
const freeMemory = formatMemoryUsage(os.freemem());
|
|
52
|
+
const memoryUsageRaw = process.memoryUsage();
|
|
53
|
+
const rss = formatMemoryUsage(memoryUsageRaw.rss);
|
|
54
|
+
const heapTotal = formatMemoryUsage(memoryUsageRaw.heapTotal);
|
|
55
|
+
const heapUsed = formatMemoryUsage(memoryUsageRaw.heapUsed);
|
|
56
|
+
const external = formatMemoryUsage(memoryUsageRaw.external);
|
|
57
|
+
const arrayBuffers = formatMemoryUsage(memoryUsageRaw.arrayBuffers);
|
|
58
|
+
if (memoryUsageRaw.rss > peakRss)
|
|
59
|
+
peakRss = memoryUsageRaw.rss;
|
|
60
|
+
cliEmitter.emit('memory', totalMememory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers);
|
|
43
61
|
const currCpus = os.cpus();
|
|
44
62
|
let cpuUsageLog;
|
|
45
63
|
if (currCpus.length !== prevCpus.length) {
|
|
46
64
|
prevCpus = currCpus;
|
|
47
|
-
|
|
65
|
+
log.debug(`Cpu check length failed, resetting previous cpus`);
|
|
66
|
+
return;
|
|
48
67
|
}
|
|
49
68
|
let totalIdle = 0, totalTick = 0;
|
|
50
69
|
prevCpus.forEach((prevCpu, i) => {
|
|
@@ -56,91 +75,116 @@ async function startMemoryCheck() {
|
|
|
56
75
|
});
|
|
57
76
|
const cpuUsage = 100 - (totalIdle / totalTick) * 100;
|
|
58
77
|
if (totalTick === 0 || isNaN(cpuUsage) || !isFinite(cpuUsage) || cpuUsage <= 0) {
|
|
78
|
+
if (lastCpuUsage != 0)
|
|
79
|
+
log.debug(`Cpu check failed, using previous cpus`);
|
|
59
80
|
cpuUsageLog = lastCpuUsage.toFixed(2);
|
|
60
81
|
}
|
|
82
|
+
else {
|
|
83
|
+
cpuUsageLog = cpuUsage.toFixed(2);
|
|
84
|
+
lastCpuUsage = cpuUsage;
|
|
85
|
+
if (lastCpuUsage > peakCpu)
|
|
86
|
+
peakCpu = lastCpuUsage;
|
|
87
|
+
cliEmitter.emit('cpu', lastCpuUsage);
|
|
88
|
+
}
|
|
61
89
|
prevCpus = currCpus;
|
|
62
|
-
|
|
63
|
-
cpuUsageLog = cpuUsage.toFixed(2);
|
|
64
|
-
const memoryUsageRaw = process.memoryUsage();
|
|
65
|
-
const memoryUsage = {
|
|
66
|
-
rss: formatMemoryUsage(memoryUsageRaw.rss),
|
|
67
|
-
heapTotal: formatMemoryUsage(memoryUsageRaw.heapTotal),
|
|
68
|
-
heapUsed: formatMemoryUsage(memoryUsageRaw.heapUsed),
|
|
69
|
-
external: formatMemoryUsage(memoryUsageRaw.external),
|
|
70
|
-
arrayBuffers: formatMemoryUsage(memoryUsageRaw.arrayBuffers),
|
|
71
|
-
};
|
|
72
|
-
console.log(`${YELLOW}${BRIGHT}Cpu usage:${db} ${CYAN}${cpuUsageLog.padStart(6, ' ')} %${db} ${YELLOW}${BRIGHT}Memory usage:${db} rss ${CYAN}${memoryUsage.rss}${db} heapTotal ${CYAN}${memoryUsage.heapTotal}${db} heapUsed ${CYAN}${memoryUsage.heapUsed}${db} external ${memoryUsage.external} arrayBuffers ${memoryUsage.arrayBuffers}` +
|
|
73
|
-
rs);
|
|
90
|
+
log.debug(`***${YELLOW}${BRIGHT}Cpu usage:${db} ${CYAN}${cpuUsageLog.padStart(6, ' ')} %${db} ${YELLOW}${BRIGHT}Memory usage:${db} rss ${CYAN}${rss}${db} heapTotal ${CYAN}${heapTotal}${db} heapUsed ${CYAN}${heapUsed}${db} external ${external} arrayBuffers ${arrayBuffers}`);
|
|
74
91
|
};
|
|
75
92
|
interval();
|
|
76
|
-
memoryCheckInterval = setInterval(interval, 1000);
|
|
93
|
+
memoryCheckInterval = setInterval(interval, getIntParameter('memoryinterval') ?? 10 * 1000);
|
|
77
94
|
}
|
|
78
|
-
async function
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
setTimeout(() => {
|
|
82
|
-
console.log(cli + `CLI: Memory check stopped` + rs);
|
|
83
|
-
clearInterval(memoryCheckInterval);
|
|
84
|
-
process.exit(0);
|
|
85
|
-
}, 5 * 60 * 1000);
|
|
95
|
+
async function stopCpuMemoryCheck() {
|
|
96
|
+
log.debug(`***Cpu memory check stopped. Peak cpu: ${CYAN}${peakCpu.toFixed(2)} %${db}. Peak rss: ${CYAN}${formatMemoryUsage(peakRss)}${db}.`);
|
|
97
|
+
clearInterval(memoryCheckInterval);
|
|
86
98
|
}
|
|
87
99
|
async function startInspector() {
|
|
88
100
|
const { Session } = await import('node:inspector');
|
|
101
|
+
log.debug(`Starting heap sampling...`);
|
|
89
102
|
session = new Session();
|
|
90
103
|
session.connect();
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
console.error(err);
|
|
94
|
-
else
|
|
95
|
-
console.log(cli + `CLI: Heap sampling started` + rs);
|
|
104
|
+
await new Promise((resolve, reject) => {
|
|
105
|
+
session?.post('HeapProfiler.startSampling', {}, (err) => (err ? reject(err) : resolve()));
|
|
96
106
|
});
|
|
107
|
+
log.debug(`Started heap sampling`);
|
|
97
108
|
}
|
|
98
109
|
async function stopInspector() {
|
|
99
110
|
const { writeFileSync } = await import('node:fs');
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
111
|
+
log.debug(`Stopping heap sampling...`);
|
|
112
|
+
if (!session) {
|
|
113
|
+
log.error('No active inspector session.');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const result = await new Promise((resolve, reject) => {
|
|
118
|
+
session?.post('HeapProfiler.stopSampling', (err, result) => (err ? reject(err) : resolve(result)));
|
|
119
|
+
});
|
|
120
|
+
const profile = JSON.stringify(result.profile);
|
|
121
|
+
writeFileSync('Heap-sampling-profile.heapprofile', profile);
|
|
122
|
+
log.debug('Heap sampling profile saved to Heap-sampling-profile.heapprofile');
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
log.error(`Failed to stop heap sampling: ${err instanceof Error ? err.message : err}`);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
session.disconnect();
|
|
129
|
+
session = undefined;
|
|
130
|
+
log.debug(`Stopped heap sampling`);
|
|
131
|
+
}
|
|
110
132
|
}
|
|
111
133
|
function registerHandlers() {
|
|
134
|
+
log.debug('Registering event handlers...');
|
|
112
135
|
if (instance)
|
|
113
136
|
instance.on('shutdown', async () => shutdown());
|
|
114
137
|
if (instance)
|
|
115
138
|
instance.on('restart', async () => restart());
|
|
116
139
|
if (instance)
|
|
117
140
|
instance.on('update', async () => update());
|
|
141
|
+
if (instance)
|
|
142
|
+
instance.on('startmemorycheck', async () => start());
|
|
143
|
+
if (instance)
|
|
144
|
+
instance.on('stopmemorycheck', async () => stop());
|
|
145
|
+
log.debug('Registered event handlers');
|
|
118
146
|
}
|
|
119
147
|
async function shutdown() {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (process.argv.includes('-inspector'))
|
|
148
|
+
log.debug('Received shutdown event, exiting...');
|
|
149
|
+
if (hasParameter('inspect'))
|
|
123
150
|
await stopInspector();
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
process.exit(0);
|
|
129
|
-
}
|
|
151
|
+
await stopCpuMemoryCheck();
|
|
152
|
+
process.exit(0);
|
|
130
153
|
}
|
|
131
154
|
async function restart() {
|
|
132
|
-
|
|
133
|
-
console.log(cli + 'CLI: received restart event, loading...' + rs);
|
|
155
|
+
log.debug('Received restart event, loading...');
|
|
134
156
|
instance = await Matterbridge.loadInstance(true);
|
|
135
157
|
registerHandlers();
|
|
136
158
|
}
|
|
137
159
|
async function update() {
|
|
138
|
-
|
|
139
|
-
console.log(cli + 'CLI: received update event, updating...' + rs);
|
|
160
|
+
log.debug('Received update event, updating...');
|
|
140
161
|
instance = await Matterbridge.loadInstance(true);
|
|
141
162
|
registerHandlers();
|
|
142
163
|
}
|
|
164
|
+
async function start() {
|
|
165
|
+
log.debug('Received start memory check event');
|
|
166
|
+
startCpuMemoryCheck();
|
|
167
|
+
}
|
|
168
|
+
async function stop() {
|
|
169
|
+
log.debug('Received stop memory check event');
|
|
170
|
+
stopCpuMemoryCheck();
|
|
171
|
+
}
|
|
172
|
+
async function main() {
|
|
173
|
+
log.debug(`Cli main() started`);
|
|
174
|
+
await startCpuMemoryCheck();
|
|
175
|
+
if (hasParameter('inspect'))
|
|
176
|
+
await startInspector();
|
|
177
|
+
log.debug(`***Matterbridge.loadInstance(true) called`);
|
|
178
|
+
instance = await Matterbridge.loadInstance(true);
|
|
179
|
+
log.debug(`***Matterbridge.loadInstance(true) exited`);
|
|
180
|
+
if (instance.shutdown) {
|
|
181
|
+
shutdown();
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
registerHandlers();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
143
187
|
process.title = 'matterbridge';
|
|
144
188
|
main().catch((error) => {
|
|
145
|
-
|
|
189
|
+
log.error(`Matterbridge.loadInstance() failed with error: ${error instanceof Error ? error.message : error}`);
|
|
146
190
|
});
|
package/dist/frontend.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { EndpointServer, Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat } from '@matter/main';
|
|
2
|
-
import { createServer } from 'http';
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
3
|
import https from 'https';
|
|
4
4
|
import express from 'express';
|
|
5
5
|
import WebSocket, { WebSocketServer } from 'ws';
|
|
6
|
-
import os from 'os';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
import { promises as fs } from 'fs';
|
|
9
|
-
import { AnsiLogger, CYAN, db,
|
|
10
|
-
import { createZip, deepCopy,
|
|
6
|
+
import os from 'node:os';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { promises as fs } from 'node:fs';
|
|
9
|
+
import { AnsiLogger, stringify, debugStringify, CYAN, db, er, nf, rs, UNDERLINE, UNDERLINEOFF, wr, YELLOW } from './logger/export.js';
|
|
10
|
+
import { createZip, deepCopy, isValidNumber, isValidObject, isValidString } from './utils/export.js';
|
|
11
11
|
import { plg } from './matterbridgeTypes.js';
|
|
12
|
+
import { hasParameter } from './utils/export.js';
|
|
12
13
|
export const WS_ID_LOG = 0;
|
|
13
14
|
export const WS_ID_REFRESH_NEEDED = 1;
|
|
14
15
|
export const WS_ID_RESTART_NEEDED = 2;
|
|
15
16
|
export const WS_ID_CPU_UPDATE = 3;
|
|
16
17
|
export const WS_ID_MEMORY_UPDATE = 4;
|
|
17
|
-
export const
|
|
18
|
+
export const WS_ID_UPTIME_UPDATE = 5;
|
|
19
|
+
export const WS_ID_SNACKBAR = 6;
|
|
18
20
|
export class Frontend {
|
|
19
21
|
matterbridge;
|
|
20
22
|
log;
|
|
@@ -171,9 +173,16 @@ export class Frontend {
|
|
|
171
173
|
this.webSocketServer.on('error', (ws, error) => {
|
|
172
174
|
this.log.error(`WebSocketServer error: ${error}`);
|
|
173
175
|
});
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
const { cliEmitter } = await import('./cli.js');
|
|
177
|
+
cliEmitter.on('uptime', (systemUptime, processUptime) => {
|
|
178
|
+
this.wssSendUptimeUpdate(systemUptime, processUptime);
|
|
179
|
+
});
|
|
180
|
+
cliEmitter.on('memory', (totalMememory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers) => {
|
|
181
|
+
this.wssSendMemoryUpdate(totalMememory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers);
|
|
182
|
+
});
|
|
183
|
+
cliEmitter.on('cpu', (cpuUsage) => {
|
|
184
|
+
this.wssSendCpuUpdate(cpuUsage);
|
|
185
|
+
});
|
|
177
186
|
this.expressApp.post('/api/login', express.json(), async (req, res) => {
|
|
178
187
|
const { password } = req.body;
|
|
179
188
|
this.log.debug('The frontend sent /api/login', password);
|
|
@@ -228,7 +237,7 @@ export class Frontend {
|
|
|
228
237
|
space_available_size: this.formatMemoryUsage(space.space_available_size),
|
|
229
238
|
physical_space_size: this.formatMemoryUsage(space.physical_space_size),
|
|
230
239
|
}));
|
|
231
|
-
const { default: module } = await import('module');
|
|
240
|
+
const { default: module } = await import('node:module');
|
|
232
241
|
const loadedModules = module._cache ? Object.keys(module._cache).sort() : [];
|
|
233
242
|
const memoryReport = {
|
|
234
243
|
memoryUsage,
|
|
@@ -785,9 +794,6 @@ export class Frontend {
|
|
|
785
794
|
});
|
|
786
795
|
this.webSocketServer = undefined;
|
|
787
796
|
}
|
|
788
|
-
if (hasParameter('memorydump')) {
|
|
789
|
-
this.stopCpuMemoryDump();
|
|
790
|
-
}
|
|
791
797
|
}
|
|
792
798
|
formatMemoryUsage = (bytes) => {
|
|
793
799
|
if (bytes >= 1024 ** 3) {
|
|
@@ -800,8 +806,7 @@ export class Frontend {
|
|
|
800
806
|
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
801
807
|
}
|
|
802
808
|
};
|
|
803
|
-
formatOsUpTime = () => {
|
|
804
|
-
const seconds = os.uptime();
|
|
809
|
+
formatOsUpTime = (seconds) => {
|
|
805
810
|
if (seconds >= 86400) {
|
|
806
811
|
const days = Math.floor(seconds / 86400);
|
|
807
812
|
return `${days} day${days !== 1 ? 's' : ''}`;
|
|
@@ -816,84 +821,13 @@ export class Frontend {
|
|
|
816
821
|
}
|
|
817
822
|
return `${seconds} second${seconds !== 1 ? 's' : ''}`;
|
|
818
823
|
};
|
|
819
|
-
getCpuUsage = () => {
|
|
820
|
-
const currCpus = os.cpus();
|
|
821
|
-
if (currCpus.length !== this.prevCpus.length) {
|
|
822
|
-
this.prevCpus = deepCopy(currCpus);
|
|
823
|
-
this.log.debug(`***Cpu usage reset. Current cpus: ${currCpus.length}. Previous cpus: ${this.prevCpus.length}.`);
|
|
824
|
-
return this.lastCpuUsage.toFixed(2);
|
|
825
|
-
}
|
|
826
|
-
let totalIdle = 0, totalTick = 0;
|
|
827
|
-
this.prevCpus.forEach((prevCpu, i) => {
|
|
828
|
-
const currCpu = currCpus[i];
|
|
829
|
-
const idleDiff = currCpu.times.idle - prevCpu.times.idle;
|
|
830
|
-
const totalDiff = Object.keys(currCpu.times).reduce((acc, key) => acc + (currCpu.times[key] - prevCpu.times[key]), 0);
|
|
831
|
-
totalIdle += idleDiff;
|
|
832
|
-
totalTick += totalDiff;
|
|
833
|
-
});
|
|
834
|
-
const cpuUsage = 100 - (totalIdle / totalTick) * 100;
|
|
835
|
-
if (totalTick === 0 || isNaN(cpuUsage) || !isFinite(cpuUsage) || cpuUsage <= 0) {
|
|
836
|
-
this.log.debug('***Invalid cpu usage. Returning the previous one.');
|
|
837
|
-
return this.lastCpuUsage.toFixed(2);
|
|
838
|
-
}
|
|
839
|
-
this.prevCpus = deepCopy(currCpus);
|
|
840
|
-
this.lastCpuUsage = cpuUsage;
|
|
841
|
-
return cpuUsage.toFixed(2);
|
|
842
|
-
};
|
|
843
|
-
startCpuMemoryDump() {
|
|
844
|
-
clearInterval(this.memoryInterval);
|
|
845
|
-
clearTimeout(this.memoryTimeout);
|
|
846
|
-
const interval = () => {
|
|
847
|
-
const cpuUsage = this.getCpuUsage();
|
|
848
|
-
const memoryUsageRaw = process.memoryUsage();
|
|
849
|
-
this.memoryData.push({ ...memoryUsageRaw, cpu: cpuUsage });
|
|
850
|
-
const memoryUsage = {
|
|
851
|
-
rss: this.formatMemoryUsage(memoryUsageRaw.rss),
|
|
852
|
-
heapTotal: this.formatMemoryUsage(memoryUsageRaw.heapTotal),
|
|
853
|
-
heapUsed: this.formatMemoryUsage(memoryUsageRaw.heapUsed),
|
|
854
|
-
external: this.formatMemoryUsage(memoryUsageRaw.external),
|
|
855
|
-
arrayBuffers: this.formatMemoryUsage(memoryUsageRaw.arrayBuffers),
|
|
856
|
-
};
|
|
857
|
-
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}`);
|
|
858
|
-
this.matterbridge.systemInformation.freeMemory = this.formatMemoryUsage(os.freemem());
|
|
859
|
-
this.matterbridge.systemInformation.totalMemory = this.formatMemoryUsage(os.totalmem());
|
|
860
|
-
this.matterbridge.systemInformation.systemUptime = this.formatOsUpTime();
|
|
861
|
-
this.matterbridge.systemInformation.cpuUsed = cpuUsage;
|
|
862
|
-
this.matterbridge.systemInformation.rss = this.formatMemoryUsage(process.memoryUsage().rss);
|
|
863
|
-
this.matterbridge.systemInformation.heapTotal = this.formatMemoryUsage(process.memoryUsage().heapTotal);
|
|
864
|
-
this.matterbridge.systemInformation.heapUsed = this.formatMemoryUsage(process.memoryUsage().heapUsed);
|
|
865
|
-
this.wssSendCpuUpdate(this.matterbridge.systemInformation.cpuUsed);
|
|
866
|
-
this.wssSendMemoryUpdate(this.matterbridge.systemInformation.freeMemory, this.matterbridge.systemInformation.totalMemory, this.matterbridge.systemInformation.systemUptime, this.matterbridge.systemInformation.rss, this.matterbridge.systemInformation.heapUsed, this.matterbridge.systemInformation.heapTotal);
|
|
867
|
-
};
|
|
868
|
-
interval();
|
|
869
|
-
this.memoryInterval = setInterval(interval, getIntParameter('memoryinterval') ?? 1000).unref();
|
|
870
|
-
this.memoryTimeout = setTimeout(() => {
|
|
871
|
-
this.stopCpuMemoryDump();
|
|
872
|
-
}, getIntParameter('memorytimeout') ?? 600000).unref();
|
|
873
|
-
}
|
|
874
|
-
stopCpuMemoryDump() {
|
|
875
|
-
clearInterval(this.memoryInterval);
|
|
876
|
-
this.memoryInterval = undefined;
|
|
877
|
-
clearTimeout(this.memoryTimeout);
|
|
878
|
-
this.memoryTimeout = undefined;
|
|
879
|
-
for (const memory of this.memoryData) {
|
|
880
|
-
const memoryUsage = {
|
|
881
|
-
rss: this.formatMemoryUsage(memory.rss),
|
|
882
|
-
heapTotal: this.formatMemoryUsage(memory.heapTotal),
|
|
883
|
-
heapUsed: this.formatMemoryUsage(memory.heapUsed),
|
|
884
|
-
external: this.formatMemoryUsage(memory.external),
|
|
885
|
-
arrayBuffers: this.formatMemoryUsage(memory.arrayBuffers),
|
|
886
|
-
};
|
|
887
|
-
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}`);
|
|
888
|
-
}
|
|
889
|
-
this.memoryData = [];
|
|
890
|
-
this.prevCpus = [];
|
|
891
|
-
}
|
|
892
824
|
async getApiSettings() {
|
|
825
|
+
const { lastCpuUsage } = await import('./cli.js');
|
|
893
826
|
this.matterbridge.systemInformation.totalMemory = this.formatMemoryUsage(os.totalmem());
|
|
894
827
|
this.matterbridge.systemInformation.freeMemory = this.formatMemoryUsage(os.freemem());
|
|
895
|
-
this.matterbridge.systemInformation.systemUptime = this.formatOsUpTime();
|
|
896
|
-
this.matterbridge.systemInformation.
|
|
828
|
+
this.matterbridge.systemInformation.systemUptime = this.formatOsUpTime(os.uptime());
|
|
829
|
+
this.matterbridge.systemInformation.processUptime = this.formatOsUpTime(Math.floor(process.uptime()));
|
|
830
|
+
this.matterbridge.systemInformation.cpuUsage = lastCpuUsage.toFixed(2) + ' %';
|
|
897
831
|
this.matterbridge.systemInformation.rss = this.formatMemoryUsage(process.memoryUsage().rss);
|
|
898
832
|
this.matterbridge.systemInformation.heapTotal = this.formatMemoryUsage(process.memoryUsage().heapTotal);
|
|
899
833
|
this.matterbridge.systemInformation.heapUsed = this.formatMemoryUsage(process.memoryUsage().heapUsed);
|
|
@@ -1378,21 +1312,27 @@ export class Frontend {
|
|
|
1378
1312
|
}
|
|
1379
1313
|
});
|
|
1380
1314
|
}
|
|
1381
|
-
wssSendCpuUpdate(
|
|
1315
|
+
wssSendCpuUpdate(cpuUsage) {
|
|
1316
|
+
this.log.debug('Sending a cpu update message to all connected clients');
|
|
1317
|
+
this.webSocketServer?.clients.forEach((client) => {
|
|
1318
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1319
|
+
client.send(JSON.stringify({ id: WS_ID_CPU_UPDATE, src: 'Matterbridge', dst: 'Frontend', method: 'cpu_update', params: { cpuUsage } }));
|
|
1320
|
+
}
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
wssSendMemoryUpdate(totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers) {
|
|
1382
1324
|
this.log.debug('Sending a memory update message to all connected clients');
|
|
1383
|
-
this.matterbridge.matterbridgeInformation.restartRequired = true;
|
|
1384
1325
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1385
1326
|
if (client.readyState === WebSocket.OPEN) {
|
|
1386
|
-
client.send(JSON.stringify({ id:
|
|
1327
|
+
client.send(JSON.stringify({ id: WS_ID_MEMORY_UPDATE, src: 'Matterbridge', dst: 'Frontend', method: 'memory_update', params: { totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers } }));
|
|
1387
1328
|
}
|
|
1388
1329
|
});
|
|
1389
1330
|
}
|
|
1390
|
-
|
|
1391
|
-
this.log.debug('Sending a
|
|
1392
|
-
this.matterbridge.matterbridgeInformation.restartRequired = true;
|
|
1331
|
+
wssSendUptimeUpdate(systemUptime, processUptime) {
|
|
1332
|
+
this.log.debug('Sending a uptime update message to all connected clients');
|
|
1393
1333
|
this.webSocketServer?.clients.forEach((client) => {
|
|
1394
1334
|
if (client.readyState === WebSocket.OPEN) {
|
|
1395
|
-
client.send(JSON.stringify({ id:
|
|
1335
|
+
client.send(JSON.stringify({ id: WS_ID_UPTIME_UPDATE, src: 'Matterbridge', dst: 'Frontend', method: 'uptime_update', params: { systemUptime, processUptime } }));
|
|
1396
1336
|
}
|
|
1397
1337
|
});
|
|
1398
1338
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Matterbridge } from './matterbridge.js';
|
|
2
|
+
import { hasParameter } from './utils/export.js';
|
|
3
|
+
import { AnsiLogger } from './logger/export.js';
|
|
2
4
|
export { SemanticNamespace, ClosureTag, CompassDirectionTag, CompassLocationTag, DirectionTag, ElectricalMeasurementTag, LaundryTag, LevelTag, LocationTag, NumberTag, PositionTag, PowerSourceTag, RefrigeratorTag, RoomAirConditionerTag, SwitchesTag, } from '@matter/main';
|
|
3
5
|
export * from '@matter/main/clusters';
|
|
4
6
|
export * from '@matter/main/types';
|
|
@@ -11,16 +13,12 @@ export * from './matterbridgeDeviceTypes.js';
|
|
|
11
13
|
export * from './matterbridgePlatform.js';
|
|
12
14
|
export * from './matterbridgeAccessoryPlatform.js';
|
|
13
15
|
export * from './matterbridgeDynamicPlatform.js';
|
|
14
|
-
const
|
|
15
|
-
const er = '\u001B[38;5;9m';
|
|
16
|
-
const rs = '\u001B[40;0m';
|
|
16
|
+
const log = new AnsiLogger({ logName: 'Main', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
17
17
|
async function main() {
|
|
18
|
-
|
|
19
|
-
console.log(cli + 'MAIN: Matterbridge.loadInstance() called' + rs);
|
|
18
|
+
log.debug('***Matterbridge.loadInstance() called');
|
|
20
19
|
await Matterbridge.loadInstance();
|
|
21
|
-
|
|
22
|
-
console.log(cli + 'MAIN: Matterbridge.loadInstance() exited' + rs);
|
|
20
|
+
log.debug('***Matterbridge.loadInstance() exited');
|
|
23
21
|
}
|
|
24
22
|
main().catch((error) => {
|
|
25
|
-
|
|
23
|
+
log.error(`Matterbridge.loadInstance() failed with error: ${error instanceof Error ? error.message : error}`);
|
|
26
24
|
});
|