@matterbridge/core 3.5.6-dev-20260221-7ca0f7a → 3.5.6-dev-20260223-7c65d78

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 (65) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/cliHistory.js +1 -1
  3. package/dist/deviceManager.d.ts +1 -1
  4. package/dist/deviceManager.js +3 -3
  5. package/dist/devices/airConditioner.d.ts +1 -1
  6. package/dist/devices/airConditioner.js +1 -1
  7. package/dist/devices/basicVideoPlayer.d.ts +3 -3
  8. package/dist/devices/basicVideoPlayer.js +4 -4
  9. package/dist/devices/batteryStorage.js +1 -1
  10. package/dist/devices/castingVideoPlayer.d.ts +1 -1
  11. package/dist/devices/castingVideoPlayer.js +2 -2
  12. package/dist/devices/dishwasher.d.ts +3 -3
  13. package/dist/devices/dishwasher.js +4 -4
  14. package/dist/devices/evse.d.ts +3 -3
  15. package/dist/devices/evse.js +5 -5
  16. package/dist/devices/export.d.ts +9 -9
  17. package/dist/devices/export.js +9 -9
  18. package/dist/devices/heatPump.js +1 -1
  19. package/dist/devices/laundryDryer.d.ts +2 -2
  20. package/dist/devices/laundryDryer.js +2 -2
  21. package/dist/devices/laundryWasher.d.ts +2 -2
  22. package/dist/devices/laundryWasher.js +3 -3
  23. package/dist/devices/microwaveOven.d.ts +2 -2
  24. package/dist/devices/microwaveOven.js +4 -4
  25. package/dist/devices/oven.d.ts +3 -3
  26. package/dist/devices/oven.js +4 -4
  27. package/dist/devices/refrigerator.d.ts +1 -1
  28. package/dist/devices/refrigerator.js +3 -3
  29. package/dist/devices/roboticVacuumCleaner.d.ts +6 -6
  30. package/dist/devices/roboticVacuumCleaner.js +8 -8
  31. package/dist/devices/solarPower.js +1 -1
  32. package/dist/devices/speaker.js +1 -1
  33. package/dist/devices/temperatureControl.d.ts +1 -1
  34. package/dist/devices/temperatureControl.js +1 -1
  35. package/dist/devices/waterHeater.d.ts +2 -2
  36. package/dist/devices/waterHeater.js +3 -3
  37. package/dist/export.d.ts +5 -5
  38. package/dist/export.js +5 -5
  39. package/dist/frontend.d.ts +1 -1
  40. package/dist/frontend.js +8 -8
  41. package/dist/helpers.js +3 -3
  42. package/dist/jestutils/jestHelpers.d.ts +13 -5
  43. package/dist/jestutils/jestHelpers.js +66 -8
  44. package/dist/matter/endpoints.d.ts +1 -1
  45. package/dist/matter/endpoints.js +1 -1
  46. package/dist/matterNode.d.ts +4 -4
  47. package/dist/matterNode.js +14 -14
  48. package/dist/matterbridge.d.ts +12 -7
  49. package/dist/matterbridge.js +117 -15
  50. package/dist/matterbridgeAccessoryPlatform.d.ts +1 -1
  51. package/dist/matterbridgeBehaviors.d.ts +28 -28
  52. package/dist/matterbridgeBehaviors.js +27 -27
  53. package/dist/matterbridgeDeviceTypes.js +2 -2
  54. package/dist/matterbridgeDynamicPlatform.d.ts +1 -1
  55. package/dist/matterbridgeEndpoint.d.ts +17 -17
  56. package/dist/matterbridgeEndpoint.js +50 -50
  57. package/dist/matterbridgeEndpointHelpers.d.ts +14 -14
  58. package/dist/matterbridgeEndpointHelpers.js +65 -65
  59. package/dist/matterbridgeEndpointTypes.d.ts +3 -3
  60. package/dist/matterbridgePlatform.d.ts +3 -3
  61. package/dist/matterbridgePlatform.js +5 -5
  62. package/dist/pluginManager.d.ts +4 -4
  63. package/dist/pluginManager.js +3 -3
  64. package/dist/spawn.js +2 -2
  65. package/package.json +6 -6
package/dist/helpers.js CHANGED
@@ -1,14 +1,14 @@
1
1
  if (process.argv.includes('--loader') || process.argv.includes('-loader'))
2
2
  console.log('\u001B[32mMatterbridge helpers loaded.\u001B[40;0m');
3
- import { OnOff } from '@matter/types/clusters/on-off';
4
3
  import { Endpoint } from '@matter/node';
5
4
  import { BridgedDeviceBasicInformationServer } from '@matter/node/behaviors/bridged-device-basic-information';
6
- import { OnOffBaseServer } from '@matter/node/behaviors/on-off';
7
5
  import { DescriptorServer } from '@matter/node/behaviors/descriptor';
8
- import { OnOffPlugInUnitDevice } from '@matter/node/devices/on-off-plug-in-unit';
6
+ import { OnOffBaseServer } from '@matter/node/behaviors/on-off';
9
7
  import { MountedOnOffControlDevice } from '@matter/node/devices/mounted-on-off-control';
10
8
  import { OnOffLightDevice } from '@matter/node/devices/on-off-light';
11
9
  import { OnOffLightSwitchDevice } from '@matter/node/devices/on-off-light-switch';
10
+ import { OnOffPlugInUnitDevice } from '@matter/node/devices/on-off-plug-in-unit';
11
+ import { OnOff } from '@matter/types/clusters/on-off';
12
12
  import { VendorId } from '@matter/types/datatype';
13
13
  import { hasParameter } from '@matterbridge/utils';
