From d0edc1daa9eebacc03dfa359df7482f8c28db22e Mon Sep 17 00:00:00 2001 From: Luligu Date: Thu, 13 Feb 2025 19:30:35 +0100 Subject: [PATCH] Dev 2.1.6-dev.3 --- CHANGELOG.md | 3 +- package-lock.json | 84 ++++++++++++++++++++--------------------- package.json | 4 +- src/cli.ts | 90 +++++++++++++++++++++++++++++++++++++++++++- src/frontend.ts | 16 -------- src/matter/export.ts | 3 +- 6 files changed, 135 insertions(+), 65 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24b5aaa5..3fa613f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ matterbridge-zigbee2mqtt v. 2.4.4 matterbridge-somfy-tahoma v. 1.2.3 matterbridge-hass v. 0.0.8 -## [2.1.6] - 2025-02-12 +## [2.1.6] - 2025-02-13 ### Added @@ -45,6 +45,7 @@ matterbridge-hass v. 0.0.8 ### Changed - [package]: Update matter.js to 0.12.4-alpha.0-20250212-b2729c9eb +- [package]: Update matter.js to 0.12.4-alpha.0-20250213-1187f81eb Buy me a coffee diff --git a/package-lock.json b/package-lock.json index 7b3db1c3..314905b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "2.1.6-dev.3", "license": "Apache-2.0", "dependencies": { - "@matter/main": "^0.12.4-alpha.0-20250212-b2729c9eb", + "@matter/main": "^0.12.4-alpha.0-20250213-1187f81eb", "archiver": "7.0.1", "express": "4.21.2", "glob": "11.0.1", @@ -1333,65 +1333,65 @@ } }, "node_modules/@matter/general": { - "version": "0.12.4-alpha.0-20250212-b2729c9eb", - "resolved": "https://registry.npmjs.org/@matter/general/-/general-0.12.4-alpha.0-20250212-b2729c9eb.tgz", - "integrity": "sha512-6HCn8NBYrMjpr9h65z5u2gIjkrR8ilE/errqAI+GZkq21HJZFOGqG7G+hO0gzcrIj617sAEbQXJKfD2mVe2nCg==", + "version": "0.12.4-alpha.0-20250213-1187f81eb", + "resolved": "https://registry.npmjs.org/@matter/general/-/general-0.12.4-alpha.0-20250213-1187f81eb.tgz", + "integrity": "sha512-JFn9Eedx1ftPcifxIE2MnQs0P5BwEV5viiPsqGbzYuMtSNg98v7U6ikCt1LsptFtMJcxON30toY57Huf9Gdswg==", "license": "Apache-2.0", "dependencies": { "@noble/curves": "^1.8.1" } }, "node_modules/@matter/main": { - "version": "0.12.4-alpha.0-20250212-b2729c9eb", - "resolved": "https://registry.npmjs.org/@matter/main/-/main-0.12.4-alpha.0-20250212-b2729c9eb.tgz", - "integrity": "sha512-yCDXoeF9OonYOxjE1FwWZ+KxFLowf/G6To+R+GrHwrIqC1fhP0M1tL2f8rixMMnSUFzfXhSTssnGBiBDqQz1Iw==", + "version": "0.12.4-alpha.0-20250213-1187f81eb", + "resolved": "https://registry.npmjs.org/@matter/main/-/main-0.12.4-alpha.0-20250213-1187f81eb.tgz", + "integrity": "sha512-pQmJZY2wK7j7I27oIjZHaBt6kBnodMPjpeQ96afDniTI8XIWGY/bywUOemFK3AqTdWRO06bpQiuu/myKPvtKtw==", "license": "Apache-2.0", "dependencies": { - "@matter/general": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/model": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/node": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/protocol": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/types": "0.12.4-alpha.0-20250212-b2729c9eb", + "@matter/general": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/model": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/node": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/protocol": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/types": "0.12.4-alpha.0-20250213-1187f81eb", "@noble/curves": "^1.8.1" }, "optionalDependencies": { - "@matter/nodejs": "0.12.4-alpha.0-20250212-b2729c9eb" + "@matter/nodejs": "0.12.4-alpha.0-20250213-1187f81eb" } }, "node_modules/@matter/model": { - "version": "0.12.4-alpha.0-20250212-b2729c9eb", - "resolved": "https://registry.npmjs.org/@matter/model/-/model-0.12.4-alpha.0-20250212-b2729c9eb.tgz", - "integrity": "sha512-CzUUBnzgrEfGjuF2K6Q9xT/JotOE8bcu77G6FfxKBRlhfq/kRKM9IM771jQ3rz7YeVxPg7ONsuKPL4sw+4aEJA==", + "version": "0.12.4-alpha.0-20250213-1187f81eb", + "resolved": "https://registry.npmjs.org/@matter/model/-/model-0.12.4-alpha.0-20250213-1187f81eb.tgz", + "integrity": "sha512-qIZz6A3lgJW4HHFAZrjBdHCcIJnyyjUUPkROxJ18VAQB9I1siwoQKrbpbyFWsm1SEep4s/6P61+BCXZimEDTqw==", "license": "Apache-2.0", "dependencies": { - "@matter/general": "0.12.4-alpha.0-20250212-b2729c9eb", + "@matter/general": "0.12.4-alpha.0-20250213-1187f81eb", "@noble/curves": "^1.8.1" } }, "node_modules/@matter/node": { - "version": "0.12.4-alpha.0-20250212-b2729c9eb", - "resolved": "https://registry.npmjs.org/@matter/node/-/node-0.12.4-alpha.0-20250212-b2729c9eb.tgz", - "integrity": "sha512-X8Q3HRKRkBNkUlTbsx9VT2bNtOUoAb1eHvgKuGQ3H9rzBy6xeCsMsQRai3Of321y2dxoGx0S+2+u4Lv06hljQA==", + "version": "0.12.4-alpha.0-20250213-1187f81eb", + "resolved": "https://registry.npmjs.org/@matter/node/-/node-0.12.4-alpha.0-20250213-1187f81eb.tgz", + "integrity": "sha512-PoXcZc5zWwDXS6zHYrGAmBP4YVji6m2Ba9mukMaPqKCbY5UpjMqyv+dXa7U2Q+9QnljVhyvmUNOFWJ4bSe4+AA==", "license": "Apache-2.0", "dependencies": { - "@matter/general": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/model": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/protocol": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/types": "0.12.4-alpha.0-20250212-b2729c9eb", + "@matter/general": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/model": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/protocol": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/types": "0.12.4-alpha.0-20250213-1187f81eb", "@noble/curves": "^1.8.1" } }, "node_modules/@matter/nodejs": { - "version": "0.12.4-alpha.0-20250212-b2729c9eb", - "resolved": "https://registry.npmjs.org/@matter/nodejs/-/nodejs-0.12.4-alpha.0-20250212-b2729c9eb.tgz", - "integrity": "sha512-Muxi2dd8B2GWI52FeK8wmqcRT9PJjWJPsStPFE/ABGMOTkcAifMzb1cr76wswhNWZxDWthAYmgHfyZ+vEGf3Pw==", + "version": "0.12.4-alpha.0-20250213-1187f81eb", + "resolved": "https://registry.npmjs.org/@matter/nodejs/-/nodejs-0.12.4-alpha.0-20250213-1187f81eb.tgz", + "integrity": "sha512-O7Iu64UxGbv4XOMU2x7DubBhwUnO3tsCoQw40wcH7tWvWm5na7c9ZNEcn0ewtRKuSjEIWLFxKzEW7r5qy/1Vhg==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@matter/general": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/node": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/protocol": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/types": "0.12.4-alpha.0-20250212-b2729c9eb", + "@matter/general": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/node": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/protocol": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/types": "0.12.4-alpha.0-20250213-1187f81eb", "node-localstorage": "^3.0.5" }, "engines": { @@ -1399,25 +1399,25 @@ } }, "node_modules/@matter/protocol": { - "version": "0.12.4-alpha.0-20250212-b2729c9eb", - "resolved": "https://registry.npmjs.org/@matter/protocol/-/protocol-0.12.4-alpha.0-20250212-b2729c9eb.tgz", - "integrity": "sha512-Al2SMUsm2i3KywIA+kLsVWAlT0EJ/iQNQeLE4FIJcnaQNiik+EU3F+KyUzR3Ydw9gAHIgcsJ9Ikbx4sZxlsPbA==", + "version": "0.12.4-alpha.0-20250213-1187f81eb", + "resolved": "https://registry.npmjs.org/@matter/protocol/-/protocol-0.12.4-alpha.0-20250213-1187f81eb.tgz", + "integrity": "sha512-Gbn7Xj/SOScl6Nc20RJ0A9lYCSA9CX7tToYm0GpAQpYvAJswwr6jc3ML6V3JAcQsngBFYDp8wbirJegR97GkiA==", "license": "Apache-2.0", "dependencies": { - "@matter/general": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/model": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/types": "0.12.4-alpha.0-20250212-b2729c9eb", + "@matter/general": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/model": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/types": "0.12.4-alpha.0-20250213-1187f81eb", "@noble/curves": "^1.8.1" } }, "node_modules/@matter/types": { - "version": "0.12.4-alpha.0-20250212-b2729c9eb", - "resolved": "https://registry.npmjs.org/@matter/types/-/types-0.12.4-alpha.0-20250212-b2729c9eb.tgz", - "integrity": "sha512-EtvcNWd+zjWPp76Av5kSIajzvFXSZznL1cpWQ+rBDpg4M2jqpM2So0Fq+zP0yCJMTRkXlv3EyCqgWUeRFJyNwQ==", + "version": "0.12.4-alpha.0-20250213-1187f81eb", + "resolved": "https://registry.npmjs.org/@matter/types/-/types-0.12.4-alpha.0-20250213-1187f81eb.tgz", + "integrity": "sha512-Mu2MJ2XY+/cdLKNQIHoSjgQZlSYJ8pLJSbPsM26p5EjfGymvoVvEkaamGS1GUB1A270ow9lwadVIM7zXgN+lCg==", "license": "Apache-2.0", "dependencies": { - "@matter/general": "0.12.4-alpha.0-20250212-b2729c9eb", - "@matter/model": "0.12.4-alpha.0-20250212-b2729c9eb", + "@matter/general": "0.12.4-alpha.0-20250213-1187f81eb", + "@matter/model": "0.12.4-alpha.0-20250213-1187f81eb", "@noble/curves": "^1.8.1" } }, diff --git a/package.json b/package.json index c54ab039..943a7066 100644 --- a/package.json +++ b/package.json @@ -148,14 +148,14 @@ "install:jest": "npm install --save-dev jest ts-jest @types/jest eslint-plugin-jest && npm run test" }, "dependencies": { - "@matter/main": "^0.12.4-alpha.0-20250212-b2729c9eb", + "@matter/main": "^0.12.4-alpha.0-20250213-1187f81eb", "archiver": "7.0.1", "express": "4.21.2", "glob": "11.0.1", "https": "1.0.0", "node-ansi-logger": "3.0.0", "node-persist-manager": "1.0.8", - "ws": "8.18.0" + "ws": "8.18.0" }, "devDependencies": { "@eslint/js": "9.20.0", diff --git a/src/cli.ts b/src/cli.ts index 488aa65c..c1d3e3ac 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -26,13 +26,25 @@ import { Matterbridge } from './matterbridge.js'; import type { Session } from 'node:inspector'; +import type os from 'node:os'; let instance: Matterbridge | undefined; +let session: Session; +let memoryCheckInterval: NodeJS.Timeout; +let prevCpus: os.CpuInfo[]; +let lastCpuUsage = 0; + const cli = '\u001B[32m'; const er = '\u001B[38;5;9m'; const rs = '\u001B[40;0m'; +const db = '\u001B[38;5;245m'; +const CYAN = '\u001B[36m'; +const YELLOW = '\u001B[33m'; +const BRIGHT = '\u001B[1m'; async function main() { + if (process.argv.includes('-memorycheck')) await startMemoryCheck(); + if (process.argv.includes('-inspector')) await startInspector(); if (process.argv.includes('-debug')) console.log(cli + `CLI: ${process.argv.includes('-edge') ? 'MatterbridgeEdge' : 'Matterbridge'}.loadInstance() called` + rs); @@ -41,7 +53,77 @@ async function main() { if (process.argv.includes('-debug')) console.log(cli + `CLI: ${process.argv.includes('-edge') ? 'MatterbridgeEdge' : 'Matterbridge'}.loadInstance() exited` + rs); } -let session: Session; +async function startMemoryCheck() { + const os = await import('node:os'); + console.log(cli + `CLI: Memory check started` + rs); + prevCpus = os.cpus(); + + const formatMemoryUsage = (bytes: number): string => { + if (bytes >= 1024 ** 3) { + return `${(bytes / 1024 ** 3).toFixed(2)} GB`; + } else if (bytes >= 1024 ** 2) { + return `${(bytes / 1024 ** 2).toFixed(2)} MB`; + } else { + return `${(bytes / 1024).toFixed(2)} KB`; + } + }; + + const interval = () => { + // Get the cpu usage + const currCpus = os.cpus(); + let cpuUsageLog: string; + if (currCpus.length !== prevCpus.length) { + prevCpus = currCpus; // Reset the previous cpus + cpuUsageLog = lastCpuUsage.toFixed(2); + } + let totalIdle = 0, + totalTick = 0; + + prevCpus.forEach((prevCpu, i) => { + const currCpu = currCpus[i]; + const idleDiff = currCpu.times.idle - prevCpu.times.idle; + const totalDiff = (Object.keys(currCpu.times) as (keyof typeof currCpu.times)[]).reduce((acc, key) => acc + (currCpu.times[key] - prevCpu.times[key]), 0); + totalIdle += idleDiff; + totalTick += totalDiff; + }); + const cpuUsage = 100 - (totalIdle / totalTick) * 100; + if (totalTick === 0 || isNaN(cpuUsage) || !isFinite(cpuUsage) || cpuUsage <= 0) { + cpuUsageLog = lastCpuUsage.toFixed(2); + } + prevCpus = currCpus; + lastCpuUsage = cpuUsage; + cpuUsageLog = cpuUsage.toFixed(2); + + // Get the memory usage + const memoryUsageRaw = process.memoryUsage(); + const memoryUsage = { + rss: formatMemoryUsage(memoryUsageRaw.rss), + heapTotal: formatMemoryUsage(memoryUsageRaw.heapTotal), + heapUsed: formatMemoryUsage(memoryUsageRaw.heapUsed), + external: formatMemoryUsage(memoryUsageRaw.external), + arrayBuffers: formatMemoryUsage(memoryUsageRaw.arrayBuffers), + }; + 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}` + + rs, + ); + }; + interval(); + memoryCheckInterval = setInterval(interval, 1000); +} + +async function stopMemoryCheck() { + console.log(cli + `CLI: Stopping memory check in 5 minute` + rs); + instance = undefined; + setTimeout( + () => { + console.log(cli + `CLI: Memory check stopped` + rs); + clearInterval(memoryCheckInterval); + process.exit(0); + }, + 5 * 60 * 1000, + ); +} async function startInspector() { const { Session } = await import('node:inspector'); @@ -79,7 +161,11 @@ async function shutdown() { if (process.argv.includes('-inspector')) await stopInspector(); - process.exit(0); + if (process.argv.includes('-memorycheck')) { + await stopMemoryCheck(); + } else { + process.exit(0); + } } async function restart() { diff --git a/src/frontend.ts b/src/frontend.ts index a1118cdf..85b282b5 100644 --- a/src/frontend.ts +++ b/src/frontend.ts @@ -928,22 +928,6 @@ export class Frontend { } async stop() { - // Start the memory check. This will not allow the process to exit but will log the memory usage for 5 minutes. - if (hasParameter('memorycheck')) { - this.wssSendSnackbarMessage('Memory check started', getIntParameter('memorycheck') ?? 5 * 60 * 1000); - await new Promise((resolve) => { - this.log.debug(`***Memory check started for ${getIntParameter('memorycheck') ?? 5 * 60 * 1000} ms`); - setTimeout( - () => { - this.wssSendSnackbarMessage('Memory check stopped', 10); - this.log.debug(`***Memory check stopped after ${getIntParameter('memorycheck') ?? 5 * 60 * 1000} ms`); - resolve(); - }, - getIntParameter('memorycheck') ?? 5 * 60 * 1000, - ); - }); - } - // Close the http server if (this.httpServer) { this.httpServer.close(); diff --git a/src/matter/export.ts b/src/matter/export.ts index 6dc1aa75..3a8fc410 100644 --- a/src/matter/export.ts +++ b/src/matter/export.ts @@ -18,5 +18,4 @@ export { SwitchesTag, } from '@matter/main'; export { AttributeElement, ClusterElement, ClusterModel, CommandElement, EventElement, FieldElement } from '@matter/main/model'; -// export { logEndpoint, MdnsService, Val } from '@matter/main/protocol'; -export { logEndpoint, MdnsService } from '@matter/main/protocol'; +export { logEndpoint, MdnsService, Val } from '@matter/main/protocol';