@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
@@ -14,6 +14,11 @@ import { rateLimit } from 'express-rate-limit';
14
14
  import multer from 'multer';
15
15
  import { AnsiLogger, er, nf } from 'node-ansi-logger';
16
16
  logModuleLoaded('BackendExpress');
17
+ function sendDownloadError(res, error, message) {
18
+ if (error.code === 'ECONNABORTED' || res.headersSent)
19
+ return;
20
+ res.status(500).send(message);
21
+ }
17
22
  export class BackendExpress {
18
23
  debug;
19
24
  verbose;
@@ -190,7 +195,7 @@ export class BackendExpress {
190
195
  res.download(path.join(os.tmpdir(), MATTERBRIDGE_LOGGER_FILE), 'matterbridge.log', (error) => {
191
196
  if (error) {
192
197
  this.log.error(`Error downloading log file ${MATTERBRIDGE_LOGGER_FILE}: ${getErrorMessage(error)}`);
193
- res.status(500).send('Error downloading the matterbridge log file');
198
+ sendDownloadError(res, error, 'Error downloading the matterbridge log file');
194
199
  }
195
200
  else {
196
201
  this.log.debug(`Matterbridge log file ${MATTERBRIDGE_LOGGER_FILE} downloaded successfully`);
@@ -230,7 +235,7 @@ export class BackendExpress {
230
235
  res.download(path.join(os.tmpdir(), MATTER_LOGGER_FILE), 'matter.log', (error) => {
231
236
  if (error) {
232
237
  this.log.error(`Error downloading log file ${MATTER_LOGGER_FILE}: ${getErrorMessage(error)}`);
233
- res.status(500).send('Error downloading the matter log file');
238
+ sendDownloadError(res, error, 'Error downloading the matter log file');
234
239
  }
235
240
  else {
236
241
  this.log.debug(`Matter log file ${MATTER_LOGGER_FILE} downloaded successfully`);
@@ -271,7 +276,7 @@ export class BackendExpress {
271
276
  res.download(path.join(os.tmpdir(), MATTERBRIDGE_DIAGNOSTIC_FILE), MATTERBRIDGE_DIAGNOSTIC_FILE, (error) => {
272
277
  if (error) {
273
278
  this.log.error(`Error downloading file ${MATTERBRIDGE_DIAGNOSTIC_FILE}: ${getErrorMessage(error)}`);
274
- res.status(500).send('Error downloading the diagnostic log file');
279
+ sendDownloadError(res, error, 'Error downloading the diagnostic log file');
275
280
  }
276
281
  else {
277
282
  this.log.debug(`Diagnostic log file ${MATTERBRIDGE_DIAGNOSTIC_FILE} downloaded successfully`);
@@ -306,7 +311,7 @@ export class BackendExpress {
306
311
  res.download(path.join(os.tmpdir(), MATTERBRIDGE_HISTORY_FILE), MATTERBRIDGE_HISTORY_FILE, (error) => {
307
312
  if (error) {
308
313
  this.log.error(`Error in /api/downloadhistory downloading history file ${MATTERBRIDGE_HISTORY_FILE}: ${getErrorMessage(error)}`);
309
- res.status(500).send('Error downloading history file');
314
+ sendDownloadError(res, error, 'Error downloading history file');
310
315
  }
311
316
  else {
312
317
  this.log.debug(`History file ${MATTERBRIDGE_HISTORY_FILE} downloaded successfully`);
@@ -326,7 +331,7 @@ export class BackendExpress {
326
331
  this.backend.backendWsServer?.wssSendCloseSnackbarMessage('Creating matterbridge backup...');
327
332
  if (error) {
328
333
  this.log.error(`Error downloading file ${MATTERBRIDGE_BACKUP_FILE}: ${getErrorMessage(error)}`);
329
- res.status(500).send(`Error downloading the matterbridge backup file.`);
334
+ sendDownloadError(res, error, `Error downloading the matterbridge backup file.`);
330
335
  }
331
336
  else {
332
337
  this.log.debug(`Backup ${MATTERBRIDGE_BACKUP_FILE} downloaded successfully`);
@@ -341,7 +346,7 @@ export class BackendExpress {
341
346
  this.backend.backendWsServer?.wssSendCloseSnackbarMessage('Creating matterbridge storage backup...');
342
347
  if (error) {
343
348
  this.log.error(`Error downloading file matterbridge.${NODE_STORAGE_DIR}.zip: ${getErrorMessage(error)}`);
344
- res.status(500).send('Error downloading the matterbridge storage file');
349
+ sendDownloadError(res, error, 'Error downloading the matterbridge storage file');
345
350
  }
346
351
  else {
347
352
  this.log.debug(`Matterbridge storage matterbridge.${NODE_STORAGE_DIR}.zip downloaded successfully`);
@@ -356,7 +361,7 @@ export class BackendExpress {
356
361
  this.backend.backendWsServer?.wssSendCloseSnackbarMessage('Creating matter storage backup...');
357
362
  if (error) {
358
363
  this.log.error(`Error downloading the matter storage matterbridge.${MATTER_STORAGE_DIR}.zip: ${getErrorMessage(error)}`);
359
- res.status(500).send('Error downloading the matter storage file');
364
+ sendDownloadError(res, error, 'Error downloading the matter storage file');
360
365
  }
361
366
  else {
362
367
  this.log.debug(`Matter storage matterbridge.${MATTER_STORAGE_DIR}.zip downloaded successfully`);
@@ -371,7 +376,7 @@ export class BackendExpress {
371
376
  this.backend.backendWsServer?.wssSendCloseSnackbarMessage('Creating plugin backup...');
372
377
  if (error) {
373
378
  this.log.error(`Error downloading file ${MATTERBRIDGE_PLUGIN_STORAGE_FILE}: ${getErrorMessage(error)}`);
374
- res.status(500).send('Error downloading the matterbridge plugin storage file');
379
+ sendDownloadError(res, error, 'Error downloading the matterbridge plugin storage file');
375
380
  }
376
381
  else {
377
382
  this.log.debug(`Plugin storage ${MATTERBRIDGE_PLUGIN_STORAGE_FILE} downloaded successfully`);
@@ -386,7 +391,7 @@ export class BackendExpress {
386
391
  this.backend.backendWsServer?.wssSendCloseSnackbarMessage('Creating config backup...');
387
392
  if (error) {
388
393
  this.log.error(`Error downloading file ${MATTERBRIDGE_PLUGIN_CONFIG_FILE}: ${getErrorMessage(error)}`);
389
- res.status(500).send('Error downloading the matterbridge plugin config file');
394
+ sendDownloadError(res, error, 'Error downloading the matterbridge plugin config file');
390
395
  }
391
396
  else {
392
397
  this.log.debug(`Plugin config ${MATTERBRIDGE_PLUGIN_CONFIG_FILE} downloaded successfully`);
@@ -1,4 +1,3 @@
1
- import type { EndpointNumber } from '@matter/types/datatype';
2
1
  import type { ApiMatter, BridgeStatus, PluginStatusUpdate, RefreshRequiredChanged, SharedMatterbridge, WsMessageBroadcast } from '@matterbridge/types';
3
2
  import { WebSocketServer } from 'ws';
4
3
  import type { Backend } from './backend.js';
@@ -30,10 +29,7 @@ export declare class BackendWsServer {
30
29
  wssSendPluginUpdateRequired(plugin: string, version: string, devVersion?: boolean): void;
31
30
  wssSendPluginStatusUpdate(plugin: string, status: PluginStatusUpdate): void;
32
31
  wssSendMatterbridgeStatusUpdate(status: BridgeStatus): void;
33
- wssSendCpuUpdate(cpuUsage: number, processCpuUsage: number): void;
34
- wssSendMemoryUpdate(totalMemory: string, freeMemory: string, rss: string, heapTotal: string, heapUsed: string, external: string, arrayBuffers: string): void;
35
- wssSendUptimeUpdate(systemUptime: string, processUptime: string): void;
36
32
  wssSendSnackbarMessage(message: string, timeout?: number, severity?: 'info' | 'warning' | 'error' | 'success'): void;
37
33
  wssSendCloseSnackbarMessage(message: string): void;
38
- wssSendAttributeChangedMessage(plugin: string, serialNumber: string, uniqueId: string, number: EndpointNumber, id: string, cluster: string, attribute: string, value: number | string | boolean | null): void;
34
+ wssSendAttributeChangedMessage(plugin: string, serialNumber: string, uniqueId: string, number: number, id: string, cluster: string, attribute: string, value: number | string | boolean | null): void;
39
35
  }
@@ -46,6 +46,10 @@ export class BackendWsServer {
46
46
  this.log.logLevel = msg.params.logLevel;
47
47
  this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
48
48
  break;
49
+ case 'frontend_broadcast_message':
50
+ this.wssBroadcastMessage(msg.params.msg);
51
+ this.server.respond({ ...msg, result: { success: true } });
52
+ break;
49
53
  }
50
54
  }
51
55
  }
@@ -343,41 +347,6 @@ export class BackendWsServer {
343
347
  this.log.debug('Sending a matterbridge status update message to all connected clients');
344
348
  this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'matterbridge_status_update', success: true, response: { status } });
345
349
  }
346
- wssSendCpuUpdate(cpuUsage, processCpuUsage) {
347
- if (!this.hasActiveClients())
348
- return;
349
- if (this.verbose)
350
- this.log.debug('Sending a cpu update message to all connected clients');
351
- this.wssBroadcastMessage({
352
- id: 0,
353
- src: 'Matterbridge',
354
- dst: 'Frontend',
355
- method: 'cpu_update',
356
- success: true,
357
- response: { cpuUsage: Math.round(cpuUsage * 100) / 100, processCpuUsage: Math.round(processCpuUsage * 100) / 100 },
358
- });
359
- }
360
- wssSendMemoryUpdate(totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers) {
361
- if (!this.hasActiveClients())
362
- return;
363
- if (this.verbose)
364
- this.log.debug('Sending a memory update message to all connected clients');
365
- this.wssBroadcastMessage({
366
- id: 0,
367
- src: 'Matterbridge',
368
- dst: 'Frontend',
369
- method: 'memory_update',
370
- success: true,
371
- response: { totalMemory, freeMemory, rss, heapTotal, heapUsed, external, arrayBuffers },
372
- });
373
- }
374
- wssSendUptimeUpdate(systemUptime, processUptime) {
375
- if (!this.hasActiveClients())
376
- return;
377
- if (this.verbose)
378
- this.log.debug('Sending a uptime update message to all connected clients');
379
- this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'uptime_update', success: true, response: { systemUptime, processUptime } });
380
- }
381
350
  wssSendSnackbarMessage(message, timeout = 5, severity = 'info') {
382
351
  if (!this.hasActiveClients())
383
352
  return;
@@ -1,7 +1,7 @@
1
1
  import type { Endpoint } from '@matter/main/node';
2
2
  import { BindingBehavior, BindingServer } from '@matter/node/behaviors/binding';
3
- import type { ClusterId } from '@matter/types';
4
3
  import type { Binding } from '@matter/types/clusters/binding';
4
+ import type { ClusterId } from '@matter/types/datatype';
5
5
  import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
6
6
  export declare class MatterbridgeBindingServer extends BindingServer {
7
7
  readonly endpoint: MatterbridgeEndpoint;
@@ -1,6 +1,7 @@
1
1
  import { BooleanStateConfigurationServer } from '@matter/node/behaviors/boolean-state-configuration';
2
- import { Status, StatusResponseError } from '@matter/types';
3
2
  import { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
3
+ import { StatusResponseError } from '@matter/types/common';
4
+ import { Status } from '@matter/types/globals';
4
5
  import { debugStringify, nf } from 'node-ansi-logger';
5
6
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
7
  export class MatterbridgeBooleanStateConfigurationServer extends BooleanStateConfigurationServer.with(BooleanStateConfiguration.Feature.Visual, BooleanStateConfiguration.Feature.Audible, BooleanStateConfiguration.Feature.AlarmSuppress, BooleanStateConfiguration.Feature.SensitivityLevel, BooleanStateConfiguration.Feature.FaultEvents) {
@@ -1,7 +1,7 @@
1
1
  import { CameraAvSettingsUserLevelManagementServer } from '@matter/node/behaviors/camera-av-settings-user-level-management';
2
- import { type Viewport } from '@matter/types';
3
2
  import { CameraAvSettingsUserLevelManagement } from '@matter/types/clusters/camera-av-settings-user-level-management';
4
3
  import type { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
4
+ import { type Viewport } from '@matter/types/globals';
5
5
  import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
6
6
  declare const MatterbridgeCameraAvSettingsUserLevelManagementServer_base: import("@matter/node").ClusterBehavior.Type<typeof CameraAvSettingsUserLevelManagementServer, import("@matter/types").ClusterType.WithSupportedFeatures<CameraAvSettingsUserLevelManagement, {
7
7
  digitalPtz: true;
@@ -1,6 +1,7 @@
1
1
  import { CameraAvSettingsUserLevelManagementServer } from '@matter/node/behaviors/camera-av-settings-user-level-management';
2
- import { Status, StatusResponseError } from '@matter/types';
3
2
  import { CameraAvSettingsUserLevelManagement } from '@matter/types/clusters/camera-av-settings-user-level-management';
3
+ import { StatusResponseError } from '@matter/types/common';
4
+ import { Status } from '@matter/types/globals';
4
5
  import { MatterbridgeCameraAvStreamManagementServer } from './cameraAvStreamManagementServer.js';
5
6
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
7
  function clamp(value, min, max) {
@@ -1,7 +1,6 @@
1
1
  import { CameraAvStreamManagementServer } from '@matter/node/behaviors/camera-av-stream-management';
2
- import { StreamUsage } from '@matter/types';
3
- import type { Viewport } from '@matter/types';
4
2
  import { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
3
+ import { StreamUsage, type Viewport } from '@matter/types/globals';
5
4
  import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
6
5
  export type SnapshotSource = 'test' | 'webcam' | 'rtsp';
7
6
  declare const MatterbridgeCameraAvStreamManagementServerBase: import("@matter/node").ClusterBehavior.Type<typeof CameraAvStreamManagementServer, import("@matter/types").ClusterType.WithSupportedFeatures<CameraAvStreamManagement, {
@@ -1,7 +1,8 @@
1
1
  import { CameraAvStreamManagementServer } from '@matter/node/behaviors/camera-av-stream-management';
2
2
  import { WebRtcTransportProviderServer } from '@matter/node/behaviors/web-rtc-transport-provider';
3
- import { Status, StatusResponseError, StreamUsage, ThreeLevelAuto } from '@matter/types';
4
3
  import { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
4
+ import { StatusResponseError } from '@matter/types/common';
5
+ import { Status, StreamUsage, ThreeLevelAuto } from '@matter/types/globals';
5
6
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
7
  import { captureSnapshot, TEST_SNAPSHOT_SOURCE } from './snapshot.js';
7
8
  const AUDIO_STREAM_BIT_DEPTHS = [8, 16, 24, 32];
@@ -1,6 +1,7 @@
1
1
  import { ChimeServer } from '@matter/node/behaviors/chime';
2
- import { Status, StatusResponseError } from '@matter/types';
3
2
  import { Chime } from '@matter/types/clusters/chime';
3
+ import { StatusResponseError } from '@matter/types/common';
4
+ import { Status } from '@matter/types/globals';
4
5
  import { MatterbridgeServer } from './matterbridgeServer.js';
5
6
  const ChimeServerBase = ChimeServer.enable({ events: { chimeStartedPlaying: true } });
6
7
  export class MatterbridgeChimeServer extends ChimeServerBase {
@@ -1,7 +1,8 @@
1
1
  import { Seconds, Time } from '@matter/general';
2
2
  import { DeviceEnergyManagementServer } from '@matter/node/behaviors/device-energy-management';
3
- import { Status, StatusResponseError } from '@matter/types';
4
3
  import { DeviceEnergyManagement } from '@matter/types/clusters/device-energy-management';
4
+ import { StatusResponseError } from '@matter/types/common';
5
+ import { Status } from '@matter/types/globals';
5
6
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
7
  export class MatterbridgeDeviceEnergyManagementServer extends DeviceEnergyManagementServer.with(DeviceEnergyManagement.Feature.PowerForecastReporting, DeviceEnergyManagement.Feature.PowerAdjustment) {
7
8
  async initialize() {
@@ -1,6 +1,7 @@
1
1
  import { FanControlServer } from '@matter/node/behaviors/fan-control';
2
- import { Status, StatusResponseError } from '@matter/types';
3
2
  import { FanControl } from '@matter/types/clusters/fan-control';
3
+ import { StatusResponseError } from '@matter/types/common';
4
+ import { Status } from '@matter/types/globals';
4
5
  import { getEnumDescription } from '@matterbridge/utils/enum';
5
6
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
7
  const lookupStepDirection = ['Increase', 'Decrease'];
@@ -1,8 +1,9 @@
1
1
  import { LevelControlServer } from '@matter/node/behaviors/level-control';
2
2
  import { OnOffServer } from '@matter/node/behaviors/on-off';
3
3
  import { PumpConfigurationAndControlServer } from '@matter/node/behaviors/pump-configuration-and-control';
4
- import { Status, StatusResponseError } from '@matter/types';
5
4
  import { PumpConfigurationAndControl } from '@matter/types/clusters/pump-configuration-and-control';
5
+ import { StatusResponseError } from '@matter/types/common';
6
+ import { Status } from '@matter/types/globals';
6
7
  import { MatterbridgeServer } from './matterbridgeServer.js';
7
8
  export class MatterbridgePumpConfigurationAndControlServer extends PumpConfigurationAndControlServer.with(PumpConfigurationAndControl.Feature.ConstantSpeed) {
8
9
  initialize() {
@@ -1,7 +1,8 @@
1
1
  import { Seconds, Time } from '@matter/general';
2
2
  import { SmokeCoAlarmServer } from '@matter/node/behaviors/smoke-co-alarm';
3
- import { Status, StatusResponseError } from '@matter/types';
4
3
  import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
4
+ import { StatusResponseError } from '@matter/types/common';
5
+ import { Status } from '@matter/types/globals';
5
6
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
7
  export class MatterbridgeSmokeCoAlarmServer extends SmokeCoAlarmServer.with(SmokeCoAlarm.Feature.SmokeAlarm, SmokeCoAlarm.Feature.CoAlarm) {
7
8
  static selfTestDurationSeconds = 5;
@@ -1,7 +1,8 @@
1
1
  import { AttributeElement, CommandElement, EventElement, FieldElement } from '@matter/model';
2
2
  import { TemperatureAlarmServer } from '@matter/node/behaviors/temperature-alarm';
3
- import { Status, StatusResponseError } from '@matter/types';
4
3
  import { TemperatureAlarm } from '@matter/types/clusters/temperature-alarm';
4
+ import { StatusResponseError } from '@matter/types/common';
5
+ import { Status } from '@matter/types/globals';
5
6
  import { debugStringify, nf } from 'node-ansi-logger';
6
7
  import { MatterbridgeServer } from './matterbridgeServer.js';
7
8
  const MatterbridgeTemperatureAlarmSchema = TemperatureAlarmServer.schema.extend({}, AttributeElement({ name: 'Mask', id: 0x0000, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'Latch', id: 0x0001, type: 'AlarmBitmap', access: 'R V', conformance: 'RESET', quality: 'F' }), AttributeElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'Supported', id: 0x0003, type: 'AlarmBitmap', access: 'R V', conformance: 'M', quality: 'F' }), CommandElement({ name: 'Reset', id: 0x0000, access: 'O', conformance: 'RESET', direction: 'request', response: 'status' }, FieldElement({ name: 'Alarms', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' })), CommandElement({ name: 'ModifyEnabledAlarms', id: 0x0001, access: 'O', conformance: 'O', direction: 'request', response: 'status' }, FieldElement({ name: 'Mask', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' })), EventElement({ name: 'Notify', id: 0x0000, access: 'V', conformance: 'M', priority: 'info' }, FieldElement({ name: 'Active', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Inactive', id: 0x0001, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Mask', id: 0x0003, type: 'AlarmBitmap', conformance: 'M' })));
@@ -1,7 +1,8 @@
1
1
  import { Bytes } from '@matter/general';
2
2
  import { ThermostatServer } from '@matter/node/behaviors/thermostat';
3
- import { Status, StatusResponseError } from '@matter/types';
4
3
  import { Thermostat } from '@matter/types/clusters/thermostat';
4
+ import { StatusResponseError } from '@matter/types/common';
5
+ import { Status } from '@matter/types/globals';
5
6
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
7
  export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermostat.Feature.Cooling, Thermostat.Feature.Heating, Thermostat.Feature.AutoMode, Thermostat.Feature.Presets, Thermostat.Feature.MatterScheduleConfiguration, Thermostat.Feature.ThermostatSuggestions) {
7
8
  async initialize() {
@@ -1,7 +1,8 @@
1
1
  import { Millis, Seconds, Time } from '@matter/general';
2
2
  import { ValveConfigurationAndControlServer } from '@matter/node/behaviors/valve-configuration-and-control';
3
- import { Status, StatusResponseError } from '@matter/types';
4
3
  import { ValveConfigurationAndControl } from '@matter/types/clusters/valve-configuration-and-control';
4
+ import { StatusResponseError } from '@matter/types/common';
5
+ import { Status } from '@matter/types/globals';
5
6
  import { MatterbridgeServer } from './matterbridgeServer.js';
6
7
  const MatterbridgeValveConfigurationAndControlServerBase = ValveConfigurationAndControlServer.with(ValveConfigurationAndControl.Feature.Level);
7
8
  export class MatterbridgeValveConfigurationAndControlServer extends MatterbridgeValveConfigurationAndControlServerBase {
@@ -1,9 +1,11 @@
1
1
  import { Node } from '@matter/main';
2
2
  import { WebRtcTransportProviderServer } from '@matter/node/behaviors/web-rtc-transport-provider';
3
3
  import { WebRtcTransportRequestorClient } from '@matter/node/behaviors/web-rtc-transport-requestor';
4
- import { EndpointNumber, FabricIndex, NodeId, StreamUsage, Status, StatusResponseError } from '@matter/types';
5
4
  import { WebRtcTransportDefinitions } from '@matter/types/clusters/web-rtc-transport-definitions';
6
5
  import { WebRtcTransportProvider } from '@matter/types/clusters/web-rtc-transport-provider';
6
+ import { StatusResponseError } from '@matter/types/common';
7
+ import { EndpointNumber, FabricIndex, NodeId } from '@matter/types/datatype';
8
+ import { Status, StreamUsage } from '@matter/types/globals';
7
9
  import { MatterbridgeCameraAvStreamManagementServer } from './cameraAvStreamManagementServer.js';
8
10
  import { MatterbridgeServer } from './matterbridgeServer.js';
9
11
  import { WeriftWebRtcSession } from './weriftSession.js';
package/dist/chipTests.js CHANGED
@@ -4,7 +4,6 @@ import { Seconds, Time } from '@matter/general';
4
4
  import { BasicInformationServer } from '@matter/node/behaviors/basic-information';
5
5
  import { BridgedDeviceBasicInformationServer } from '@matter/node/behaviors/bridged-device-basic-information';
6
6
  import { GeneralDiagnosticsServer } from '@matter/node/behaviors/general-diagnostics';
7
- import { MATTER_EPOCH_OFFSET_S, Status, StatusResponseError } from '@matter/types';
8
7
  import { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
9
8
  import { ClosureControl } from '@matter/types/clusters/closure-control';
10
9
  import { CommodityMetering } from '@matter/types/clusters/commodity-metering';
@@ -22,7 +21,9 @@ import { RvcOperationalState } from '@matter/types/clusters/rvc-operational-stat
22
21
  import { RvcRunMode } from '@matter/types/clusters/rvc-run-mode';
23
22
  import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
24
23
  import { Switch } from '@matter/types/clusters/switch';
25
- import { TariffPriceType, TariffUnit } from '@matter/types/globals';
24
+ import { StatusResponseError } from '@matter/types/common';
25
+ import { Status, TariffPriceType, TariffUnit } from '@matter/types/globals';
26
+ import { MATTER_EPOCH_OFFSET_S } from '@matter/types/tlv';
26
27
  import { wait } from '@matterbridge/utils/wait';
27
28
  import { MatterbridgeOccupancySensingServer } from './behaviors/occupancySensingServer.js';
28
29
  import { cliEmitter } from './cliEmitter.js';
package/dist/cli.js CHANGED
@@ -1,7 +1,9 @@
1
+ import os from 'node:os';
1
2
  import path from 'node:path';
2
3
  import { fileURLToPath } from 'node:url';
3
4
  import { ThreadsManager } from '@matterbridge/thread/manager';
4
5
  import { BroadcastServer } from '@matterbridge/thread/server';
6
+ import { constrainedMemory, memoryFootprint } from '@matterbridge/utils/bun';
5
7
  import { hasAnyParameter, hasParameter } from '@matterbridge/utils/cli';
6
8
  import { inspectError } from '@matterbridge/utils/error';
7
9
  import { formatBytes, formatUptime } from '@matterbridge/utils/format';
@@ -18,14 +20,44 @@ const log = new AnsiLogger({ logName: 'Cli', logTimestampFormat: 4, logLevel: ha
18
20
  const manager = new ThreadsManager(path.dirname(fileURLToPath(import.meta.url)));
19
21
  const server = new BroadcastServer('cli', log);
20
22
  function startCpuMemoryCheck() {
23
+ const memoryUsage = process.memoryUsage();
24
+ const systemUpdate = {
25
+ systemUptime: formatUptime(Math.floor(os.uptime())),
26
+ processUptime: formatUptime(Math.floor(process.uptime())),
27
+ totalMemory: formatBytes(os.totalmem()),
28
+ freeMemory: formatBytes(os.freemem()),
29
+ constrainedMemory: formatBytes(constrainedMemory()),
30
+ rss: formatBytes(memoryFootprint()),
31
+ heapTotal: formatBytes(memoryUsage.heapTotal),
32
+ heapUsed: formatBytes(memoryUsage.heapUsed),
33
+ external: formatBytes(memoryUsage.external),
34
+ arrayBuffers: formatBytes(memoryUsage.arrayBuffers),
35
+ cpuUsage: 0,
36
+ processCpuUsage: 0,
37
+ };
21
38
  log.debug(`Cpu memory check starting...`);
22
39
  tracker.start();
23
- tracker.on('uptime', (os, process) => {
24
- cliEmitter.emit('uptime', formatUptime(Math.floor(os)), formatUptime(Math.floor(process)));
40
+ tracker.on('uptime', (systemUptime, processUptime) => {
41
+ systemUpdate.systemUptime = formatUptime(Math.floor(systemUptime));
42
+ systemUpdate.processUptime = formatUptime(Math.floor(processUptime));
25
43
  });
26
44
  tracker.on('snapshot', (snapshot) => {
27
- cliEmitter.emit('memory', formatBytes(snapshot.totalMemory), formatBytes(snapshot.freeMemory), formatBytes(snapshot.rss), formatBytes(snapshot.heapTotal), formatBytes(snapshot.heapUsed), formatBytes(snapshot.external), formatBytes(snapshot.arrayBuffers));
28
- cliEmitter.emit('cpu', snapshot.osCpu, snapshot.processCpu);
45
+ systemUpdate.totalMemory = formatBytes(snapshot.totalMemory);
46
+ systemUpdate.freeMemory = formatBytes(snapshot.freeMemory);
47
+ systemUpdate.constrainedMemory = formatBytes(snapshot.constrainedMemory);
48
+ systemUpdate.rss = formatBytes(snapshot.rss);
49
+ systemUpdate.heapTotal = formatBytes(snapshot.heapTotal);
50
+ systemUpdate.heapUsed = formatBytes(snapshot.heapUsed);
51
+ systemUpdate.external = formatBytes(snapshot.external);
52
+ systemUpdate.arrayBuffers = formatBytes(snapshot.arrayBuffers);
53
+ systemUpdate.cpuUsage = Math.round(snapshot.osCpu * 100) / 100;
54
+ systemUpdate.processCpuUsage = Math.round(snapshot.processCpu * 100) / 100;
55
+ server.request({
56
+ type: 'frontend_broadcast_message',
57
+ src: 'cli',
58
+ dst: 'frontend',
59
+ params: { msg: { id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'system_update', success: true, response: systemUpdate } },
60
+ });
29
61
  });
30
62
  log.debug(`Cpu memory check started`);
31
63
  }
@@ -1,9 +1,6 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  interface CliEvents {
3
3
  shutdown: [];
4
- cpu: [cpuUsage: number, processCpuUsage: number];
5
- memory: [totalMememory: string, freeMemory: string, rss: string, heapTotal: string, heapUsed: string, external: string, arrayBuffers: string];
6
- uptime: [systemUptime: string, processUptime: string];
7
4
  ready: [];
8
5
  }
9
6
  export declare const cliEmitter: EventEmitter<CliEvents>;
@@ -1,7 +1,6 @@
1
1
  import type { ApiDevice, BaseDevice } from '@matterbridge/types';
2
2
  import { LogLevel } from 'node-ansi-logger';
3
3
  import type { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
4
- export declare function toBaseDevice(device: MatterbridgeEndpoint | BaseDevice): BaseDevice;
5
4
  export declare class DeviceManager {
6
5
  private readonly _devices;
7
6
  private readonly log;
@@ -3,35 +3,8 @@ import { dev } from '@matterbridge/types';
3
3
  import { hasParameter } from '@matterbridge/utils/cli';
4
4
  import { logModuleLoaded } from '@matterbridge/utils/loader';
5
5
  import { AnsiLogger, BLUE, CYAN, db, debugStringify, er } from 'node-ansi-logger';
6
- import { getBatteryLevel, getClusterTextFromDevice, getPowerSource, getReachability, getServerNodeData } from './matterNodeHelpers.js';
6
+ import { toApiDevice, toBaseDevice } from './matterNodeHelpers.js';
7
7
  logModuleLoaded('Device Manager');
8
- export function toBaseDevice(device) {
9
- return {
10
- mode: device.mode,
11
- plugin: device.plugin,
12
- configUrl: device.configUrl,
13
- deviceName: device.deviceName,
14
- serialNumber: device.serialNumber,
15
- uniqueId: device.uniqueId,
16
- vendorId: device.vendorId,
17
- vendorName: device.vendorName,
18
- productId: device.productId,
19
- productName: device.productName,
20
- productLabel: device.productLabel,
21
- productUrl: device.productUrl,
22
- configurationVersion: device.configurationVersion,
23
- softwareVersion: device.softwareVersion,
24
- softwareVersionString: device.softwareVersionString,
25
- hardwareVersion: device.hardwareVersion,
26
- hardwareVersionString: device.hardwareVersionString,
27
- tagList: device.tagList,
28
- originalId: device.originalId,
29
- name: device.name,
30
- deviceType: device.deviceType,
31
- number: device.number,
32
- id: device.id,
33
- };
34
- }
35
8
  export class DeviceManager {
36
9
  _devices = new Map();
37
10
  log;
@@ -39,7 +12,7 @@ export class DeviceManager {
39
12
  debug = hasParameter('debug') || hasParameter('verbose');
40
13
  verbose = hasParameter('verbose');
41
14
  constructor() {
42
- this.log = new AnsiLogger({ logName: 'DeviceManager', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
15
+ this.log = new AnsiLogger({ logName: 'DeviceManager', logTimestampFormat: 4, logLevel: this.debug ? "debug" : "info" });
43
16
  this.log.debug('Matterbridge device manager starting...');
44
17
  this.server = new BroadcastServer('devices', this.log);
45
18
  this.server.on('broadcast_message', this.msgHandler.bind(this));
@@ -76,7 +49,16 @@ export class DeviceManager {
76
49
  }
77
50
  break;
78
51
  case 'devices_set':
79
- this.server.respond({ ...msg, result: { device: this.set(toBaseDevice(msg.params.device)) } });
52
+ {
53
+ const device = msg.params.device.uniqueId ? this._devices.get(msg.params.device.uniqueId) : undefined;
54
+ if (device) {
55
+ Object.assign(device, Object.fromEntries(Object.entries(toBaseDevice(msg.params.device)).filter(([, value]) => value !== undefined)));
56
+ this.server.respond({ ...msg, result: { device: device } });
57
+ }
58
+ else {
59
+ this.server.respond({ ...msg, result: { device: this.set(toBaseDevice(msg.params.device)) } });
60
+ }
61
+ }
80
62
  break;
81
63
  case 'devices_remove':
82
64
  this.server.respond({ ...msg, result: { success: this.remove(toBaseDevice(msg.params.device)) } });
@@ -147,23 +129,9 @@ export class DeviceManager {
147
129
  for (const device of this._devices.values()) {
148
130
  if (pluginName && pluginName !== device.plugin)
149
131
  continue;
150
- if (!device.plugin || !device.deviceType || !device.name || !device.deviceName || !device.serialNumber || !device.uniqueId || !device.lifecycle.isReady)
151
- continue;
152
- devices.push({
153
- pluginName: device.plugin,
154
- type: device.name + ' (0x' + device.deviceType.toString(16).padStart(4, '0') + ')',
155
- endpoint: device.number,
156
- name: device.deviceName,
157
- serial: device.serialNumber,
158
- productUrl: device.productUrl,
159
- configUrl: device.configUrl,
160
- uniqueId: device.uniqueId,
161
- reachable: getReachability(device),
162
- powerSource: getPowerSource(device),
163
- batteryLevel: getBatteryLevel(device),
164
- matter: device.mode === 'server' && device.serverNode ? getServerNodeData(device.serverNode) : undefined,
165
- cluster: getClusterTextFromDevice(device),
166
- });
132
+ const apiDevice = toApiDevice(device);
133
+ if (apiDevice)
134
+ devices.push(apiDevice);
167
135
  }
168
136
  return devices;
169
137
  }
@@ -1,6 +1,6 @@
1
- import type { EndpointNumber } from '@matter/types';
2
1
  import { FanControl } from '@matter/types/clusters/fan-control';
3
2
  import { ThermostatUserInterfaceConfiguration } from '@matter/types/clusters/thermostat-user-interface-configuration';
3
+ import type { EndpointNumber } from '@matter/types/datatype';
4
4
  import type { Semtag } from '@matter/types/globals';
5
5
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
6
6
  export interface AirConditionerOptions {
@@ -1,6 +1,6 @@
1
- import { StreamUsage } from '@matter/types';
2
1
  import { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
3
2
  import { Identify } from '@matter/types/clusters/identify';
3
+ import { StreamUsage } from '@matter/types/globals';
4
4
  import type { WeriftOfferOptions } from '../behaviors/weriftSession.js';
5
5
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
6
6
  import type { MatterbridgeEndpointOptions } from '../matterbridgeEndpointTypes.js';
@@ -1,6 +1,6 @@
1
- import { StreamUsage } from '@matter/types';
2
1
  import { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
3
2
  import { Identify } from '@matter/types/clusters/identify';
3
+ import { StreamUsage } from '@matter/types/globals';
4
4
  import { createDefaultAudioCameraAvStreamManagementClusterServer } from '../behaviors/cameraAvStreamManagementServer.js';
5
5
  import { addChimeClient, addWebRtcTransportRequestorClient } from '../behaviors/clients.js';
6
6
  import { createDefaultWebRtcTransportProviderClusterServer } from '../behaviors/webRtcTransportProviderServer.js';
@@ -1,5 +1,5 @@
1
- import type { EndpointNumber } from '@matter/types';
2
1
  import { PowerSource } from '@matter/types/clusters/power-source';
2
+ import type { EndpointNumber } from '@matter/types/datatype';
3
3
  import type { Semtag } from '@matter/types/globals';
4
4
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
5
5
  export interface BatteryStorageOptions {
@@ -1,8 +1,7 @@
1
- import { StreamUsage } from '@matter/types';
2
- import type { Viewport } from '@matter/types';
3
1
  import type { CameraAvSettingsUserLevelManagement } from '@matter/types/clusters/camera-av-settings-user-level-management';
4
2
  import { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
5
3
  import { Identify } from '@matter/types/clusters/identify';
4
+ import { StreamUsage, type Viewport } from '@matter/types/globals';
6
5
  import type { WeriftOfferOptions } from '../behaviors/weriftSession.js';
7
6
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
8
7
  import type { MatterbridgeEndpointOptions } from '../matterbridgeEndpointTypes.js';
@@ -1,6 +1,6 @@
1
- import { StreamUsage } from '@matter/types';
2
1
  import { CameraAvStreamManagement } from '@matter/types/clusters/camera-av-stream-management';
3
2
  import { Identify } from '@matter/types/clusters/identify';
3
+ import { StreamUsage } from '@matter/types/globals';
4
4
  import { createDefaultCameraAvSettingsUserLevelManagementClusterServer } from '../behaviors/cameraAvSettingsUserLevelManagementServer.js';
5
5
  import { createDefaultCameraAvStreamManagementClusterServer } from '../behaviors/cameraAvStreamManagementServer.js';
6
6
  import { addWebRtcTransportRequestorClient } from '../behaviors/clients.js';
@@ -1,9 +1,9 @@
1
1
  import { type MaybePromise, type Timer } from '@matter/general';
2
2
  import { ClosureControlServer } from '@matter/node/behaviors/closure-control';
3
- import { type EndpointNumber } from '@matter/types';
4
3
  import { ClosureControl } from '@matter/types/clusters/closure-control';
5
4
  import { Identify } from '@matter/types/clusters/identify';
6
- import type { Semtag } from '@matter/types/globals';
5
+ import type { EndpointNumber } from '@matter/types/datatype';
6
+ import { type Semtag } from '@matter/types/globals';
7
7
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
8
8
  import { type ClosureDimensionType, type ClosurePanelOptions } from './closurePanel.js';
9
9
  declare const MatterbridgeClosureControlServerBase: import("@matter/node").ClusterBehavior.Type<typeof ClosureControlServer, import("@matter/types").ClusterType.WithSupportedFeatures<ClosureControl, {
@@ -1,9 +1,9 @@
1
1
  import { Millis, Time } from '@matter/general';
2
2
  import { ClosureTag } from '@matter/node';
3
3
  import { ClosureControlServer } from '@matter/node/behaviors/closure-control';
4
- import { StatusResponse } from '@matter/types';
5
4
  import { ClosureControl } from '@matter/types/clusters/closure-control';
6
5
  import { Identify } from '@matter/types/clusters/identify';
6
+ import { StatusResponse } from '@matter/types/common';
7
7
  import { ThreeLevelAuto } from '@matter/types/globals';
8
8
  import { MatterbridgeServer } from '../behaviors/matterbridgeServer.js';
9
9
  import { closure, closurePanel, powerSource } from '../matterbridgeDeviceTypes.js';
@@ -1,9 +1,9 @@
1
1
  import { Millis, Time } from '@matter/general';
2
2
  import { ClosureControlServer } from '@matter/node/behaviors/closure-control';
3
3
  import { ClosureDimensionServer } from '@matter/node/behaviors/closure-dimension';
4
- import { StatusResponse } from '@matter/types';
5
4
  import { ClosureControl } from '@matter/types/clusters/closure-control';
6
5
  import { ClosureDimension } from '@matter/types/clusters/closure-dimension';
6
+ import { StatusResponse } from '@matter/types/common';
7
7
  import { ThreeLevelAuto } from '@matter/types/globals';
8
8
  import { MatterbridgeServer } from '../behaviors/matterbridgeServer.js';
9
9
  const MatterbridgeClosureDimensionServerBase = ClosureDimensionServer.with(ClosureDimension.Feature.Positioning, ClosureDimension.Feature.MotionLatching, ClosureDimension.Feature.Speed);