@matterbridge/core 3.10.14-dev-20261010-607ee18 → 3.10.14-dev-20261013-e87a0c8

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.
Files changed (77) hide show
  1. package/dist/backendExpress.js +14 -9
  2. package/dist/backendWsServer.d.ts +1 -5
  3. package/dist/backendWsServer.js +4 -35
  4. package/dist/behaviors/bindingServer.d.ts +1 -1
  5. package/dist/behaviors/booleanStateConfigurationServer.js +2 -1
  6. package/dist/behaviors/cameraAvSettingsUserLevelManagementServer.d.ts +1 -1
  7. package/dist/behaviors/cameraAvSettingsUserLevelManagementServer.js +2 -1
  8. package/dist/behaviors/cameraAvStreamManagementServer.d.ts +1 -2
  9. package/dist/behaviors/cameraAvStreamManagementServer.js +2 -1
  10. package/dist/behaviors/chimeServer.js +2 -1
  11. package/dist/behaviors/deviceEnergyManagementServer.js +2 -1
  12. package/dist/behaviors/fanControlServer.js +2 -1
  13. package/dist/behaviors/pumpConfigurationAndControlServer.js +2 -1
  14. package/dist/behaviors/smokeCoAlarmServer.js +2 -1
  15. package/dist/behaviors/temperatureAlarmServer.js +2 -1
  16. package/dist/behaviors/thermostatServer.js +2 -1
  17. package/dist/behaviors/valveConfigurationAndControlServer.js +2 -1
  18. package/dist/behaviors/webRtcTransportProviderServer.js +3 -1
  19. package/dist/chipTests.js +3 -2
  20. package/dist/cli.js +36 -4
  21. package/dist/cliEmitter.d.ts +0 -3
  22. package/dist/deviceManager.d.ts +0 -1
  23. package/dist/deviceManager.js +15 -47
  24. package/dist/devices/airConditioner.d.ts +1 -1
  25. package/dist/devices/audioDoorbell.d.ts +1 -1
  26. package/dist/devices/audioDoorbell.js +1 -1
  27. package/dist/devices/batteryStorage.d.ts +1 -1
  28. package/dist/devices/camera.d.ts +1 -2
  29. package/dist/devices/camera.js +1 -1
  30. package/dist/devices/closure.d.ts +2 -2
  31. package/dist/devices/closure.js +1 -1
  32. package/dist/devices/closurePanel.js +1 -1
  33. package/dist/devices/cooktop.d.ts +2 -1
  34. package/dist/devices/dishwasher.d.ts +2 -2
  35. package/dist/devices/dishwasher.js +2 -1
  36. package/dist/devices/electricalUtilityMeter.d.ts +1 -1
  37. package/dist/devices/electricalUtilityMeter.js +1 -1
  38. package/dist/devices/evse.d.ts +1 -1
  39. package/dist/devices/evse.js +2 -1
  40. package/dist/devices/extractorHood.d.ts +1 -1
  41. package/dist/devices/floodlightCamera.d.ts +1 -1
  42. package/dist/devices/floodlightCamera.js +1 -1
  43. package/dist/devices/heatPump.d.ts +1 -1
  44. package/dist/devices/intercom.d.ts +1 -1
  45. package/dist/devices/intercom.js +1 -1
  46. package/dist/devices/irrigationSystem.d.ts +1 -1
  47. package/dist/devices/laundryDryer.d.ts +2 -2
  48. package/dist/devices/laundryDryer.js +2 -1
  49. package/dist/devices/laundryWasher.d.ts +2 -2
  50. package/dist/devices/laundryWasher.js +2 -1
  51. package/dist/devices/microwaveOven.d.ts +2 -2
  52. package/dist/devices/microwaveOven.js +2 -1
  53. package/dist/devices/oven.d.ts +2 -1
  54. package/dist/devices/refrigerator.d.ts +2 -1
  55. package/dist/devices/roboticVacuumCleaner.d.ts +1 -1
  56. package/dist/devices/snapshotCamera.d.ts +1 -1
  57. package/dist/devices/snapshotCamera.js +1 -1
  58. package/dist/devices/solarPower.d.ts +1 -1
  59. package/dist/devices/temperatureControl.js +2 -1
  60. package/dist/devices/videoDoorbell.d.ts +1 -1
  61. package/dist/devices/videoDoorbell.js +1 -1
  62. package/dist/devices/waterHeater.d.ts +1 -1
  63. package/dist/frontend.d.ts +1 -8
  64. package/dist/frontend.js +23 -82
  65. package/dist/matterNode.d.ts +4 -2
  66. package/dist/matterNode.js +116 -67
  67. package/dist/matterNodeHelpers.d.ts +3 -1
  68. package/dist/matterNodeHelpers.js +48 -0
  69. package/dist/matterbridge.js +14 -24
  70. package/dist/matterbridgeDeviceTypes.d.ts +1 -1
  71. package/dist/matterbridgeEndpoint.js +43 -29
  72. package/dist/matterbridgePlatform.js +39 -3
  73. package/dist/pluginManager.js +10 -1
  74. package/dist/runners/threadBackend.js +20 -6
  75. package/dist/runners/threadRootNode.js +32 -12
  76. package/dist/runners/threadTracker.js +23 -6
  77. package/package.json +5 -5
