matterbridge 2.1.5-dev.2 → 2.1.5-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -33,13 +33,18 @@ 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.5] - 2025-02-08
36
+ ## [2.1.5] - 2025-02-09
37
37
 
38
38
  ### Added
39
39
 
40
+ - [frontend]: Frontend v.2.4.1.
41
+ - [frontend]: Optimized rendering of all pages.
42
+ - [frontend]: Added cpuUsed, rss and heapUsed to SystemInformation.
43
+
40
44
  ### Changed
41
45
 
42
46
  - [matterbridge]: Calls getNpmPackageVersion() instead of npm to get latest version.
47
+ - [matterbridge]: Memory optimization on MatterbridgeEndpoint.
43
48
 
44
49
  ### Fixed
45
50
 
package/dist/frontend.js CHANGED
@@ -7,12 +7,14 @@ import os from 'os';
7
7
  import path from 'path';
8
8
  import { promises as fs } from 'fs';
9
9
  import { AnsiLogger, CYAN, db, debugStringify, er, nf, rs, stringify, UNDERLINE, UNDERLINEOFF, wr, YELLOW } from './logger/export.js';
10
- import { createZip, getIntParameter, hasParameter, isValidNumber, isValidObject, isValidString } from './utils/utils.js';
10
+ import { createZip, deepCopy, getIntParameter, hasParameter, isValidNumber, isValidObject, isValidString } from './utils/utils.js';
11
11
  import { plg } from './matterbridgeTypes.js';
12
12
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
13
13
  export const WS_ID_LOG = 0;
14
14
  export const WS_ID_REFRESH_NEEDED = 1;
15
15
  export const WS_ID_RESTART_NEEDED = 2;