14
14
  export async function addVirtualDevice(aggregatorEndpoint, name, type, callback) {
@@ -1,16 +1,18 @@
1
1
  import type { jest } from '@jest/globals';
2
- import { AnsiLogger } from 'node-ansi-logger';
3
2
  import { Environment } from '@matter/general';
4
3
  import { Endpoint, ServerNode } from '@matter/node';
5
- import { DeviceTypeId } from '@matter/types/datatype';
6
4
  import { AggregatorEndpoint } from '@matter/node/endpoints';
5
+ import { ColorControl } from '@matter/types/clusters/color-control';
6
+ import { LevelControl } from '@matter/types/clusters/level-control';
7
+ import { DeviceTypeId } from '@matter/types/datatype';
7
8
  import { BroadcastServer } from '@matterbridge/thread';
8
- import { Matterbridge } from '../matterbridge.js';
9
- import { MatterbridgePlatform } from '../matterbridgePlatform.js';
9
+ import { AnsiLogger } from 'node-ansi-logger';
10
10
  import { DeviceManager } from '../deviceManager.js';
11
- import { PluginManager } from '../pluginManager.js';
12
11
  import { Frontend } from '../frontend.js';
12
+ import { Matterbridge } from '../matterbridge.js';
13
13
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
14
+ import { MatterbridgePlatform } from '../matterbridgePlatform.js';
15
+ import { PluginManager } from '../pluginManager.js';
14
16
  export declare const originalProcessArgv: readonly string[];
15
17
  export declare const originalProcessEnv: Readonly<Record<string, string | undefined>>;
16
18
  export declare let loggerLogSpy: jest.SpiedFunction<typeof AnsiLogger.prototype.log>;
@@ -88,3 +90,9 @@ export declare function startServerNode(name: string, port: number, deviceType?:
88
90
  export declare function stopServerNode(server: ServerNode<ServerNode.RootEndpoint>, createOnly?: boolean): Promise<void>;
89
91
  export declare function addDevice(owner: ServerNode<ServerNode.RootEndpoint> | Endpoint<AggregatorEndpoint>, device: Endpoint, pause?: number): Promise<boolean>;
90
92
  export declare function deleteDevice(owner: ServerNode<ServerNode.RootEndpoint> | Endpoint<AggregatorEndpoint>, device: Endpoint, pause?: number): Promise<boolean>;
93
+ export declare function getMoveToLevelRequest(level: number, transitionTime: number, executeIfOff: boolean): LevelControl.MoveToLevelRequest;
94
+ export declare function getMoveToColorTemperatureRequest(colorTemperatureMireds: number, transitionTime: number, executeIfOff: boolean): ColorControl.MoveToColorTemperatureRequest;
95
+ export declare function getMoveToHueRequest(hue: number, transitionTime: number, executeIfOff: boolean): ColorControl.MoveToHueRequest;
96
+ export declare function getMoveToSaturationRequest(saturation: number, transitionTime: number, executeIfOff: boolean): ColorControl.MoveToSaturationRequest;
97
+ export declare function getMoveToHueAndSaturationRequest(hue: number, saturation: number, transitionTime: number, executeIfOff: boolean): ColorControl.MoveToHueAndSaturationRequest;
98
+ export declare function getMoveToColorRequest(colorX: number, colorY: number, transitionTime: number, executeIfOff: boolean): ColorControl.MoveToColorRequest;
@@ -1,20 +1,21 @@
1
1
  import { rmSync } from 'node:fs';
2
- import { inspect } from 'node:util';
3
2
  import path from 'node:path';
4
- import { AnsiLogger, er, rs, UNDERLINE, UNDERLINEOFF } from 'node-ansi-logger';
5
- import { NodeStorageManager } from 'node-persist-manager';
6
- import { LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, Environment, Lifecycle } from '@matter/general';
3
+ import { inspect } from 'node:util';
4
+ import { Environment, Lifecycle, LogFormat as MatterLogFormat, LogLevel as MatterLogLevel } from '@matter/general';
7
5
  import { Endpoint, ServerNode, ServerNodeStore } from '@matter/node';
8
- import { DeviceTypeId, VendorId } from '@matter/types/datatype';
9
6
  import { AggregatorEndpoint } from '@matter/node/endpoints';
10
7
  import { MdnsService } from '@matter/protocol';
8
+ import { ColorControl } from '@matter/types/clusters/color-control';
9
+ import { DeviceTypeId, VendorId } from '@matter/types/datatype';
11
10
  import { BroadcastServer } from '@matterbridge/thread';
12
11
  import { MATTER_STORAGE_NAME, NODE_STORAGE_DIR } from '@matterbridge/types';
12
+ import { AnsiLogger, er, rs, UNDERLINE, UNDERLINEOFF } from 'node-ansi-logger';
13
+ import { NodeStorageManager } from 'node-persist-manager';
14
+ import { Frontend } from '../frontend.js';
13
15
  import { Matterbridge } from '../matterbridge.js';
14
16
  import { bridge } from '../matterbridgeDeviceTypes.js';
15
- import { PluginManager } from '../pluginManager.js';
16
- import { Frontend } from '../frontend.js';
17
17
  import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
18
+ import { PluginManager } from '../pluginManager.js';
18
19
  export const originalProcessArgv = Object.freeze([...process.argv]);
19
20
  export const originalProcessEnv = Object.freeze({ ...process.env });
20
21
  export let loggerLogSpy;
@@ -254,7 +255,7 @@ export async function createMatterbridgeEnvironment(name) {
254
255
  matterbridge = await Matterbridge.loadInstance(false);
255
256
  expect(matterbridge).toBeDefined();
256
257
  expect(matterbridge).toBeInstanceOf(Matterbridge);
257
- matterbridge.matterbridgeVersion = '3.5.5';
258
+ matterbridge.matterbridgeVersion = '3.5.6';
258
259
  matterbridge.bridgeMode = 'bridge';
259
260
  matterbridge.rootDirectory = path.join('jest', name);
260
261
  matterbridge.homeDirectory = path.join('jest', name);
@@ -605,3 +606,60 @@ export async function deleteDevice(owner, device, pause = 10) {
605
606
  await flushAsync(undefined, undefined, pause);
606
607
  return true;
607
608
  }
609
+ export function getMoveToLevelRequest(level, transitionTime, executeIfOff) {
610
+ const request = {
611
+ level,
612
+ transitionTime,
613
+ optionsMask: { executeIfOff, coupleColorTempToLevel: false },
614
+ optionsOverride: { executeIfOff, coupleColorTempToLevel: false },
615
+ };
616
+ return request;
617
+ }
618
+ export function getMoveToColorTemperatureRequest(colorTemperatureMireds, transitionTime, executeIfOff) {
619
+ const request = {
620
+ colorTemperatureMireds,
621
+ transitionTime,
622
+ optionsMask: { executeIfOff },
623
+ optionsOverride: { executeIfOff },
624
+ };
625
+ return request;
626
+ }
627
+ export function getMoveToHueRequest(hue, transitionTime, executeIfOff) {
628
+ const request = {
629
+ hue,
630
+ transitionTime,
631
+ direction: ColorControl.Direction.Shortest,
632
+ optionsMask: { executeIfOff },
633
+ optionsOverride: { executeIfOff },
634
+ };
635
+ return request;
636
+ }
637
+ export function getMoveToSaturationRequest(saturation, transitionTime, executeIfOff) {
638
+ const request = {
639
+ saturation,
640
+ transitionTime,
641
+ optionsMask: { executeIfOff },
642
+ optionsOverride: { executeIfOff },
643
+ };
644
+ return request;
645
+ }
646
+ export function getMoveToHueAndSaturationRequest(hue, saturation, transitionTime, executeIfOff) {
647
+ const request = {
648
+ hue,
649
+ saturation,
650
+ transitionTime,
651
+ optionsMask: { executeIfOff },
652
+ optionsOverride: { executeIfOff },
653
+ };
654
+ return request;
655
+ }
656
+ export function getMoveToColorRequest(colorX, colorY, transitionTime, executeIfOff) {
657
+ const request = {
658
+ colorX,
659
+ colorY,
660
+ transitionTime,
661
+ optionsMask: { executeIfOff },
662
+ optionsOverride: { executeIfOff },
663
+ };
664
+ return request;
665
+ }
@@ -1 +1 @@
1
- export { AggregatorEndpoint, ElectricalSensorEndpoint, PowerSourceEndpoint, BridgedNodeEndpoint, RootEndpoint, DeviceEnergyManagementEndpoint, OtaProviderEndpoint, OtaRequestorEndpoint, } from '@matter/node/endpoints';
1
+ export { AggregatorEndpoint, BridgedNodeEndpoint, DeviceEnergyManagementEndpoint, ElectricalSensorEndpoint, OtaProviderEndpoint, OtaRequestorEndpoint, PowerSourceEndpoint, RootEndpoint, } from '@matter/node/endpoints';
@@ -1 +1 @@
1
- export { AggregatorEndpoint, ElectricalSensorEndpoint, PowerSourceEndpoint, BridgedNodeEndpoint, RootEndpoint, DeviceEnergyManagementEndpoint, OtaProviderEndpoint, OtaRequestorEndpoint, } from '@matter/node/endpoints';
1
+ export { AggregatorEndpoint, BridgedNodeEndpoint, DeviceEnergyManagementEndpoint, ElectricalSensorEndpoint, OtaProviderEndpoint, OtaRequestorEndpoint, PowerSourceEndpoint, RootEndpoint, } from '@matter/node/endpoints';
@@ -1,10 +1,10 @@
1
- import EventEmitter from 'node:events';
2
1
  import '@matter/nodejs';
2
+ import EventEmitter from 'node:events';
3
3
  import { Diagnostic, StorageContext, StorageManager, StorageService } from '@matter/general';
4
- import { DeviceCertification, ExposedFabricInformation, MdnsService } from '@matter/protocol';
5
- import { VendorId, DeviceTypeId } from '@matter/types';
6
- import { ServerNode, Endpoint, SessionsBehavior } from '@matter/node';
4
+ import { Endpoint, ServerNode, SessionsBehavior } from '@matter/node';
7
5
  import { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
6
+ import { DeviceCertification, ExposedFabricInformation, MdnsService } from '@matter/protocol';
7
+ import { DeviceTypeId, VendorId } from '@matter/types';
8
8
  import type { ApiMatter, PluginName, SanitizedExposedFabricInformation, SanitizedSession, SharedMatterbridge, WorkerMessage } from '@matterbridge/types';
9
9
  import type { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
10
10
  import { Plugin, PluginManager } from './pluginManager.js';
@@ -1,23 +1,23 @@
1
- import path from 'node:path';
2
- import fs from 'node:fs';
3
- import EventEmitter from 'node:events';
4
- import { AnsiLogger, BLUE, CYAN, db, debugStringify, er, nf, or, zb } from 'node-ansi-logger';
5
- import { NodeStorageManager } from 'node-persist-manager';
6
1
  import '@matter/nodejs';
7
- import { Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, StorageService, UINT32_MAX, UINT16_MAX, Environment, } from '@matter/general';
8
- import { MdnsService } from '@matter/protocol';
9
- import { VendorId, DeviceTypeId } from '@matter/types';
10
- import { ServerNode, Endpoint } from '@matter/node';
11
- import { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
2
+ import EventEmitter from 'node:events';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { Environment, LogFormat as MatterLogFormat, Logger, LogLevel as MatterLogLevel, StorageService, UINT16_MAX, UINT32_MAX, } from '@matter/general';
6
+ import { Endpoint, ServerNode } from '@matter/node';
12
7
  import { BasicInformationServer } from '@matter/node/behaviors/basic-information';
13
8
  import { BridgedDeviceBasicInformationServer } from '@matter/node/behaviors/bridged-device-basic-information';
14
- import { copyDirectory, getIntParameter, getParameter, hasParameter, inspectError, isValidNumber, isValidString, parseVersionString, wait, withTimeout } from '@matterbridge/utils';
15
- import { dev, MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, plg, NODE_STORAGE_DIR, MATTERBRIDGE_LOGGER_FILE } from '@matterbridge/types';
9
+ import { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
10
+ import { MdnsService } from '@matter/protocol';
11
+ import { DeviceTypeId, VendorId } from '@matter/types';
16
12
  import { BroadcastServer } from '@matterbridge/thread';
17
- import { bridge } from './matterbridgeDeviceTypes.js';
13
+ import { dev, MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg } from '@matterbridge/types';
14
+ import { copyDirectory, getIntParameter, getParameter, hasParameter, inspectError, isValidNumber, isValidString, parseVersionString, wait, withTimeout } from '@matterbridge/utils';
15
+ import { AnsiLogger, BLUE, CYAN, db, debugStringify, er, nf, or, zb } from 'node-ansi-logger';
16
+ import { NodeStorageManager } from 'node-persist-manager';
18
17
  import { toBaseDevice } from './deviceManager.js';
19
- import { PluginManager } from './pluginManager.js';
20
18
  import { addVirtualDevice } from './helpers.js';
19
+ import { bridge } from './matterbridgeDeviceTypes.js';
20
+ import { PluginManager } from './pluginManager.js';
21
21
  export class MatterNode extends EventEmitter {
22
22
  matterbridge;
23
23
  pluginName;
@@ -1,17 +1,17 @@
1
- import EventEmitter from 'node:events';
2
- import { AnsiLogger, LogLevel } from 'node-ansi-logger';
3
- import { NodeStorageManager, NodeStorage } from 'node-persist-manager';
4
1
  import '@matter/nodejs';
2
+ import EventEmitter from 'node:events';
5
3
  import { StorageContext, StorageManager, StorageService } from '@matter/general';
6
- import { DeviceCertification } from '@matter/protocol';
7
4
  import { Endpoint, ServerNode } from '@matter/node';
8
- import { DeviceTypeId, VendorId } from '@matter/types/datatype';
9
5
  import { AggregatorEndpoint } from '@matter/node/endpoints';
6
+ import { DeviceCertification } from '@matter/protocol';
7
+ import { DeviceTypeId, VendorId } from '@matter/types/datatype';
10
8
  import type { ApiMatter, MaybePromise, PlatformMatterbridge, SharedMatterbridge, SystemInformation } from '@matterbridge/types';
11
- import { PluginManager } from './pluginManager.js';
9
+ import { AnsiLogger, LogLevel } from 'node-ansi-logger';
10
+ import { NodeStorage, NodeStorageManager } from 'node-persist-manager';
12
11
  import { DeviceManager } from './deviceManager.js';
13
- import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
14
12
  import { Frontend } from './frontend.js';
13
+ import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
14
+ import { PluginManager } from './pluginManager.js';
15
15
  interface MatterbridgeEvents {
16
16
  shutdown: [];
17
17
  restart: [];
@@ -102,6 +102,11 @@ export declare class Matterbridge extends EventEmitter<MatterbridgeEvents> {
102
102
  aggregatorDeviceType: DeviceTypeId;
103
103
  aggregatorSerialNumber: string | undefined;
104
104
  aggregatorUniqueId: string | undefined;
105
+ controllerNode: ServerNode<ServerNode.RootEndpoint> | undefined;
106
+ controllerVendorId: VendorId;
107
+ controllerVendorName: string;
108
+ controllerProductId: number;
109
+ controllerProductName: string;
105
110
  advertisingNodes: Map<string, number>;
106
111
  private readonly server;
107
112
  private readonly verbose;
@@ -1,29 +1,30 @@
1
1
  if (process.argv.includes('--loader') || process.argv.includes('-loader'))
2
2
  console.log('\u001B[32mMatterbridge loaded.\u001B[40;0m');
3
+ import '@matter/nodejs';
4
+ import EventEmitter from 'node:events';
5
+ import fs, { unlinkSync } from 'node:fs';
3
6
  import os from 'node:os';
4
7
  import path from 'node:path';
5
8
  import { fileURLToPath } from 'node:url';
6
- import fs, { unlinkSync } from 'node:fs';
7
- import EventEmitter from 'node:events';
8
9
  import { inspect } from 'node:util';
9
- import { AnsiLogger, UNDERLINE, UNDERLINEOFF, db, debugStringify, BRIGHT, RESET, er, nf, rs, wr, RED, GREEN, zb, CYAN, nt, BLUE, or, } from 'node-ansi-logger';
10
- import { NodeStorageManager } from 'node-persist-manager';
11
- import '@matter/nodejs';
12
- import { Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, UINT32_MAX, UINT16_MAX, Crypto, Environment, StorageService, } from '@matter/general';
13
- import { PaseClient } from '@matter/protocol';
10
+ import { Crypto, Environment, LogFormat as MatterLogFormat, Logger, LogLevel as MatterLogLevel, StorageService, UINT16_MAX, UINT32_MAX, } from '@matter/general';
14
11
  import { Endpoint, ServerNode } from '@matter/node';
15
- import { DeviceTypeId, VendorId } from '@matter/types/datatype';
16
- import { AggregatorEndpoint } from '@matter/node/endpoints';
17
12
  import { BasicInformationServer } from '@matter/node/behaviors/basic-information';
18
- import { copyDirectory, createDirectory, formatBytes, formatPercent, formatUptime, getIntParameter, getParameter, hasParameter, isValidNumber, isValidObject, isValidString, parseVersionString, excludedInterfaceNamePattern, } from '@matterbridge/utils';
19
- import { dev, MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg, typ } from '@matterbridge/types';
13
+ import { AggregatorEndpoint } from '@matter/node/endpoints';
14
+ import { PaseClient } from '@matter/protocol';
15
+ import { DeviceTypeId, VendorId } from '@matter/types/datatype';
20
16
  import { BroadcastServer } from '@matterbridge/thread';
21
- import { PluginManager } from './pluginManager.js';
17
+ import { dev, MATTER_LOGGER_FILE, MATTER_STORAGE_NAME, MATTERBRIDGE_LOGGER_FILE, NODE_STORAGE_DIR, plg, typ } from '@matterbridge/types';
18
+ import { copyDirectory, createDirectory, excludedInterfaceNamePattern, formatBytes, formatPercent, formatUptime, getIntParameter, getParameter, hasParameter, isValidNumber, isValidObject, isValidString, parseVersionString, } from '@matterbridge/utils';
19
+ import { AnsiLogger, BLUE, BRIGHT, CYAN, db, debugStringify, er, GREEN, nf, nt, or, RED, RESET, rs, UNDERLINE, UNDERLINEOFF, wr, zb, } from 'node-ansi-logger';
20
+ import { NodeStorageManager } from 'node-persist-manager';
22
21
  import { DeviceManager } from './deviceManager.js';
23
- import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
24
- import { bridge } from './matterbridgeDeviceTypes.js';
25
22
  import { Frontend } from './frontend.js';
26
23
  import { addVirtualDevice, addVirtualDevices } from './helpers.js';
24
+ import { ManualPairingCodeCodec } from './matter/types.js';
25
+ import { bridge } from './matterbridgeDeviceTypes.js';
26
+ import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
27
+ import { PluginManager } from './pluginManager.js';
27
28
  export class Matterbridge extends EventEmitter {
28
29
  systemInformation = {
29
30
  interfaceName: '',
@@ -121,6 +122,11 @@ export class Matterbridge extends EventEmitter {
121
122
  aggregatorDeviceType = DeviceTypeId(getIntParameter('deviceType') ?? bridge.code);
122
123
  aggregatorSerialNumber = getParameter('serialNumber');
123
124
  aggregatorUniqueId = getParameter('uniqueId');
125
+ controllerNode;
126
+ controllerVendorId = VendorId(getIntParameter('vendorId') ?? 0xfff1);
127
+ controllerVendorName = getParameter('vendorName') ?? 'Matterbridge';
128
+ controllerProductId = getIntParameter('productId') ?? 0x8000;
129
+ controllerProductName = getParameter('productName') ?? 'Matterbridge controller';
124
130
  advertisingNodes = new Map();
125
131
  server;
126
132
  verbose = hasParameter('verbose');
@@ -534,6 +540,7 @@ export class Matterbridge extends EventEmitter {
534
540
  await this.plugins.loadFromStorage();
535
541
  this.devices.logLevel = this.log.logLevel;
536
542
  for (const plugin of this.plugins) {
543
+ this.log.debug(`Parsing plugin ${plg}${plugin.name}${db} from path ${CYAN}${plugin.path}${db} with version ${CYAN}${plugin.version}${db} and type ${CYAN}${plugin.type}${db}.`);
537
544
  if (!fs.existsSync(plugin.path) &&
538
545
  !hasParameter('add') &&
539
546
  !hasParameter('remove') &&
@@ -1121,6 +1128,12 @@ export class Matterbridge extends EventEmitter {
1121
1128
  }
1122
1129
  }
1123
1130
  this.log.notice('Stopped matter server nodes');
1131
+ if (this.controllerNode) {
1132
+ this.log.notice(`Stopping matter controller...`);
1133
+ await this.stopServerNode(this.controllerNode);
1134
+ this.controllerNode = undefined;
1135
+ this.log.notice('Stopped matter controller');
1136
+ }
1124
1137
  if (message === 'shutting down with reset...') {
1125
1138
  this.log.info('Resetting Matterbridge commissioning information...');
1126
1139
  await this.matterStorageManager?.createContext('events')?.clearAll();
@@ -1455,6 +1468,95 @@ export class Matterbridge extends EventEmitter {
1455
1468
  }, Number(process.env['MATTERBRIDGE_START_MATTER_INTERVAL_MS']) || this.startMatterIntervalMs);
1456
1469
  }
1457
1470
  async startController() {
1471
+ if (!this.matterStorageManager) {
1472
+ this.log.error('No storage manager initialized');
1473
+ await this.cleanup('No storage manager initialized');
1474
+ return;
1475
+ }
1476
+ if (!this.matterStorageService) {
1477
+ this.log.error('No storage service initialized');
1478
+ await this.cleanup('No storage service initialized');
1479
+ return;
1480
+ }
1481
+ this.matterStorageManager = await this.matterStorageService.open('MatterbridgeController');
1482
+ this.log.info('Matter node storage manager "MatterbridgeController" created');
1483
+ this.log.info('Creating context controllerContext...');
1484
+ this.controllerContext = this.matterStorageManager.createContext('controllerContext');
1485
+ if (!this.controllerContext) {
1486
+ this.log.error('No storage context controllerContext initialized');
1487
+ await this.cleanup('No storage context controllerContext initialized');
1488
+ return;
1489
+ }
1490
+ const { randomBytes } = await import('node:crypto');
1491
+ const storeId = 'MatterbridgeController';
1492
+ const random = randomBytes(8).toString('hex');
1493
+ await this.controllerContext.set('storeId', storeId);
1494
+ await this.controllerContext.set('vendorId', this.controllerVendorId);
1495
+ await this.controllerContext.set('vendorName', this.controllerVendorName.slice(0, 32));
1496
+ await this.controllerContext.set('productId', this.controllerProductId);
1497
+ await this.controllerContext.set('productName', this.controllerProductName.slice(0, 32));
1498
+ await this.controllerContext.set('productLabel', this.controllerProductName.slice(0, 32));
1499
+ await this.controllerContext.set('nodeLabel', storeId.slice(0, 32));
1500
+ await this.controllerContext.set('serialNumber', await this.controllerContext.get('serialNumber', 'SN' + random));
1501
+ await this.controllerContext.set('uniqueId', await this.controllerContext.get('uniqueId', 'UI' + random));
1502
+ await this.controllerContext.set('softwareVersion', isValidNumber(parseVersionString(this.matterbridgeVersion), 0, UINT32_MAX) ? parseVersionString(this.matterbridgeVersion) : 1);
1503
+ await this.controllerContext.set('softwareVersionString', isValidString(this.matterbridgeVersion, 5, 64) ? this.matterbridgeVersion : '1.0.0');
1504
+ await this.controllerContext.set('hardwareVersion', isValidNumber(parseVersionString(this.systemInformation.osRelease), 0, UINT16_MAX) ? parseVersionString(this.systemInformation.osRelease) : 1);
1505
+ await this.controllerContext.set('hardwareVersionString', isValidString(this.systemInformation.osRelease, 5, 64) ? this.systemInformation.osRelease : '1.0.0');
1506
+ this.log.info('Creating matter commissioning controller...');
1507
+ this.controllerNode = await ServerNode.create({
1508
+ id: storeId,
1509
+ environment: this.environment,
1510
+ network: {
1511
+ listeningAddressIpv4: this.ipv4Address,
1512
+ listeningAddressIpv6: this.ipv6Address,
1513
+ port: this.port,
1514
+ },
1515
+ basicInformation: {
1516
+ nodeLabel: await this.controllerContext.get('nodeLabel'),
1517
+ vendorId: VendorId(await this.controllerContext.get('vendorId')),
1518
+ vendorName: await this.controllerContext.get('vendorName'),
1519
+ productId: await this.controllerContext.get('productId'),
1520
+ productName: await this.controllerContext.get('productName'),
1521
+ productLabel: await this.controllerContext.get('productLabel'),
1522
+ serialNumber: await this.controllerContext.get('serialNumber'),
1523
+ uniqueId: await this.controllerContext.get('uniqueId'),
1524
+ softwareVersion: await this.controllerContext.get('softwareVersion'),
1525
+ softwareVersionString: await this.controllerContext.get('softwareVersionString'),
1526
+ hardwareVersion: await this.controllerContext.get('hardwareVersion'),
1527
+ hardwareVersionString: await this.controllerContext.get('hardwareVersionString'),
1528
+ reachable: true,
1529
+ },
1530
+ });
1531
+ this.log.info(`Starting matter commissioning controller: ${this.controllerNode.peers.size} peer nodes...`);
1532
+ if (hasParameter('pair')) {
1533
+ let options;
1534
+ if (hasParameter('pairingcode')) {
1535
+ const pairingCode = getParameter('pairingcode');
1536
+ this.log.info(`Pairing device with pairingcode: ${pairingCode}`);
1537
+ const pairingData = ManualPairingCodeCodec.decode(pairingCode);
1538
+ this.log.info(`Data extracted from pairing code: ${Logger.toJSON(pairingData)}`);
1539
+ options = { id: 'device', pairingCode };
1540
+ }
1541
+ else {
1542
+ const discriminator = getIntParameter('discriminator');
1543
+ const passcode = getIntParameter('passcode') ?? 0;
1544
+ options = { id: 'device', discriminator, passcode };
1545
+ }
1546
+ this.log.info('Commissioning with options:', options);
1547
+ const nodeId = this.controllerNode.peers.commission(options);
1548
+ this.log.info(`Commissioning successfully done with nodeId: ${nodeId}`);
1549
+ }
1550
+ if (hasParameter('unpairall')) {
1551
+ this.log.info('Matter commissioning controller decommissioning all nodes...');
1552
+ const nodeIds = this.controllerNode.peers;
1553
+ for (const nodeId of nodeIds) {
1554
+ this.log.info('Matter commissioning controller decommissioning node:', nodeId.id);
1555
+ await nodeId.decommission();
1556
+ }
1557
+ this.log.info('Matter commissioning controller decommissioned all nodes');
1558
+ return;
1559
+ }
1458
1560
  }
1459
1561
  async startMatterStorage() {
1460
1562
  this.log.info(`Starting matter node storage...`);
@@ -1651,7 +1753,7 @@ export class Matterbridge extends EventEmitter {
1651
1753
  id: serverNode.id,
1652
1754
  online: serverNode.lifecycle.isOnline,
1653
1755
  commissioned: serverNode.state.commissioning.commissioned,
1654
- advertising: advertiseTime > Date.now() - 15 * 60 * 1000,
1756
+ advertising: true,
1655
1757
  advertiseTime,
1656
1758
  windowStatus: serverNode.state.administratorCommissioning.windowStatus,
1657
1759
  qrPairingCode: serverNode.state.commissioning.pairingCodes.qrPairingCode,
@@ -1,5 +1,5 @@
1
- import { AnsiLogger } from 'node-ansi-logger';
2
1
  import type { PlatformConfig, PlatformMatterbridge } from '@matterbridge/types';
2
+ import { AnsiLogger } from 'node-ansi-logger';
3
3
  import { MatterbridgePlatform } from './matterbridgePlatform.js';
4
4
  export declare function isMatterbridgeAccessoryPlatform(value: unknown): value is MatterbridgeAccessoryPlatform;
5
5
  export declare class MatterbridgeAccessoryPlatform extends MatterbridgePlatform {
@@ -1,41 +1,41 @@
1
- import { AnsiLogger } from 'node-ansi-logger';
2
1
  import { MaybePromise, NamedHandler } from '@matter/general';
3
2
  import { Behavior } from '@matter/node';
3
+ import { ActivatedCarbonFilterMonitoringServer } from '@matter/node/behaviors/activated-carbon-filter-monitoring';
4
+ import { BooleanStateConfigurationServer } from '@matter/node/behaviors/boolean-state-configuration';
5
+ import { ColorControlServer } from '@matter/node/behaviors/color-control';
6
+ import { DeviceEnergyManagementServer } from '@matter/node/behaviors/device-energy-management';
7
+ import { DeviceEnergyManagementModeServer } from '@matter/node/behaviors/device-energy-management-mode';
8
+ import { DoorLockServer } from '@matter/node/behaviors/door-lock';
9
+ import { FanControlServer } from '@matter/node/behaviors/fan-control';
10
+ import { HepaFilterMonitoringServer } from '@matter/node/behaviors/hepa-filter-monitoring';
11
+ import { IdentifyServer } from '@matter/node/behaviors/identify';
12
+ import { LevelControlServer } from '@matter/node/behaviors/level-control';
13
+ import { ModeSelectServer } from '@matter/node/behaviors/mode-select';
14
+ import { OnOffServer } from '@matter/node/behaviors/on-off';
15
+ import { OperationalStateServer } from '@matter/node/behaviors/operational-state';
16
+ import { PowerSourceServer } from '@matter/node/behaviors/power-source';
17
+ import { ServiceAreaServer } from '@matter/node/behaviors/service-area';
18
+ import { SmokeCoAlarmServer } from '@matter/node/behaviors/smoke-co-alarm';
19
+ import { SwitchServer } from '@matter/node/behaviors/switch';
20
+ import { ThermostatServer } from '@matter/node/behaviors/thermostat';
21
+ import { ValveConfigurationAndControlServer } from '@matter/node/behaviors/valve-configuration-and-control';
22
+ import { MovementDirection, MovementType, WindowCoveringServer } from '@matter/node/behaviors/window-covering';
4
23
  import { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
5
24
  import { ColorControl } from '@matter/types/clusters/color-control';
25
+ import { DeviceEnergyManagement } from '@matter/types/clusters/device-energy-management';
6
26
  import { FanControl } from '@matter/types/clusters/fan-control';
7
27
  import { Identify } from '@matter/types/clusters/identify';
8
28
  import { LevelControl } from '@matter/types/clusters/level-control';
9
- import { WindowCovering } from '@matter/types/clusters/window-covering';
10
- import { Thermostat } from '@matter/types/clusters/thermostat';
11
- import { ValveConfigurationAndControl } from '@matter/types/clusters/valve-configuration-and-control';
29
+ import { ModeBase } from '@matter/types/clusters/mode-base';
12
30
  import { ModeSelect } from '@matter/types/clusters/mode-select';
13
- import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
14
31
  import { OperationalState } from '@matter/types/clusters/operational-state';
15
- import { ModeBase } from '@matter/types/clusters/mode-base';
16
- import { ServiceArea } from '@matter/types/clusters/service-area';
17
- import { DeviceEnergyManagement } from '@matter/types/clusters/device-energy-management';
18
32
  import { ResourceMonitoring } from '@matter/types/clusters/resource-monitoring';
19
- import { IdentifyServer } from '@matter/node/behaviors/identify';
20
- import { OnOffServer } from '@matter/node/behaviors/on-off';
21
- import { LevelControlServer } from '@matter/node/behaviors/level-control';
22
- import { ColorControlServer } from '@matter/node/behaviors/color-control';
23
- import { MovementDirection, MovementType, WindowCoveringServer } from '@matter/node/behaviors/window-covering';
24
- import { BooleanStateConfigurationServer } from '@matter/node/behaviors/boolean-state-configuration';
25
- import { DoorLockServer } from '@matter/node/behaviors/door-lock';
26
- import { FanControlServer } from '@matter/node/behaviors/fan-control';
27
- import { ThermostatServer } from '@matter/node/behaviors/thermostat';
28
- import { ValveConfigurationAndControlServer } from '@matter/node/behaviors/valve-configuration-and-control';
29
- import { ModeSelectServer } from '@matter/node/behaviors/mode-select';
30
- import { SmokeCoAlarmServer } from '@matter/node/behaviors/smoke-co-alarm';
31
- import { SwitchServer } from '@matter/node/behaviors/switch';
32
- import { OperationalStateServer } from '@matter/node/behaviors/operational-state';
33
- import { ServiceAreaServer } from '@matter/node/behaviors/service-area';
34
- import { DeviceEnergyManagementServer } from '@matter/node/behaviors/device-energy-management';
35
- import { DeviceEnergyManagementModeServer } from '@matter/node/behaviors/device-energy-management-mode';
36
- import { HepaFilterMonitoringServer } from '@matter/node/behaviors/hepa-filter-monitoring';
37
- import { ActivatedCarbonFilterMonitoringServer } from '@matter/node/behaviors/activated-carbon-filter-monitoring';
38
- import { PowerSourceServer } from '@matter/node/behaviors/power-source';
33
+ import { ServiceArea } from '@matter/types/clusters/service-area';
34
+ import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
35
+ import { Thermostat } from '@matter/types/clusters/thermostat';
36
+ import { ValveConfigurationAndControl } from '@matter/types/clusters/valve-configuration-and-control';
37
+ import { WindowCovering } from '@matter/types/clusters/window-covering';
38
+ import { AnsiLogger } from 'node-ansi-logger';
39
39
  import { MatterbridgeEndpointCommands } from './matterbridgeEndpointTypes.js';
40
40
  export declare class MatterbridgeServer extends Behavior {
41
41
  static readonly id = "matterbridge";
@@ -1,37 +1,37 @@
1
1
  import { Behavior } from '@matter/node';
2
- import { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
3
- import { ColorControl } from '@matter/types/clusters/color-control';
4
- import { FanControl } from '@matter/types/clusters/fan-control';
5
- import { WindowCovering } from '@matter/types/clusters/window-covering';
6
- import { Thermostat } from '@matter/types/clusters/thermostat';
7
- import { ValveConfigurationAndControl } from '@matter/types/clusters/valve-configuration-and-control';
8
- import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
9
- import { OperationalState } from '@matter/types/clusters/operational-state';
10
- import { ModeBase } from '@matter/types/clusters/mode-base';
11
- import { ServiceArea } from '@matter/types/clusters/service-area';
12
- import { DeviceEnergyManagement } from '@matter/types/clusters/device-energy-management';
13
- import { ResourceMonitoring } from '@matter/types/clusters/resource-monitoring';
14
- import { DeviceEnergyManagementMode } from '@matter/types/clusters/device-energy-management-mode';
15
- import { IdentifyServer } from '@matter/node/behaviors/identify';
16
- import { OnOffServer } from '@matter/node/behaviors/on-off';
17
- import { LevelControlServer } from '@matter/node/behaviors/level-control';
18
- import { ColorControlServer } from '@matter/node/behaviors/color-control';
19
- import { WindowCoveringServer } from '@matter/node/behaviors/window-covering';
2
+ import { ActivatedCarbonFilterMonitoringServer } from '@matter/node/behaviors/activated-carbon-filter-monitoring';
20
3
  import { BooleanStateConfigurationServer } from '@matter/node/behaviors/boolean-state-configuration';
4
+ import { ColorControlServer } from '@matter/node/behaviors/color-control';
5
+ import { DeviceEnergyManagementServer } from '@matter/node/behaviors/device-energy-management';
6
+ import { DeviceEnergyManagementModeServer } from '@matter/node/behaviors/device-energy-management-mode';
21
7
  import { DoorLockServer } from '@matter/node/behaviors/door-lock';
22
8
  import { FanControlServer } from '@matter/node/behaviors/fan-control';
23
- import { ThermostatServer } from '@matter/node/behaviors/thermostat';
24
- import { ValveConfigurationAndControlServer } from '@matter/node/behaviors/valve-configuration-and-control';
9
+ import { HepaFilterMonitoringServer } from '@matter/node/behaviors/hepa-filter-monitoring';
10
+ import { IdentifyServer } from '@matter/node/behaviors/identify';
11
+ import { LevelControlServer } from '@matter/node/behaviors/level-control';
25
12
  import { ModeSelectServer } from '@matter/node/behaviors/mode-select';
26
- import { SmokeCoAlarmServer } from '@matter/node/behaviors/smoke-co-alarm';
27
- import { SwitchServer } from '@matter/node/behaviors/switch';
13
+ import { OnOffServer } from '@matter/node/behaviors/on-off';
28
14
  import { OperationalStateServer } from '@matter/node/behaviors/operational-state';
29
- import { ServiceAreaServer } from '@matter/node/behaviors/service-area';
30
- import { DeviceEnergyManagementServer } from '@matter/node/behaviors/device-energy-management';
31
- import { DeviceEnergyManagementModeServer } from '@matter/node/behaviors/device-energy-management-mode';
32
- import { HepaFilterMonitoringServer } from '@matter/node/behaviors/hepa-filter-monitoring';
33
- import { ActivatedCarbonFilterMonitoringServer } from '@matter/node/behaviors/activated-carbon-filter-monitoring';
34
15
  import { PowerSourceServer } from '@matter/node/behaviors/power-source';
16
+ import { ServiceAreaServer } from '@matter/node/behaviors/service-area';
17
+ import { SmokeCoAlarmServer } from '@matter/node/behaviors/smoke-co-alarm';
18
+ import { SwitchServer } from '@matter/node/behaviors/switch';
19
+ import { ThermostatServer } from '@matter/node/behaviors/thermostat';
20
+ import { ValveConfigurationAndControlServer } from '@matter/node/behaviors/valve-configuration-and-control';
21
+ import { WindowCoveringServer } from '@matter/node/behaviors/window-covering';
22
+ import { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
23
+ import { ColorControl } from '@matter/types/clusters/color-control';
24
+ import { DeviceEnergyManagement } from '@matter/types/clusters/device-energy-management';
25
+ import { DeviceEnergyManagementMode } from '@matter/types/clusters/device-energy-management-mode';
26
+ import { FanControl } from '@matter/types/clusters/fan-control';
27
+ import { ModeBase } from '@matter/types/clusters/mode-base';
28
+ import { OperationalState } from '@matter/types/clusters/operational-state';
29
+ import { ResourceMonitoring } from '@matter/types/clusters/resource-monitoring';
30
+ import { ServiceArea } from '@matter/types/clusters/service-area';
31
+ import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
32
+ import { Thermostat } from '@matter/types/clusters/thermostat';
33
+ import { ValveConfigurationAndControl } from '@matter/types/clusters/valve-configuration-and-control';
34
+ import { WindowCovering } from '@matter/types/clusters/window-covering';
35
35
  export class MatterbridgeServer extends Behavior {
36
36
  static id = 'matterbridge';
37
37
  initialize() {
@@ -1,6 +1,5 @@
1
1
  if (process.argv.includes('--loader') || process.argv.includes('-loader'))
2
2
  console.log('\u001B[32mMatterbridgeDeviceTypes loaded.\u001B[40;0m');
3
- import { DeviceTypeId } from '@matter/types/datatype';
4
3
  import { AccountLogin } from '@matter/types/clusters/account-login';
5
4
  import { Actions } from '@matter/types/clusters/actions';
6
5
  import { ActivatedCarbonFilterMonitoring } from '@matter/types/clusters/activated-carbon-filter-monitoring';
@@ -71,6 +70,7 @@ import { RelativeHumidityMeasurement } from '@matter/types/clusters/relative-hum
71
70
  import { RvcCleanMode } from '@matter/types/clusters/rvc-clean-mode';
72
71
  import { RvcOperationalState } from '@matter/types/clusters/rvc-operational-state';
73
72
  import { RvcRunMode } from '@matter/types/clusters/rvc-run-mode';
73
+ import { ScenesManagement } from '@matter/types/clusters/scenes-management';
74
74
  import { ServiceArea } from '@matter/types/clusters/service-area';
75
75
  import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
76
76
  import { Switch } from '@matter/types/clusters/switch';
@@ -85,7 +85,7 @@ import { WakeOnLan } from '@matter/types/clusters/wake-on-lan';
85
85
  import { WaterHeaterManagement } from '@matter/types/clusters/water-heater-management';
86
86
  import { WaterHeaterMode } from '@matter/types/clusters/water-heater-mode';
87
87
  import { WindowCovering } from '@matter/types/clusters/window-covering';
88
- import { ScenesManagement } from '@matter/types/clusters/scenes-management';
88
+ import { DeviceTypeId } from '@matter/types/datatype';
89
89
  export var DeviceClasses;
90
90
  (function (DeviceClasses) {
91
91
  DeviceClasses["Node"] = "Node";
@@ -1,5 +1,5 @@
1
- import { AnsiLogger } from 'node-ansi-logger';
2
1
  import type { PlatformConfig, PlatformMatterbridge } from '@matterbridge/types';
2
+ import { AnsiLogger } from 'node-ansi-logger';
3
3
  import { MatterbridgePlatform } from './matterbridgePlatform.js';
4
4
  export declare function isMatterbridgeDynamicPlatform(value: unknown): value is MatterbridgeDynamicPlatform;
5
5
  export declare class MatterbridgeDynamicPlatform extends MatterbridgePlatform {