package/dist/frontend.js CHANGED
@@ -7,7 +7,7 @@ import { CommissioningOptions } from '@matter/types/commissioning';
7
7
  import { FabricIndex } from '@matter/types/datatype';
8
8
  import { BroadcastServer } from '@matterbridge/thread/server';
9
9
  import { MATTER_LOGGER_FILE, MATTER_STORAGE_DIR, MATTERBRIDGE_DIAGNOSTIC_FILE, MATTERBRIDGE_HISTORY_FILE, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg, } from '@matterbridge/types';
10
- import { isBun, memoryFootprint } from '@matterbridge/utils/bun';
10
+ import { constrainedMemory, isBun, memoryFootprint } from '@matterbridge/utils/bun';
11
11
  import { getParameter, hasAnyParameter, hasParameter } from '@matterbridge/utils/cli';
12
12
  import { writeDiagnostic } from '@matterbridge/utils/diagnostic';
13
13
  import { getErrorMessage, inspectError, logError } from '@matterbridge/utils/error';
@@ -16,11 +16,15 @@ import { logModuleLoaded } from '@matterbridge/utils/loader';
16
16
  import { isValidArray, isValidBoolean, isValidNumber, isValidObject, isValidString } from '@matterbridge/utils/validate';
17
17
  import { fireAndForget, wait, withTimeout } from '@matterbridge/utils/wait';
18
18
  import { AnsiLogger, bgHex, CYAN, db, debugStringify, er, GREEN, nf, nt, rs, stringify, UNDERLINE, UNDERLINEOFF, wr, YELLOW } from 'node-ansi-logger';
19
- import { cliEmitter } from './cliEmitter.js';
20
19
  import { generateHistoryPage } from './cliHistory.js';
21
20
  import { capitalizeFirstLetter } from './matterbridgeEndpointHelpers.js';
22
21
  import { deleteAdvertisingNode, getBatteryLevel, getClusterTextFromDevice, getPowerSource, getReachability, getServerNodeData, setAdvertisingNode } from './matterNodeHelpers.js';
23
22
  logModuleLoaded('Frontend');