16
+ export const WS_ID_CPU_UPDATE = 3;
17
+ export const WS_ID_MEMORY_UPDATE = 4;
16
18
  export class Frontend {
17
19
  matterbridge;
18
20
  log;
@@ -22,7 +24,8 @@ export class Frontend {
22
24
  httpServer;
23
25
  httpsServer;
24
26
  webSocketServer;
25
- prevCpus = os.cpus();
27
+ prevCpus = deepCopy(os.cpus());
28
+ lastCpuUsage = 0;
26
29
  memoryData = [];
27
30
  memoryInterval;
28
31
  memoryTimeout;
@@ -792,28 +795,61 @@ export class Frontend {
792
795
  }
793
796
  }
794
797
  formatMemoryUsage = (bytes) => {
795
- const kb = bytes / 1024;
796
- const mb = kb / 1024;
797
- return mb >= 1 ? `${mb.toFixed(2)} MB` : `${kb.toFixed(2)} KB`;
798
+ if (bytes >= 1024 ** 3) {
799
+ return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
800
+ }
801
+ else if (bytes >= 1024 ** 2) {
802
+ return `${(bytes / 1024 ** 2).toFixed(2)} MB`;
803
+ }
804
+ else {
805
+ return `${(bytes / 1024).toFixed(2)} KB`;
806
+ }
807
+ };
808
+ formatOsUpTime = () => {
809
+ const seconds = os.uptime();
810
+ if (seconds >= 86400) {
811
+ const days = Math.floor(seconds / 86400);
812
+ return `${days} day${days !== 1 ? 's' : ''}`;
813
+ }
814
+ if (seconds >= 3600) {
815
+ const hours = Math.floor(seconds / 3600);
816
+ return `${hours} hour${hours !== 1 ? 's' : ''}`;
817
+ }
818
+ if (seconds >= 60) {
819
+ const minutes = Math.floor(seconds / 60);
820
+ return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
821
+ }
822
+ return `${seconds} second${seconds !== 1 ? 's' : ''}`;
823
+ };
824
+ getCpuUsage = () => {
825
+ const currCpus = os.cpus();
826
+ if (currCpus.length !== this.prevCpus.length) {
827
+ this.prevCpus = deepCopy(currCpus);
828
+ this.log.debug(`***Cpu usage reset. Current cpus: ${currCpus.length}. Previous cpus: ${this.prevCpus.length}.`);
829
+ return this.lastCpuUsage.toFixed(2);
830
+ }
831
+ let totalIdle = 0, totalTick = 0;
832
+ this.prevCpus.forEach((prevCpu, i) => {
833
+ const currCpu = currCpus[i];
834
+ const idleDiff = currCpu.times.idle - prevCpu.times.idle;
835
+ const totalDiff = Object.keys(currCpu.times).reduce((acc, key) => acc + (currCpu.times[key] - prevCpu.times[key]), 0);
836
+ totalIdle += idleDiff;
837
+ totalTick += totalDiff;
838
+ });
839
+ const cpuUsage = 100 - (totalIdle / totalTick) * 100;
840
+ if (totalTick === 0 || isNaN(cpuUsage) || !isFinite(cpuUsage) || cpuUsage <= 0) {
841
+ this.log.debug('***Invalid cpu usage. Returning the previous one.');
842
+ return this.lastCpuUsage.toFixed(2);
843
+ }
844
+ this.prevCpus = deepCopy(currCpus);
845
+ this.lastCpuUsage = cpuUsage;
846
+ return cpuUsage.toFixed(2);
798
847
  };
799
848
  startCpuMemoryDump() {
800
849
  clearInterval(this.memoryInterval);
801
850
  clearTimeout(this.memoryTimeout);
802
851
  const interval = () => {
803
- const currCpus = os.cpus();
804
- if (currCpus.length !== this.prevCpus.length) {
805
- this.prevCpus = currCpus;
806
- }
807
- let totalIdle = 0, totalTick = 0;
808
- this.prevCpus.forEach((prevCpu, i) => {
809
- const currCpu = currCpus[i];
810
- const idleDiff = currCpu.times.idle - prevCpu.times.idle;
811
- const totalDiff = Object.keys(currCpu.times).reduce((acc, key) => acc + (currCpu.times[key] - prevCpu.times[key]), 0);
812
- totalIdle += idleDiff;
813
- totalTick += totalDiff;
814
- });
815
- const cpuUsage = (100 - (totalIdle / totalTick) * 100).toFixed(2);
816
- this.prevCpus = currCpus;
852
+ const cpuUsage = this.getCpuUsage();
817
853
  const memoryUsageRaw = process.memoryUsage();
818
854
  this.memoryData.push({ ...memoryUsageRaw, cpu: cpuUsage });
819
855
  const memoryUsage = {
@@ -824,6 +860,15 @@ export class Frontend {
824
860
  arrayBuffers: this.formatMemoryUsage(memoryUsageRaw.arrayBuffers),
825
861
  };
826
862
  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}`);
863
+ this.matterbridge.systemInformation.freeMemory = this.formatMemoryUsage(os.freemem());
864
+ this.matterbridge.systemInformation.totalMemory = this.formatMemoryUsage(os.totalmem());
865
+ this.matterbridge.systemInformation.systemUptime = this.formatOsUpTime();
866
+ this.matterbridge.systemInformation.cpuUsed = cpuUsage;
867
+ this.matterbridge.systemInformation.rss = this.formatMemoryUsage(process.memoryUsage().rss);
868
+ this.matterbridge.systemInformation.heapTotal = this.formatMemoryUsage(process.memoryUsage().heapTotal);
869
+ this.matterbridge.systemInformation.heapUsed = this.formatMemoryUsage(process.memoryUsage().heapUsed);
870
+ this.wssSendCpuUpdate(this.matterbridge.systemInformation.cpuUsed);
871
+ 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);
827
872
  };
828
873
  interval();
829
874
  this.memoryInterval = setInterval(interval, getIntParameter('memoryinterval') ?? 1000);
@@ -852,8 +897,13 @@ export class Frontend {
852
897
  this.prevCpus = [];
853
898
  }
854
899
  async getApiSettings() {
900
+ this.matterbridge.systemInformation.totalMemory = this.formatMemoryUsage(os.totalmem());
901
+ this.matterbridge.systemInformation.freeMemory = this.formatMemoryUsage(os.freemem());
902
+ this.matterbridge.systemInformation.systemUptime = this.formatOsUpTime();
903
+ this.matterbridge.systemInformation.cpuUsed = this.getCpuUsage();
855
904
  this.matterbridge.systemInformation.rss = this.formatMemoryUsage(process.memoryUsage().rss);
856
- this.matterbridge.systemInformation.heap = this.formatMemoryUsage(process.memoryUsage().heapUsed) + ' / ' + this.formatMemoryUsage(process.memoryUsage().heapTotal);
905
+ this.matterbridge.systemInformation.heapTotal = this.formatMemoryUsage(process.memoryUsage().heapTotal);
906
+ this.matterbridge.systemInformation.heapUsed = this.formatMemoryUsage(process.memoryUsage().heapUsed);
857
907
  this.matterbridge.matterbridgeInformation.bridgeMode = this.matterbridge.bridgeMode;
858
908
  this.matterbridge.matterbridgeInformation.restartMode = this.matterbridge.restartMode;
859
909
  this.matterbridge.matterbridgeInformation.loggerLevel = this.matterbridge.log.logLevel;
@@ -1316,4 +1366,22 @@ export class Frontend {
1316
1366
  }
1317
1367
  });
1318
1368
  }
1369
+ wssSendCpuUpdate(cpuUsed) {
1370
+ this.log.debug('Sending a memory update message to all connected clients');
1371
+ this.matterbridge.matterbridgeInformation.restartRequired = true;
1372
+ this.webSocketServer?.clients.forEach((client) => {
1373
+ if (client.readyState === WebSocket.OPEN) {
1374
+ client.send(JSON.stringify({ id: WS_ID_CPU_UPDATE, src: 'Matterbridge', dst: 'Frontend', method: 'cpu_update', params: { cpuUsed } }));
1375
+ }
1376
+ });
1377
+ }
1378
+ wssSendMemoryUpdate(freeMemory, totalMemory, systemUptime, rss, heapUsed, heapTotal) {
1379
+ this.log.debug('Sending a cpu update message to all connected clients');
1380
+ this.matterbridge.matterbridgeInformation.restartRequired = true;
1381
+ this.webSocketServer?.clients.forEach((client) => {
1382
+ if (client.readyState === WebSocket.OPEN) {
1383
+ client.send(JSON.stringify({ id: WS_ID_MEMORY_UPDATE, src: 'Matterbridge', dst: 'Frontend', method: 'memory_update', params: { freeMemory, totalMemory, systemUptime, rss, heapUsed, heapTotal } }));
1384
+ }
1385
+ });
1386
+ }
1319
1387
  }
@@ -35,8 +35,10 @@ export class Matterbridge extends EventEmitter {
35
35
  totalMemory: '',
36
36
  freeMemory: '',
37
37
  systemUptime: '',
38
+ cpuUsed: '',
38
39
  rss: '',
39
- heap: '',
40
+ heapTotal: '',
41
+ heapUsed: '',
40
42
  };
41
43
  matterbridgeInformation = {
42
44
  homeDirectory: '',
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.cf25d33e.css",
4
- "main.js": "./static/js/main.26dbf9b9.js",
4
+ "main.js": "./static/js/main.1c3bc5a8.js",
5
5
  "static/js/453.abd36b29.chunk.js": "./static/js/453.abd36b29.chunk.js",
6
6
  "static/media/roboto-latin-700-normal.woff2": "./static/media/roboto-latin-700-normal.4535474e1cf8598695ad.woff2",
7
7
  "static/media/roboto-latin-500-normal.woff2": "./static/media/roboto-latin-500-normal.7077203b1982951ecf76.woff2",
@@ -61,11 +61,11 @@
61
61
  "static/media/roboto-greek-ext-400-normal.woff": "./static/media/roboto-greek-ext-400-normal.16eb83b4a3b1ea994243.woff",
62
62
  "index.html": "./index.html",
63
63
  "main.cf25d33e.css.map": "./static/css/main.cf25d33e.css.map",
64
- "main.26dbf9b9.js.map": "./static/js/main.26dbf9b9.js.map",
64
+ "main.1c3bc5a8.js.map": "./static/js/main.1c3bc5a8.js.map",
65
65
  "453.abd36b29.chunk.js.map": "./static/js/453.abd36b29.chunk.js.map"
66
66
  },
67
67
  "entrypoints": [
68
68
  "static/css/main.cf25d33e.css",
69
- "static/js/main.26dbf9b9.js"
69
+ "static/js/main.1c3bc5a8.js"
70
70
  ]
71
71
  }
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.26dbf9b9.js"></script><link href="./static/css/main.cf25d33e.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.1c3bc5a8.js"></script><link href="./static/css/main.cf25d33e.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>