23
+ function sendDownloadError(res, error, message) {
24
+ if (error.code === 'ECONNABORTED' || res.headersSent)
25
+ return;
26
+ res.status(500).send(message);
27
+ }
24
28
  export class Frontend extends EventEmitter {
25
29
  matterbridge;
26
30
  log;
@@ -40,9 +44,6 @@ export class Frontend extends EventEmitter {
40
44
  verbose = hasParameter('verbose');
41
45
  diagnostic = hasParameter('diagnostic');
42
46
  readOnly = hasParameter('readonly') || hasParameter('shelly');
43
- shellyBoard = hasParameter('shelly');
44
- shellySysUpdate = false;
45
- shellyMainUpdate = false;
46
47
  restartRequired = false;
47
48
  fixedRestartRequired = false;
48
49
  updateRequired = false;
@@ -459,16 +460,6 @@ export class Frontend extends EventEmitter {
459
460
  return;
460
461
  });
461
462
  }
462
- cliEmitter.removeAllListeners();
463
- cliEmitter.on('uptime', (systemUptime, processUptime) => {
464
- this.wssSendUptimeUpdate(systemUptime, processUptime);
465
- });
466
- cliEmitter.on('memory', (totalMememory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers) => {
467
- this.wssSendMemoryUpdate(totalMememory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers);
468
- });
469
- cliEmitter.on('cpu', (cpuUsage, processCpuUsage) => {
470
- this.wssSendCpuUpdate(cpuUsage, processCpuUsage);
471
- });
472
463
  this.expressApp.post('/api/login', express.json(), (req, res) => {
473
464
  const { password } = req.body;
474
465
  this.log.debug(`The frontend sent /api/login with password ${password ? '[redacted]' : '(empty)'}`);
@@ -575,7 +566,7 @@ export class Frontend extends EventEmitter {
575
566
  res.download(path.join(os.tmpdir(), MATTERBRIDGE_LOGGER_FILE), 'matterbridge.log', (error) => {
576
567
  if (error) {
577
568
  logError(this.log, `Error downloading log file ${MATTERBRIDGE_LOGGER_FILE}`, error);
578
- res.status(500).send('Error downloading the matterbridge log file');
569
+ sendDownloadError(res, error, 'Error downloading the matterbridge log file');
579
570
  }
580
571
  else {
581
572
  this.log.debug(`Matterbridge log file ${MATTERBRIDGE_LOGGER_FILE} downloaded successfully`);
@@ -615,7 +606,7 @@ export class Frontend extends EventEmitter {
615
606
  res.download(path.join(os.tmpdir(), MATTER_LOGGER_FILE), 'matter.log', (error) => {
616
607
  if (error) {
617
608
  logError(this.log, `Error downloading log file ${MATTER_LOGGER_FILE}`, error);
618
- res.status(500).send('Error downloading the matter log file');
609
+ sendDownloadError(res, error, 'Error downloading the matter log file');
619
610
  }
620
611
  else {
621
612
  this.log.debug(`Matter log file ${MATTER_LOGGER_FILE} downloaded successfully`);
@@ -656,7 +647,7 @@ export class Frontend extends EventEmitter {
656
647
  res.download(path.join(os.tmpdir(), MATTERBRIDGE_DIAGNOSTIC_FILE), MATTERBRIDGE_DIAGNOSTIC_FILE, (error) => {
657
648
  if (error) {
658
649
  this.log.error(`Error downloading file ${MATTERBRIDGE_DIAGNOSTIC_FILE}: ${error instanceof Error ? error.message : error}`);
659
- res.status(500).send('Error downloading the diagnostic log file');
650
+ sendDownloadError(res, error, 'Error downloading the diagnostic log file');
660
651
  }
661
652
  else {
662
653
  this.log.debug(`Diagnostic log file ${MATTERBRIDGE_DIAGNOSTIC_FILE} downloaded successfully`);
@@ -691,7 +682,7 @@ export class Frontend extends EventEmitter {
691
682
  res.download(path.join(os.tmpdir(), MATTERBRIDGE_HISTORY_FILE), MATTERBRIDGE_HISTORY_FILE, (error) => {
692
683
  if (error) {
693
684
  logError(this.log, `Error in /api/downloadhistory downloading history file ${MATTERBRIDGE_HISTORY_FILE}`, error);
694
- res.status(500).send('Error downloading history file');
685
+ sendDownloadError(res, error, 'Error downloading history file');
695
686
  }
696
687
  else {
697
688
  this.log.debug(`History file ${MATTERBRIDGE_HISTORY_FILE} downloaded successfully`);
@@ -711,7 +702,7 @@ export class Frontend extends EventEmitter {
711
702
  this.wssSendCloseSnackbarMessage('Creating matterbridge backup...');
712
703
  if (error) {
713
704
  logError(this.log, `Error downloading file matterbridge.backup.zip`, error);
714
- res.status(500).send(`Error downloading file matterbridge.backup.zip: ${getErrorMessage(error)}`);
705
+ sendDownloadError(res, error, `Error downloading file matterbridge.backup.zip: ${getErrorMessage(error)}`);
715
706
  }
716
707
  else {
717
708
  this.log.debug('Backup matterbridge.backup.zip downloaded successfully');
@@ -726,7 +717,7 @@ export class Frontend extends EventEmitter {
726
717
  this.wssSendCloseSnackbarMessage('Creating matterbridge storage backup...');
727
718
  if (error) {
728
719
  this.log.error(`Error downloading file matterbridge.${NODE_STORAGE_DIR}.zip: ${error instanceof Error ? error.message : error}`);
729
- res.status(500).send('Error downloading the matterbridge storage file');
720
+ sendDownloadError(res, error, 'Error downloading the matterbridge storage file');
730
721
  }
731
722
  else {
732
723
  this.log.debug(`Matterbridge storage matterbridge.${NODE_STORAGE_DIR}.zip downloaded successfully`);
@@ -741,7 +732,7 @@ export class Frontend extends EventEmitter {
741
732
  this.wssSendCloseSnackbarMessage('Creating matter storage backup...');
742
733
  if (error) {
743
734
  logError(this.log, `Error downloading the matter storage matterbridge.${MATTER_STORAGE_DIR}.zip`, error);
744
- res.status(500).send('Error downloading the matter storage zip file');
735
+ sendDownloadError(res, error, 'Error downloading the matter storage zip file');
745
736
  }
746
737
  else {
747
738
  this.log.debug(`Matter storage matterbridge.${MATTER_STORAGE_DIR}.zip downloaded successfully`);
@@ -756,7 +747,7 @@ export class Frontend extends EventEmitter {
756
747
  this.wssSendCloseSnackbarMessage('Creating plugin backup...');
757
748
  if (error) {
758
749
  logError(this.log, `Error downloading file matterbridge.pluginstorage.zip`, error);
759
- res.status(500).send('Error downloading the matterbridge plugin storage file');
750
+ sendDownloadError(res, error, 'Error downloading the matterbridge plugin storage file');
760
751
  }
761
752
  else {
762
753
  this.log.debug('Plugin storage matterbridge.pluginstorage.zip downloaded successfully');
@@ -771,7 +762,7 @@ export class Frontend extends EventEmitter {
771
762
  this.wssSendCloseSnackbarMessage('Creating config backup...');
772
763
  if (error) {
773
764
  logError(this.log, `Error downloading file matterbridge.pluginconfig.zip`, error);
774
- res.status(500).send('Error downloading the matterbridge plugin config file');
765
+ sendDownloadError(res, error, 'Error downloading the matterbridge plugin config file');
775
766
  }
776
767
  else {
777
768
  this.log.debug('Plugin config matterbridge.pluginconfig.zip downloaded successfully');
@@ -927,6 +918,7 @@ export class Frontend extends EventEmitter {
927
918
  }
928
919
  getApiSettings() {
929
920
  this.matterbridge.systemInformation.totalMemory = formatBytes(os.totalmem());
921
+ this.matterbridge.systemInformation.constrainedMemory = formatBytes(constrainedMemory());
930
922
  this.matterbridge.systemInformation.freeMemory = formatBytes(os.freemem());
931
923
  this.matterbridge.systemInformation.systemUptime = formatUptime(os.uptime());
932
924
  this.matterbridge.systemInformation.processUptime = formatUptime(Math.floor(process.uptime()));
@@ -966,9 +958,6 @@ export class Frontend extends EventEmitter {
966
958
  matterDiscriminator: this.matterbridge.initialDiscriminator,
967
959
  matterPasscode: this.matterbridge.initialPasscode,
968
960
  readOnly: this.readOnly,
969
- shellyBoard: this.shellyBoard,
970
- shellySysUpdate: this.shellySysUpdate,
971
- shellyMainUpdate: this.shellyMainUpdate,
972
961
  restartRequired: this.restartRequired,
973
962
  fixedRestartRequired: this.fixedRestartRequired,
974
963
  updateRequired: this.updateRequired,
@@ -1028,11 +1017,12 @@ export class Frontend extends EventEmitter {
1028
1017
  if (!device.plugin || !device.deviceType || !device.name || !device.deviceName || !device.serialNumber || !device.uniqueId || !device.lifecycle.isReady)
1029
1018
  continue;
1030
1019
  devices.push({
1031
- pluginName: device.plugin,
1020
+ plugin: device.plugin,
1032
1021
  type: device.name + ' (0x' + device.deviceType.toString(16).padStart(4, '0') + ')',
1033
- endpoint: device.number,
1034
- name: device.deviceName,
1035
- serial: device.serialNumber,
1022
+ number: device.number,
1023
+ id: device.id,
1024
+ deviceName: device.deviceName,
1025
+ serialNumber: device.serialNumber,
1036
1026
  productUrl: device.productUrl,
1037
1027
  configUrl: device.configUrl,
1038
1028
  uniqueId: device.uniqueId,
@@ -1371,20 +1361,6 @@ export class Frontend extends EventEmitter {
1371
1361
  }, 5_000).unref();
1372
1362
  sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
1373
1363
  }
1374
- else if (data.method === '/api/shellysysupdate') {
1375
- }
1376
- else if (data.method === '/api/shellymainupdate') {
1377
- }
1378
- else if (data.method === '/api/shellycreatesystemlog') {
1379
- }
1380
- else if (data.method === '/api/shellynetconfig') {
1381
- }
1382
- else if (data.method === '/api/softreset') {
1383
- }
1384
- else if (data.method === '/api/hardreset') {
1385
- }
1386
- else if (data.method === '/api/reboot') {
1387
- }
1388
1364
  else if (data.method === '/api/restart') {
1389
1365
  this.wssSendSnackbarMessage(`Restarting matterbridge...`, 0);
1390
1366
  await this.matterbridge.restartProcess();
@@ -1560,7 +1536,7 @@ export class Frontend extends EventEmitter {
1560
1536
  return;
1561
1537
  }
1562
1538
  const start = performance.now();
1563
- const selectDevices = !plugin.platform ? [] : plugin.platform.getSelectDevices().toSorted((keyA, keyB) => keyA.name.localeCompare(keyB.name));
1539
+ const selectDevices = !plugin.platform ? [] : plugin.platform.getSelectDevices().toSorted((keyA, keyB) => keyA.deviceName.localeCompare(keyB.deviceName));
1564
1540
  if (this.diagnostic)
1565
1541
  writeDiagnostic(`Frontend:${data.sender}`, `getSelectDevices() took ${(performance.now() - start).toFixed(2)} ms`);
1566
1542
  sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true, response: selectDevices });
@@ -2014,41 +1990,6 @@ export class Frontend extends EventEmitter {
2014
1990
  this.log.debug('Sending a matterbridge status update message to all connected clients');
2015
1991
  this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'matterbridge_status_update', success: true, response: { status } });
2016
1992
  }
2017
- wssSendCpuUpdate(cpuUsage, processCpuUsage) {
2018
- if (!this.listening || this.webSocketServer?.clients.size === 0)
2019
- return;
2020
- if (hasParameter('debug'))
2021
- this.log.debug('Sending a cpu update message to all connected clients');
2022
- this.wssBroadcastMessage({
2023
- id: 0,
2024
- src: 'Matterbridge',
2025
- dst: 'Frontend',
2026
- method: 'cpu_update',
2027
- success: true,
2028
- response: { cpuUsage: Math.round(cpuUsage * 100) / 100, processCpuUsage: Math.round(processCpuUsage * 100) / 100 },
2029
- });
2030
- }
2031
- wssSendMemoryUpdate(totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers) {
2032
- if (!this.listening || this.webSocketServer?.clients.size === 0)
2033
- return;
2034
- if (hasParameter('debug'))
2035
- this.log.debug('Sending a memory update message to all connected clients');
2036
- this.wssBroadcastMessage({
2037
- id: 0,
2038
- src: 'Matterbridge',
2039
- dst: 'Frontend',
2040
- method: 'memory_update',
2041
- success: true,
2042
- response: { totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers },
2043
- });
2044
- }
2045
- wssSendUptimeUpdate(systemUptime, processUptime) {
2046
- if (!this.listening || this.webSocketServer?.clients.size === 0)
2047
- return;
2048
- if (hasParameter('debug'))
2049
- this.log.debug('Sending a uptime update message to all connected clients');
2050
- this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'uptime_update', success: true, response: { systemUptime, processUptime } });
2051
- }
2052
1993
  wssSendSnackbarMessage(message, timeout = 5, severity = 'info') {
2053
1994
  if (!this.listening || this.webSocketServer?.clients.size === 0)
2054
1995
  return;
@@ -2078,7 +2019,7 @@ export class Frontend extends EventEmitter {
2078
2019
  if (!this.listening || this.webSocketServer?.clients.size === 0)
2079
2020
  return;
2080
2021
  const stringifiedMsg = JSON.stringify(msg);
2081
- if (!['log', 'cpu_update', 'memory_update', 'uptime_update'].includes(msg.method))
2022
+ if (!['log', 'system_update'].includes(msg.method))
2082
2023
  this.log.debug(`Sending a broadcast message: ${debugStringify(msg)}`);
2083
2024
  this.webSocketServer?.clients.forEach((client) => {
2084
2025
  if (client.readyState === client.OPEN) {
@@ -4,8 +4,8 @@ import { type Diagnostic, type StorageContext, type StorageManager, StorageServi
4
4
  import { Endpoint, ServerNode } from '@matter/node';
5
5
  import { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
6
6
  import { type DeviceCertification, MdnsService } from '@matter/protocol';
7
- import { DeviceTypeId, VendorId } from '@matter/types';
8
- import type { PluginName, SharedMatterbridge, WorkerMessage } from '@matterbridge/types';
7
+ import { DeviceTypeId, VendorId } from '@matter/types/datatype';
8
+ import type { BridgeStatus, PluginName, PluginStatusUpdate, SharedMatterbridge, WorkerMessage } from '@matterbridge/types';
9
9
  import type { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
10
10
  import { type Plugin, PluginManager } from './pluginManager.js';
11
11
  interface MatterEvents {
@@ -73,6 +73,8 @@ export declare class MatterNode extends EventEmitter<MatterEvents> {
73
73
  subscribeAttributeChanged(plugin: Plugin, device: MatterbridgeEndpoint): Promise<void>;
74
74
  setServerReachability(reachable: boolean): Promise<void>;
75
75
  setAggregatorReachability(aggregatorNode: Endpoint<AggregatorEndpoint>, reachable: boolean): Promise<void>;
76
+ pluginStatusUpdate(pluginName: string, status: PluginStatusUpdate): void;
77
+ matterbridgeStatusUpdate(status: BridgeStatus): void;
76
78
  yieldToNode(timeout?: number): Promise<void>;
77
79
  }
78
80
  export {};