matterbridge 1.6.6 → 1.6.7-dev.2

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 (102) hide show
  1. package/CHANGELOG.md +22 -4
  2. package/README.md +5 -3
  3. package/dist/cli.js +0 -26
  4. package/dist/cluster/export.js +0 -2
  5. package/dist/defaultConfigSchema.js +0 -23
  6. package/dist/deviceManager.js +1 -26
  7. package/dist/index.js +0 -30
  8. package/dist/logger/export.js +0 -1
  9. package/dist/matter/export.js +1 -1
  10. package/dist/matterbridge.js +66 -706
  11. package/dist/matterbridgeAccessoryPlatform.js +0 -33
  12. package/dist/matterbridgeBehaviors.js +1 -29
  13. package/dist/matterbridgeDevice.js +11 -947
  14. package/dist/matterbridgeDeviceTypes.js +12 -59
  15. package/dist/matterbridgeDynamicPlatform.js +0 -33
  16. package/dist/matterbridgeEdge.js +147 -574
  17. package/dist/matterbridgeEndpoint.js +13 -1061
  18. package/dist/matterbridgePlatform.js +5 -94
  19. package/dist/matterbridgeTypes.js +0 -24
  20. package/dist/matterbridgeWebsocket.js +0 -45
  21. package/dist/pluginManager.js +11 -240
  22. package/dist/storage/export.js +0 -1
  23. package/dist/utils/colorUtils.js +2 -205
  24. package/dist/utils/export.js +0 -1
  25. package/dist/utils/utils.js +7 -252
  26. package/frontend/build/asset-manifest.json +3 -3
  27. package/frontend/build/index.html +1 -1
  28. package/frontend/build/static/js/{main.a742de4e.js → main.4dd7e165.js} +3 -3
  29. package/frontend/build/static/js/main.4dd7e165.js.map +1 -0
  30. package/npm-shrinkwrap.json +20 -16
  31. package/package.json +2 -3
  32. package/dist/cli.d.ts +0 -25
  33. package/dist/cli.d.ts.map +0 -1
  34. package/dist/cli.js.map +0 -1
  35. package/dist/cluster/export.d.ts +0 -2
  36. package/dist/cluster/export.d.ts.map +0 -1
  37. package/dist/cluster/export.js.map +0 -1
  38. package/dist/defaultConfigSchema.d.ts +0 -27
  39. package/dist/defaultConfigSchema.d.ts.map +0 -1
  40. package/dist/defaultConfigSchema.js.map +0 -1
  41. package/dist/deviceManager.d.ts +0 -46
  42. package/dist/deviceManager.d.ts.map +0 -1
  43. package/dist/deviceManager.js.map +0 -1
  44. package/dist/index.d.ts +0 -40
  45. package/dist/index.d.ts.map +0 -1
  46. package/dist/index.js.map +0 -1
  47. package/dist/logger/export.d.ts +0 -2
  48. package/dist/logger/export.d.ts.map +0 -1
  49. package/dist/logger/export.js.map +0 -1
  50. package/dist/matter/export.d.ts +0 -5
  51. package/dist/matter/export.d.ts.map +0 -1
  52. package/dist/matter/export.js.map +0 -1
  53. package/dist/matterbridge.d.ts +0 -466
  54. package/dist/matterbridge.d.ts.map +0 -1
  55. package/dist/matterbridge.js.map +0 -1
  56. package/dist/matterbridgeAccessoryPlatform.d.ts +0 -39
  57. package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
  58. package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
  59. package/dist/matterbridgeBehaviors.d.ts +0 -942
  60. package/dist/matterbridgeBehaviors.d.ts.map +0 -1
  61. package/dist/matterbridgeBehaviors.js.map +0 -1
  62. package/dist/matterbridgeDevice.d.ts +0 -6674
  63. package/dist/matterbridgeDevice.d.ts.map +0 -1
  64. package/dist/matterbridgeDevice.js.map +0 -1
  65. package/dist/matterbridgeDeviceTypes.d.ts +0 -82
  66. package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
  67. package/dist/matterbridgeDeviceTypes.js.map +0 -1
  68. package/dist/matterbridgeDynamicPlatform.d.ts +0 -39
  69. package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
  70. package/dist/matterbridgeDynamicPlatform.js.map +0 -1
  71. package/dist/matterbridgeEdge.d.ts +0 -89
  72. package/dist/matterbridgeEdge.d.ts.map +0 -1
  73. package/dist/matterbridgeEdge.js.map +0 -1
  74. package/dist/matterbridgeEndpoint.d.ts +0 -9774
  75. package/dist/matterbridgeEndpoint.d.ts.map +0 -1
  76. package/dist/matterbridgeEndpoint.js.map +0 -1
  77. package/dist/matterbridgePlatform.d.ts +0 -114
  78. package/dist/matterbridgePlatform.d.ts.map +0 -1
  79. package/dist/matterbridgePlatform.js.map +0 -1
  80. package/dist/matterbridgeTypes.d.ts +0 -161
  81. package/dist/matterbridgeTypes.d.ts.map +0 -1
  82. package/dist/matterbridgeTypes.js.map +0 -1
  83. package/dist/matterbridgeWebsocket.d.ts +0 -49
  84. package/dist/matterbridgeWebsocket.d.ts.map +0 -1
  85. package/dist/matterbridgeWebsocket.js.map +0 -1
  86. package/dist/pluginManager.d.ts +0 -238
  87. package/dist/pluginManager.d.ts.map +0 -1
  88. package/dist/pluginManager.js.map +0 -1
  89. package/dist/storage/export.d.ts +0 -2
  90. package/dist/storage/export.d.ts.map +0 -1
  91. package/dist/storage/export.js.map +0 -1
  92. package/dist/utils/colorUtils.d.ts +0 -61
  93. package/dist/utils/colorUtils.d.ts.map +0 -1
  94. package/dist/utils/colorUtils.js.map +0 -1
  95. package/dist/utils/export.d.ts +0 -3
  96. package/dist/utils/export.d.ts.map +0 -1
  97. package/dist/utils/export.js.map +0 -1
  98. package/dist/utils/utils.d.ts +0 -221
  99. package/dist/utils/utils.d.ts.map +0 -1
  100. package/dist/utils/utils.js.map +0 -1
  101. package/frontend/build/static/js/main.a742de4e.js.map +0 -1
  102. /package/frontend/build/static/js/{main.a742de4e.js.LICENSE.txt → main.4dd7e165.js.LICENSE.txt} +0 -0
@@ -1,61 +1,25 @@
1
- /* eslint-disable no-console */
2
- /**
3
- * This file contains the class MatterbridgeEdge that extends the Matterbridge class.
4
- *
5
- * @file matterbridgeEdge.ts
6
- * @author Luca Liguori
7
- * @date 2024-10-01
8
- * @version 1.0.0
9
- *
10
- * Copyright 2024, 2025, 2026 Luca Liguori.
11
- *
12
- * Licensed under the Apache License, Version 2.0 (the "License");
13
- * you may not use this file except in compliance with the License.
14
- * You may obtain a copy of the License at
15
- *
16
- * http://www.apache.org/licenses/LICENSE-2.0
17
- *
18
- * Unless required by applicable law or agreed to in writing, software
19
- * distributed under the License is distributed on an "AS IS" BASIS,
20
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
- * See the License for the specific language governing permissions and
22
- * limitations under the License. *
23
- */
24
- /* eslint-disable @typescript-eslint/no-unused-vars */
25
- // Node.js modules
26
1
  import path from 'path';
27
2
  import os from 'os';
28
3
  import { randomBytes } from 'crypto';
29
- // NodeStorage and AnsiLogger modules
30
- import { rs, GREEN, debugStringify, er, zb, nf } from 'node-ansi-logger';
31
- // Matterbridge
4
+ import { rs, GREEN, debugStringify, er, zb, nf, db } from 'node-ansi-logger';
32
5
  import { Matterbridge } from './matterbridge.js';
33
6
  import { bridge } from './matterbridgeDeviceTypes.js';
34
7
  import { dev, plg } from './matterbridgeTypes.js';
35
8
  import { copyDirectory, getParameter, hasParameter } from './utils/utils.js';
36
- // @matter
37
9
  import { DeviceTypeId, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, VendorId, EndpointServer } from '@matter/main';
38
10
  import { ServerNode, Endpoint as EndpointNode, Environment, StorageService } from '@matter/main';
39
11
  import { BasicInformationCluster } from '@matter/main/clusters';
40
- import { FabricAction, MdnsService } from '@matter/main/protocol';
12
+ import { FabricAction, MdnsService, PaseClient } from '@matter/main/protocol';
41
13
  import { GenericSwitchDevice } from '@matter/main/devices';
42
14
  import { AggregatorEndpoint } from '@matter/main/endpoints';
43
15
  import { BridgedDeviceBasicInformationServer, SwitchServer } from '@matter/main/behaviors';
44
16
  import { Device, logEndpoint } from '@project-chip/matter.js/device';
45
- /**
46
- * Represents the MatterbridgeEdge application.
47
- */
48
17
  export class MatterbridgeEdge extends Matterbridge {
49
18
  static instance;
50
- // Matter environment
51
19
  environment = Environment.default;
52
- // Matter storage
53
20
  matterStorageService;
54
- // Mapping of CommissioningServer to ServerNode
55
21
  csToServerNode = new Map();
56
- // Mapping of Aggregator to AggregatorEndpoint
57
22
  agToAggregatorEndpoint = new Map();
58
- // Mapping of sessions
59
23
  activeSessions = new Map();
60
24
  constructor() {
61
25
  super();
@@ -73,28 +37,24 @@ export class MatterbridgeEdge extends Matterbridge {
73
37
  async initialize() {
74
38
  if (hasParameter('debug'))
75
39
  console.log('Initializing MatterbridgeEdge...');
76
- // Set the matterbridge directory
77
40
  this.homeDirectory = getParameter('homedir') ?? os.homedir();
78
41
  this.matterbridgeDirectory = path.join(this.homeDirectory, '.matterbridge');
79
42
  this.matterStorageName = 'matterstorage' + (getParameter('profile') ? '.' + getParameter('profile') : '');
80
- // Setup matter environment
81
43
  this.environment.vars.set('log.level', MatterLogLevel.INFO);
82
44
  this.environment.vars.set('log.format', MatterLogFormat.ANSI);
83
45
  this.environment.vars.set('path.root', path.join(this.matterbridgeDirectory, this.matterStorageName));
84
46
  this.environment.vars.set('runtime.signals', false);
85
47
  this.environment.vars.set('runtime.exitcode', false);
86
- // Initialize the base Matterbridge class
48
+ this.port = 5540;
49
+ this.passcode = PaseClient.generateRandomPasscode();
50
+ this.discriminator = PaseClient.generateRandomDiscriminator();
51
+ if (hasParameter('debug'))
52
+ console.log(`Initializing server node for Matterbridge... on port ${this.port} with passcode ${this.passcode} and discriminator ${this.discriminator}`);
87
53
  await super.initialize();
88
- // Setup Matter mdnsInterface
89
54
  if (this.mdnsInterface)
90
55
  this.environment.vars.set('mdns.networkInterface', this.mdnsInterface);
91
- // Setup Matter commissioning server
92
- // this.port = 5540;
93
- // this.passcode = PaseClient.generateRandomPasscode();
94
- // this.discriminator = PaseClient.generateRandomDiscriminator();
95
56
  }
96
57
  async startMatterStorage(storageType, storageName) {
97
- // Setup Matter storage
98
58
  this.log.info(`Starting matter node storage...`);
99
59
  this.matterStorageService = this.environment.get(StorageService);
100
60
  this.log.info(`Matter node storage service created: ${this.matterStorageService.location}`);
@@ -102,7 +62,6 @@ export class MatterbridgeEdge extends Matterbridge {
102
62
  this.log.info('Matter node storage manager "Matterbridge" created');
103
63
  this.matterbridgeContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', bridge.code, this.aggregatorVendorId, 'Matterbridge', this.aggregatorProductId, 'Matterbridge aggregator');
104
64
  this.log.info('Matter node storage started');
105
- // Backup matter storage since it is created/opened correctly
106
65
  await this.backupMatterStorage(path.join(this.matterbridgeDirectory, this.matterStorageName), path.join(this.matterbridgeDirectory, this.matterStorageName + '.backup'));
107
66
  }
108
67
  async backupMatterStorage(storageName, backupName) {
@@ -118,61 +77,6 @@ export class MatterbridgeEdge extends Matterbridge {
118
77
  this.matterbridgeContext = undefined;
119
78
  this.log.info('Matter node storage closed');
120
79
  }
121
- createMatterServer(storageManager) {
122
- if (hasParameter('debug'))
123
- this.log.warn('createMatterServer() => mock matterServer');
124
- const matterServer = {
125
- addCommissioningServer: (commissioningServer, nodeOptions) => {
126
- if (hasParameter('debug'))
127
- this.log.warn('MatterServer.addCommissioningServer() => do nothing');
128
- },
129
- };
130
- return matterServer;
131
- }
132
- async startMatterServer() {
133
- if (hasParameter('debug'))
134
- this.log.warn('createMatterServer() => do nothing');
135
- }
136
- async stopMatterServer() {
137
- this.log.info(`Stopping matter server nodes in ${this.bridgeMode} mode...`);
138
- if (this.bridgeMode === 'bridge') {
139
- const serverNode = this.csToServerNode.get('Matterbridge')?.serverNode;
140
- if (serverNode) {
141
- await this.stopServerNode(serverNode);
142
- this.log.info(`Stopped matter server node Matterbridge`);
143
- }
144
- }
145
- if (this.bridgeMode === 'childbridge') {
146
- this.plugins.forEach(async (plugin) => {
147
- const serverNode = this.csToServerNode.get(plugin.name)?.serverNode;
148
- if (serverNode) {
149
- await this.stopServerNode(serverNode);
150
- this.log.info(`Stopped matter server node ${plugin.name}`);
151
- }
152
- });
153
- }
154
- this.log.info('Stopped matter server nodes');
155
- await this.environment.get(MdnsService)[Symbol.asyncDispose]();
156
- this.log.info('Stopped MdnsService');
157
- }
158
- /**
159
- * Creates a server node storage context.
160
- *
161
- * @param pluginName - The name of the plugin.
162
- * @param deviceName - The name of the device.
163
- * @param deviceType - The deviceType of the device.
164
- * @param vendorId - The vendor ID.
165
- * @param vendorName - The vendor name.
166
- * @param productId - The product ID.
167
- * @param productName - The product name.
168
- * @param serialNumber - The serial number of the device (optional).
169
- * @param uniqueId - The unique ID of the device (optional).
170
- * @param softwareVersion - The software version of the device (optional).
171
- * @param softwareVersionString - The software version string of the device (optional).
172
- * @param hardwareVersion - The hardware version of the device (optional).
173
- * @param hardwareVersionString - The hardware version string of the device (optional).
174
- * @returns The storage context for the commissioning server.
175
- */
176
80
  async createServerNodeContext(pluginName, deviceName, deviceType, vendorId, vendorName, productId, productName, serialNumber) {
177
81
  if (!this.matterStorageService)
178
82
  throw new Error('No storage service initialized');
@@ -207,40 +111,28 @@ export class MatterbridgeEdge extends Matterbridge {
207
111
  }
208
112
  async createServerNode(storageContext, port = 5540, passcode = 20242025, discriminator = 3850) {
209
113
  const storeId = await storageContext.get('storeId');
210
- this.log.info(`Creating server node for ${storeId}...`);
114
+ this.log.info(`Creating server node for ${storeId} on port ${port} with passcode ${passcode} and discriminator ${discriminator}...`);
211
115
  this.log.debug(`- deviceName: ${await storageContext.get('deviceName')}`);
212
116
  this.log.debug(`- deviceType: ${await storageContext.get('deviceType')}(0x${(await storageContext.get('deviceType'))?.toString(16).padStart(4, '0')})`);
213
117
  this.log.debug(`- serialNumber: ${await storageContext.get('serialNumber')}`);
214
118
  this.log.debug(`- uniqueId: ${await storageContext.get('uniqueId')}`);
215
119
  this.log.debug(`- softwareVersion: ${await storageContext.get('softwareVersion')} softwareVersionString: ${await storageContext.get('softwareVersionString')}`);
216
120
  this.log.debug(`- hardwareVersion: ${await storageContext.get('hardwareVersion')} hardwareVersionString: ${await storageContext.get('hardwareVersionString')}`);
217
- /**
218
- * Create a Matter ServerNode, which contains the Root Endpoint and all relevant data and configuration
219
- */
220
121
  const serverNode = await ServerNode.create({
221
- // Required: Give the Node a unique ID which is used to store the state of this node
222
122
  id: storeId,
223
- // Provide Network relevant configuration like the port
224
- // Optional when operating only one device on a host, Default port is 5540
225
123
  network: {
226
124
  listeningAddressIpv4: this.ipv4address,
227
125
  listeningAddressIpv6: this.ipv6address,
228
126
  port,
229
127
  },
230
- // Provide Commissioning relevant settings
231
- // Optional for development/testing purposes
232
128
  commissioning: {
233
129
  passcode,
234
130
  discriminator,
235
131
  },
236
- // Provide Node announcement settings
237
- // Optional: If Ommitted some development defaults are used
238
132
  productDescription: {
239
133
  name: await storageContext.get('deviceName'),
240
134
  deviceType: DeviceTypeId(await storageContext.get('deviceType')),
241
135
  },
242
- // Provide defaults for the BasicInformation cluster on the Root endpoint
243
- // Optional: If Omitted some development defaults are used
244
136
  basicInformation: {
245
137
  vendorId: VendorId(await storageContext.get('vendorId')),
246
138
  vendorName: await storageContext.get('vendorName'),
@@ -257,7 +149,6 @@ export class MatterbridgeEdge extends Matterbridge {
257
149
  },
258
150
  });
259
151
  const sanitizeFabrics = (fabrics) => {
260
- // New type of fabric information: Record<FabricIndex, ExposedFabricInformation>
261
152
  const sanitizedFabrics = this.sanitizeFabricInformations(Array.from(Object.values(serverNode.state.commissioning.fabrics)));
262
153
  this.log.info(`Fabrics: ${debugStringify(sanitizedFabrics)}`);
263
154
  if (this.bridgeMode === 'bridge') {
@@ -265,15 +156,17 @@ export class MatterbridgeEdge extends Matterbridge {
265
156
  this.matterbridgeSessionInformations = [];
266
157
  this.matterbridgePaired = true;
267
158
  }
159
+ if (this.bridgeMode === 'childbridge') {
160
+ const plugin = this.plugins.get(storeId);
161
+ if (plugin) {
162
+ plugin.fabricInformations = sanitizedFabrics;
163
+ plugin.sessionInformations = [];
164
+ plugin.paired = true;
165
+ }
166
+ }
268
167
  };
269
- /**
270
- * This event is triggered when the device is initially commissioned successfully.
271
- * This means: It is added to the first fabric.
272
- */
273
168
  serverNode.lifecycle.commissioned.on(() => this.log.notice(`Server node for ${storeId} was initially commissioned successfully!`));
274
- /** This event is triggered when all fabrics are removed from the device, usually it also does a factory reset then. */
275
169
  serverNode.lifecycle.decommissioned.on(() => this.log.notice(`Server node for ${storeId} was fully decommissioned successfully!`));
276
- /** This event is triggered when the device went online. This means that it is discoverable in the network. */
277
170
  serverNode.lifecycle.online.on(() => {
278
171
  this.log.notice(`Server node for ${storeId} is online`);
279
172
  if (!serverNode.lifecycle.isCommissioned) {
@@ -289,13 +182,25 @@ export class MatterbridgeEdge extends Matterbridge {
289
182
  this.log.notice(`QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`);
290
183
  this.log.notice(`Manual pairing code: ${manualPairingCode}`);
291
184
  }
185
+ if (this.bridgeMode === 'childbridge') {
186
+ const plugin = this.plugins.get(storeId);
187
+ if (plugin) {
188
+ plugin.qrPairingCode = qrPairingCode;
189
+ plugin.manualPairingCode = manualPairingCode;
190
+ plugin.fabricInformations = [];
191
+ plugin.sessionInformations = [];
192
+ plugin.paired = false;
193
+ plugin.connected = false;
194
+ this.log.notice(`QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`);
195
+ this.log.notice(`Manual pairing code: ${manualPairingCode}`);
196
+ }
197
+ }
292
198
  }
293
199
  else {
294
200
  this.log.notice(`Server node for ${storeId} is already commissioned. Waiting for controllers to connect ...`);
295
201
  sanitizeFabrics(serverNode.state.commissioning.fabrics);
296
202
  }
297
203
  });
298
- /** This event is triggered when the device went offline. it is not longer discoverable or connectable in the network. */
299
204
  serverNode.lifecycle.offline.on(() => {
300
205
  this.log.notice(`Server node for ${storeId} is offline`);
301
206
  if (this.bridgeMode === 'bridge') {
@@ -307,10 +212,6 @@ export class MatterbridgeEdge extends Matterbridge {
307
212
  this.matterbridgeConnected = false;
308
213
  }
309
214
  });
310
- /**
311
- * This event is triggered when a fabric is added, removed or updated on the device. Use this if more granular
312
- * information is needed.
313
- */
314
215
  serverNode.events.commissioning.fabricsChanged.on((fabricIndex, fabricAction) => {
315
216
  let action = '';
316
217
  switch (fabricAction) {
@@ -336,23 +237,21 @@ export class MatterbridgeEdge extends Matterbridge {
336
237
  if (this.bridgeMode === 'bridge') {
337
238
  this.matterbridgeSessionInformations = sanitizedSessions;
338
239
  }
240
+ if (this.bridgeMode === 'childbridge') {
241
+ const plugin = this.plugins.get(storeId);
242
+ if (plugin) {
243
+ plugin.sessionInformations = sanitizedSessions;
244
+ }
245
+ }
339
246
  };
340
- /**
341
- * This event is triggered when an operative new session was opened by a Controller.
342
- * It is not triggered for the initial commissioning process, just afterwards for real connections.
343
- */
344
247
  serverNode.events.sessions.opened.on((session) => {
345
248
  this.log.notice(`Session opened on server node for ${storeId}: ${debugStringify(session)}`);
346
249
  sanitizeSessions(Object.values(serverNode.state.sessions.sessions));
347
250
  });
348
- /**
349
- * This event is triggered when an operative session is closed by a Controller or because the Device goes offline.
350
- */
351
251
  serverNode.events.sessions.closed.on((session) => {
352
252
  this.log.notice(`Session closed on server node for ${storeId}: ${debugStringify(session)}`);
353
253
  sanitizeSessions(Object.values(serverNode.state.sessions.sessions));
354
254
  });
355
- /** This event is triggered when a subscription gets added or removed on an operative session. */
356
255
  serverNode.events.sessions.subscriptionsChanged.on((session) => {
357
256
  this.log.notice(`Session subscriptions changed on server node for ${storeId}: ${debugStringify(session)}`);
358
257
  sanitizeSessions(Object.values(serverNode.state.sessions.sessions));
@@ -378,39 +277,139 @@ export class MatterbridgeEdge extends Matterbridge {
378
277
  return aggregator;
379
278
  }
380
279
  async addBridgedEndpoint(pluginName, device) {
381
- // Check if the plugin is registered
382
280
  const plugin = this.plugins.get(pluginName);
383
281
  if (!plugin) {
384
- this.log.error(`Error adding bridged device ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) plugin ${plg}${pluginName}${er} not found`);
282
+ this.log.error(`Error adding bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) plugin ${plg}${pluginName}${er} not found`);
385
283
  return;
386
284
  }
387
- // Register and add the device to the matterbridge aggregator node
388
285
  if (this.bridgeMode === 'bridge') {
389
286
  this.log.info(`Adding ${pluginName}:${device.deviceName} to Matterbridge aggregator node`);
390
287
  const aggregatorNode = this.agToAggregatorEndpoint.get('Matterbridge')?.aggregatorNode;
391
288
  await aggregatorNode?.add(device);
392
289
  }
393
290
  else if (this.bridgeMode === 'childbridge') {
291
+ if (plugin.type === 'AccessoryPlatform') {
292
+ if (!plugin.locked && device.deviceName && device.vendorId && device.productId && device.vendorName && device.productName) {
293
+ plugin.locked = true;
294
+ plugin.storageContext = await this.createServerNodeContext(plugin.name, device.deviceName, DeviceTypeId(device.deviceType), device.vendorId, device.vendorName, device.productId, device.productName);
295
+ plugin.commissioningServer = (await this.createServerNode(plugin.storageContext, this.port++, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined));
296
+ this.log.debug(`Adding matterbridge endpoint to server node for plugin ${plg}${plugin.name}${db}`);
297
+ await plugin.commissioningServer.add(device);
298
+ this.csToServerNode.set(plugin.name, { commissioningServer: plugin.commissioningServer, serverNode: plugin.commissioningServer });
299
+ }
300
+ }
394
301
  if (plugin.type === 'DynamicPlatform') {
395
- this.log.info(`Adding ${pluginName}:${device.deviceName} to ${pluginName} aggregator node`);
302
+ if (!plugin.locked) {
303
+ plugin.locked = true;
304
+ plugin.storageContext = await this.createServerNodeContext(plugin.name, 'Matterbridge', bridge.code, this.aggregatorVendorId, 'Matterbridge', this.aggregatorProductId, plugin.description);
305
+ plugin.commissioningServer = (await this.createServerNode(plugin.storageContext, this.port++, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined));
306
+ plugin.aggregator = (await this.createAggregatorNode(plugin.storageContext));
307
+ this.log.debug(`Adding matter aggregator node to server node for plugin ${plg}${plugin.name}${db}`);
308
+ await plugin.commissioningServer.add(plugin.aggregator);
309
+ this.csToServerNode.set(plugin.name, { commissioningServer: plugin.commissioningServer, serverNode: plugin.commissioningServer });
310
+ this.agToAggregatorEndpoint.set(plugin.name, { aggregator: plugin.aggregator, aggregatorNode: plugin.aggregator });
311
+ }
396
312
  const aggregatorNode = this.agToAggregatorEndpoint.get(pluginName)?.aggregatorNode;
397
313
  await aggregatorNode?.add(device);
398
314
  }
399
315
  }
400
- // TODO: Implement plugins and devices
401
316
  if (plugin.registeredDevices !== undefined)
402
317
  plugin.registeredDevices++;
403
318
  if (plugin.addedDevices !== undefined)
404
319
  plugin.addedDevices++;
405
- // Add the device to the DeviceManager
406
320
  this.devices.set(device);
407
- this.log.info(`Added and registered bridged device (${plugin.registeredDevices}/${plugin.addedDevices}) ${dev}${device.deviceName}${nf} (${dev}${device.id}${nf}) for plugin ${plg}${pluginName}${nf}`);
321
+ this.log.info(`Added and registered bridged endpoint (${plugin.registeredDevices}/${plugin.addedDevices}) ${dev}${device.deviceName}${nf} (${dev}${device.id}${nf}) for plugin ${plg}${pluginName}${nf}`);
408
322
  }
409
323
  async removeBridgedEndpoint(pluginName, device) {
410
- // TODO: Implement removeBridgedEndpoint
324
+ this.log.debug(`Removing bridged endpoint ${dev}${device.deviceName}${db} (${zb}${device.name}${db}) for plugin ${plg}${pluginName}${db}`);
325
+ const plugin = this.plugins.get(pluginName);
326
+ if (!plugin) {
327
+ this.log.error(`Error removing bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.name}${er}) for plugin ${plg}${pluginName}${er}: plugin not found`);
328
+ return;
329
+ }
330
+ if (this.bridgeMode === 'bridge') {
331
+ const aggregatoreNode = this.agToAggregatorEndpoint.get('Matterbridge')?.aggregatorNode;
332
+ if (!aggregatoreNode) {
333
+ this.log.error(`Error removing bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.name}${er}) for plugin ${plg}${pluginName}${er}: matterAggregator node not found`);
334
+ return;
335
+ }
336
+ await device.delete();
337
+ this.log.info(`Removed bridged endpoint(${plugin.registeredDevices}/${plugin.addedDevices}) ${dev}${device.deviceName}${nf} (${zb}${device.name}${nf}) for plugin ${plg}${pluginName}${nf}`);
338
+ if (plugin.registeredDevices !== undefined)
339
+ plugin.registeredDevices--;
340
+ if (plugin.addedDevices !== undefined)
341
+ plugin.addedDevices--;
342
+ }
343
+ else if (this.bridgeMode === 'childbridge') {
344
+ if (plugin.type === 'AccessoryPlatform') {
345
+ }
346
+ else if (plugin.type === 'DynamicPlatform') {
347
+ const aggregatoreNode = this.agToAggregatorEndpoint.get(pluginName)?.aggregatorNode;
348
+ if (!aggregatoreNode) {
349
+ this.log.error(`Error removing bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.name}${er}) for plugin ${plg}${pluginName}${er}: aggregator not found`);
350
+ return;
351
+ }
352
+ await device.delete();
353
+ }
354
+ this.log.info(`Removed bridged endpoint(${plugin.registeredDevices}/${plugin.addedDevices}) ${dev}${device.deviceName}${nf} (${zb}${device.name}${nf}) for plugin ${plg}${pluginName}${nf}`);
355
+ if (plugin.registeredDevices !== undefined)
356
+ plugin.registeredDevices--;
357
+ if (plugin.addedDevices !== undefined)
358
+ plugin.addedDevices--;
359
+ if (plugin.registeredDevices === 0 && plugin.addedDevices === 0) {
360
+ const serverNode = this.csToServerNode.get(pluginName)?.serverNode;
361
+ if (serverNode)
362
+ await this.stopServerNode(serverNode);
363
+ this.csToServerNode.delete(pluginName);
364
+ this.log.info(`Removed server node for plugin ${plg}${pluginName}${nf}`);
365
+ }
366
+ }
367
+ this.devices.remove(device);
411
368
  }
412
369
  async removeAllBridgedEndpoints(pluginName) {
413
- // TODO: Implement removeAllBridgedEndpoints
370
+ this.log.debug(`Removing all bridged endpoints for plugin ${plg}${pluginName}${db}`);
371
+ for (const device of this.devices.array().filter((device) => device.plugin === pluginName)) {
372
+ await this.removeBridgedEndpoint(pluginName, device);
373
+ }
374
+ }
375
+ createMatterServer(storageManager) {
376
+ if (hasParameter('debug'))
377
+ this.log.warn('createMatterServer() => mock MatterServer.addCommissioningServer()');
378
+ const matterServer = {
379
+ addCommissioningServer: (commissioningServer, nodeOptions) => {
380
+ if (hasParameter('debug'))
381
+ this.log.warn('MatterServer.addCommissioningServer() => do nothing');
382
+ },
383
+ };
384
+ return matterServer;
385
+ }
386
+ async startMatterServer() {
387
+ if (hasParameter('debug'))
388
+ this.log.warn('startMatterServer() => do nothing');
389
+ }
390
+ async stopMatterServer() {
391
+ if (hasParameter('debug'))
392
+ this.log.warn('stopMatterServer() => ...');
393
+ this.log.info(`Stopping matter server nodes in ${this.bridgeMode} mode...`);
394
+ if (this.bridgeMode === 'bridge') {
395
+ const serverNode = this.csToServerNode.get('Matterbridge')?.serverNode;
396
+ if (serverNode) {
397
+ await this.stopServerNode(serverNode);
398
+ this.log.info(`Stopped matter server node Matterbridge`);
399
+ }
400
+ }
401
+ if (this.bridgeMode === 'childbridge') {
402
+ for (const plugin of this.plugins.array()) {
403
+ const serverNode = this.csToServerNode.get(plugin.name)?.serverNode;
404
+ if (serverNode) {
405
+ await this.stopServerNode(serverNode);
406
+ this.log.info(`Stopped matter server node ${plugin.name}`);
407
+ }
408
+ }
409
+ }
410
+ this.log.info('Stopped matter server nodes');
411
+ await this.environment.get(MdnsService)[Symbol.asyncDispose]();
412
+ this.log.info('Stopped MdnsService');
414
413
  }
415
414
  async createCommissioningServerContext(pluginName, deviceName, deviceType, vendorId, vendorName, productId, productName) {
416
415
  if (hasParameter('debug'))
@@ -432,11 +431,10 @@ export class MatterbridgeEdge extends Matterbridge {
432
431
  if (hasParameter('debug'))
433
432
  this.log.warn(`createCommisioningServer() for ${pluginName} => createServerNode()`);
434
433
  const port = this.port;
435
- const serverNode = await this.createServerNode(context, this.port++, this.passcode ? this.passcode++ : 20242025, this.discriminator ? this.discriminator++ : 3840);
434
+ const serverNode = await this.createServerNode(context, this.port++, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
436
435
  const commissioningServer = {
437
436
  getPort: () => port,
438
437
  addDevice: async (device) => {
439
- // if (hasParameter('debug')) this.log.warn('CommissioningServer.addDevice()', device.name);
440
438
  if (device instanceof Device) {
441
439
  if (hasParameter('debug'))
442
440
  this.log.warn('CommissioningServer.addDevice() => Device');
@@ -451,7 +449,6 @@ export class MatterbridgeEdge extends Matterbridge {
451
449
  await serverNode.add(aggregatorNode);
452
450
  if (!this.test) {
453
451
  this.test = true;
454
- // await this.testEndpoints();
455
452
  }
456
453
  }
457
454
  },
@@ -467,11 +464,11 @@ export class MatterbridgeEdge extends Matterbridge {
467
464
  name: 'MA-aggregator',
468
465
  addBridgedDevice: (device) => {
469
466
  if (hasParameter('debug'))
470
- this.log.warn('Aggregator.addBridgedDevice() => not inplemented');
467
+ this.log.error('****Aggregator.addBridgedDevice() => not inplemented');
471
468
  },
472
469
  removeBridgedDevice: (device) => {
473
470
  if (hasParameter('debug'))
474
- this.log.warn('Aggregator.removeBridgedDevice() => not inplemented');
471
+ this.log.error('****Aggregator.removeBridgedDevice() => not inplemented');
475
472
  },
476
473
  };
477
474
  this.agToAggregatorEndpoint.set(pluginName, { aggregator, aggregatorNode });
@@ -508,37 +505,6 @@ export class MatterbridgeEdge extends Matterbridge {
508
505
  const aggregatorNode = this.agToAggregatorEndpoint.get('Matterbridge')?.aggregatorNode;
509
506
  if (!aggregatorNode)
510
507
  return;
511
- /*
512
- this.log.notice(`Creating OnOffLight1`);
513
- const lightEndpoint = new MatterbridgeEndpoint(onOffLight, { uniqueStorageKey: 'OnOffLight1' }, true);
514
- lightEndpoint.addDeviceType(bridgedNode);
515
- lightEndpoint.createDefaultBridgedDeviceBasicInformationClusterServer('OnOffLight 1', '123456789', 0xfff1, 'Matterbridge', 'Light');
516
- lightEndpoint.addDeviceType(powerSource);
517
- lightEndpoint.createDefaultPowerSourceWiredClusterServer();
518
- lightEndpoint.addDeviceType(electricalSensor);
519
- lightEndpoint.addClusterServer(lightEndpoint.getDefaultElectricalEnergyMeasurementClusterServer());
520
- lightEndpoint.addClusterServer(lightEndpoint.getDefaultElectricalPowerMeasurementClusterServer());
521
- lightEndpoint.addRequiredClusterServers(lightEndpoint);
522
- this.log.notice(`Adding OnOffLight1 to ${await this.matterbridgeContext.get<string>('storeId')} aggregator`);
523
- await aggregatorNode.add(lightEndpoint);
524
- logEndpoint(EndpointServer.forEndpoint(lightEndpoint));
525
-
526
- this.log.notice(`Creating Outlet1`);
527
- const outletEndpoint = new MatterbridgeEndpoint(onOffOutlet, { uniqueStorageKey: 'OnOffOutlet1' }, true);
528
- outletEndpoint.addDeviceType(bridgedNode);
529
- outletEndpoint.createDefaultBridgedDeviceBasicInformationClusterServer('OnOffOutlet 1', '123456789', 0xfff1, 'Matterbridge', 'Outlet');
530
- outletEndpoint.addDeviceType(powerSource);
531
- outletEndpoint.createDefaultPowerSourceReplaceableBatteryClusterServer();
532
- outletEndpoint.addDeviceType(electricalSensor);
533
- outletEndpoint.addClusterServer(outletEndpoint.getDefaultElectricalEnergyMeasurementClusterServer());
534
- outletEndpoint.addClusterServer(outletEndpoint.getDefaultElectricalPowerMeasurementClusterServer());
535
- outletEndpoint.addRequiredClusterServers(outletEndpoint);
536
- const input0 = outletEndpoint.addChildDeviceTypeWithClusterServer('Input:0', [genericSwitch], undefined, undefined, true);
537
- const input1 = outletEndpoint.addChildDeviceTypeWithClusterServer('Input:1', [genericSwitch], undefined, undefined, true);
538
- this.log.notice(`Adding OnOffOutlet1 to ${await this.matterbridgeContext.get<string>('storeId')} aggregator`);
539
- await aggregatorNode.add(outletEndpoint);
540
- logEndpoint(EndpointServer.forEndpoint(outletEndpoint));
541
- */
542
508
  this.log.notice(`Creating switchEnpoint1`);
543
509
  const switchEnpoint1 = new EndpointNode(GenericSwitchDevice.with(BridgedDeviceBasicInformationServer, SwitchServer.with('MomentarySwitch', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress', 'MomentarySwitchRelease')), {
544
510
  id: 'GenericSwitch',
@@ -561,398 +527,5 @@ export class MatterbridgeEdge extends Matterbridge {
561
527
  this.log.notice(`Adding switchEnpoint1 to ${await this.matterbridgeContext.get('storeId')} aggregator`);
562
528
  await aggregatorNode.add(switchEnpoint1);
563
529
  logEndpoint(EndpointServer.forEndpoint(switchEnpoint1), { logNotSupportedClusterAttributes: true, logNotSupportedClusterEvents: true, logNotSupportedClusterCommands: true });
564
- // if (switchEnpoint2.behaviors.has(SwitchServer)) this.log.notice(`SwitchServer found`);
565
- // switchEnpoint2.act((agent) => agent['switch'].events['initialPress'].emit({ newPosition: 1 }, agent.context));
566
- /*
567
- const device = new MatterbridgeEndpoint(genericSwitch, { uniqueStorageKey: 'GenericSwitch 2' }, true);
568
- device.createDefaultSwitchClusterServer();
569
- device.addRequiredClusterServers(device);
570
- await aggregatorNode.add(device);
571
- logEndpoint(EndpointServer.forEndpoint(device));
572
- await device.triggerSwitchEvent('Single', this.log);
573
- await device.triggerSwitchEvent('Double', this.log);
574
- await device.triggerSwitchEvent('Long', this.log);
575
-
576
- const device1 = new MatterbridgeEndpoint(genericSwitch, { uniqueStorageKey: 'GenericSwitch 3' }, true);
577
- device1.createDefaultLatchingSwitchClusterServer();
578
- device1.addRequiredClusterServers(device1);
579
- await aggregatorNode.add(device1);
580
- logEndpoint(EndpointServer.forEndpoint(device1));
581
- await device1.triggerSwitchEvent('Press', this.log);
582
- await device1.triggerSwitchEvent('Release', this.log);
583
-
584
- this.log.notice(`Creating TestLight`);
585
- const matterbridgeDevice = new MatterbridgeEndpoint(onOffLight, { uniqueStorageKey: 'Test .Light:2' }, true);
586
- matterbridgeDevice.behaviors.require(MatterbridgeIdentifyServer, {
587
- identifyTime: 0,
588
- identifyType: Identify.IdentifyType.None,
589
- });
590
- matterbridgeDevice.behaviors.require(GroupsServer);
591
- matterbridgeDevice.behaviors.require(MatterbridgeOnOffServer, {
592
- onOff: false,
593
- });
594
- matterbridgeDevice.behaviors.require(MatterbridgeLevelControlServer, {
595
- currentLevel: 0,
596
- options: { executeIfOff: false },
597
- });
598
- matterbridgeDevice.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.Xy, ColorControl.Feature.ColorTemperature), {
599
- colorCapabilities: { xy: true, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: true },
600
- colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
601
- enhancedColorMode: ColorControl.EnhancedColorMode.ColorTemperatureMireds,
602
- options: { executeIfOff: false },
603
- numberOfPrimaries: null,
604
- currentX: 24939,
605
- currentY: 24701,
606
- currentHue: 0,
607
- currentSaturation: 0,
608
- colorTemperatureMireds: 450,
609
- colorTempPhysicalMinMireds: 150,
610
- colorTempPhysicalMaxMireds: 450,
611
- coupleColorTempToLevelMinMireds: 150,
612
- startUpColorTemperatureMireds: null,
613
- });
614
- matterbridgeDevice.behaviors.require(BridgedDeviceBasicInformationServer, {
615
- vendorId: VendorId(await this.matterbridgeContext.get<number>('vendorId')),
616
- vendorName: await this.matterbridgeContext.get<string>('vendorName'),
617
- productName: 'TestLight2',
618
- productLabel: 'TestLight2',
619
- nodeLabel: 'TestLight2',
620
- serialNumber: 'SN 0x123456789',
621
- uniqueId: '0x123456789',
622
- reachable: true,
623
- });
624
-
625
- // await matterbridgeDevice.setTagList(null, 0x07, 1, 'endpoint 2');
626
- // await matterbridgeDevice.configureColorControlCluster(false, false, true, ColorControl.ColorMode.ColorTemperatureMireds);
627
-
628
- this.log.notice(`Adding TestLight`);
629
- await aggregatorNode?.add(matterbridgeDevice);
630
-
631
- this.log.notice(`Creating switchEnpoint1`);
632
- const switchEnpoint2 = new EndpointNode(
633
- GenericSwitchDevice.with(DescriptorServer.with(Descriptor.Feature.TagList), BridgedDeviceBasicInformationServer, SwitchServer.with('MomentarySwitch', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress', 'MomentarySwitchRelease')),
634
- {
635
- id: 'GenericSwitch1',
636
- descriptor: {
637
- tagList: [{ mfgCode: null, namespaceId: 0x07, tag: 1, label: 'Switch1' }],
638
- },
639
- bridgedDeviceBasicInformation: {
640
- vendorId: VendorId(await this.matterbridgeContext.get<number>('vendorId')),
641
- vendorName: await this.matterbridgeContext.get<string>('vendorName'),
642
-
643
- productName: 'GenericSwitch',
644
- productLabel: 'GenericSwitch',
645
- nodeLabel: 'GenericSwitch',
646
-
647
- serialNumber: 'SN 0x1234567397',
648
- uniqueId: '0x1234567397',
649
- reachable: true,
650
- },
651
- switch: {
652
- numberOfPositions: 2,
653
- currentPosition: 0,
654
- multiPressMax: 2,
655
- },
656
- },
657
- );
658
- this.log.notice(`Creating switchEnpoint2`);
659
- await aggregatorNode?.add(switchEnpoint2);
660
- */
661
- /*
662
- const lightEndpoint1 = new EndpointNode(ColorTemperatureLightDevice.with(BridgedDeviceBasicInformationServer), {
663
- // }, MatterbridgeIdentifyServer, MatterbridgeOnOffServer, MatterbridgeLevelControlServer, MatterbridgeColorControlServer), {
664
- id: 'OnOffLight',
665
- bridgedDeviceBasicInformation: {
666
- vendorId: VendorId(await this.matterbridgeContext.get<number>('vendorId')),
667
- vendorName: await this.matterbridgeContext.get<string>('vendorName'),
668
-
669
- productName: 'Light',
670
- productLabel: 'Light',
671
- nodeLabel: 'Light',
672
-
673
- serialNumber: 'SN 0x123456789',
674
- uniqueId: '0x123456789',
675
- reachable: true,
676
- },
677
- levelControl: {
678
- currentLevel: 0,
679
- options: { executeIfOff: false, coupleColorTempToLevel: false },
680
- },
681
- colorControl: {
682
- colorTemperatureMireds: 450,
683
- colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
684
- colorTempPhysicalMinMireds: 150,
685
- colorTempPhysicalMaxMireds: 450,
686
- coupleColorTempToLevelMinMireds: 150,
687
- startUpColorTemperatureMireds: 450,
688
- },
689
- });
690
- lightEndpoint1.behaviors.require(ColorControlServer.with('ColorTemperature'), {
691
- colorTemperatureMireds: 450,
692
- colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
693
- colorTempPhysicalMinMireds: 150,
694
- colorTempPhysicalMaxMireds: 450,
695
- coupleColorTempToLevelMinMireds: 150,
696
- startUpColorTemperatureMireds: 450,
697
- });
698
- await aggregatorNode?.add(lightEndpoint1);
699
-
700
- /*
701
- lightEndpoint1.behaviors.require(MatterbridgeIdentifyServer);
702
- lightEndpoint1.behaviors.require(MatterbridgeOnOffServer);
703
- lightEndpoint1.behaviors.require(MatterbridgeLevelControlServer);
704
- lightEndpoint1.behaviors.require(MatterbridgeColorControlServer, {
705
- colorTemperatureMireds: 250,
706
- colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
707
- colorTempPhysicalMinMireds: 150,
708
- colorTempPhysicalMaxMireds: 450,
709
- coupleColorTempToLevelMinMireds: 150,
710
- startUpColorTemperatureMireds: 450,
711
- });
712
- await aggregatorNode?.add(lightEndpoint1);
713
-
714
- this.log.notice(`Creating switchEnpoint2`);
715
- const switchEnpoint2 = new EndpointNode(GenericSwitchDevice.with(BridgedDeviceBasicInformationServer, SwitchServer.with('MomentarySwitch', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress', 'MomentarySwitchRelease')), {
716
- id: 'GenericSwitch',
717
- bridgedDeviceBasicInformation: {
718
- vendorId: VendorId(await this.matterbridgeContext.get<number>('vendorId')),
719
- vendorName: await this.matterbridgeContext.get<string>('vendorName'),
720
-
721
- productName: 'GenericSwitch',
722
- productLabel: 'GenericSwitch',
723
- nodeLabel: 'GenericSwitch',
724
-
725
- serialNumber: 'SN 0x123456739',
726
- uniqueId: '0x123456739',
727
- reachable: true,
728
- },
729
- switch: {
730
- numberOfPositions: 2,
731
- currentPosition: 0,
732
- multiPressMax: 2,
733
- },
734
- });
735
- await aggregatorNode?.add(switchEnpoint2);
736
- */
737
- /*
738
- for (let i = 1; i <= max; i++) {
739
- this.log.notice(`Creating lightEndpoint${i}`);
740
- const lightEndpoint = new MatterbridgeEndpoint(onOffLight, { uniqueStorageKey: 'OnOffLight' + i });
741
- lightEndpoint.addClusterServer(lightEndpoint.getDefaultBridgedDeviceBasicInformationClusterServer('OnOffLight' + i, '123456789', 0xfff1, 'Matterbridge', 'Light'));
742
- this.log.notice(`Adding lightEndpoint${i} to ${await this.matterbridgeContext.get<string>('storeId')} aggregator`);
743
- await aggregatorNode?.add(lightEndpoint);
744
- setInterval(async () => {
745
- const state = lightEndpoint.getAttribute(OnOffCluster.id, 'onOff');
746
- lightEndpoint.setAttribute(OnOffCluster.id, 'onOff', !state);
747
- this.log.notice(`Setting state for lightEndpoint${i} from:`, state, 'to:', !state);
748
- }, 10000);
749
- }
750
- for (let i = 1; i <= max; i++) {
751
- this.log.notice(`Creating outletEndpoint${i}`);
752
- const lightEndpoint = new MatterbridgeEndpoint(onOffOutlet, { uniqueStorageKey: 'OnOffOutlet' + i });
753
- lightEndpoint.addClusterServer(lightEndpoint.getDefaultBridgedDeviceBasicInformationClusterServer('OnOffOutlet' + i, '123456789', 0xfff1, 'Matterbridge', 'Outlet'));
754
- this.log.notice(`Adding outletEndpoint${i} to ${await this.matterbridgeContext.get<string>('storeId')} aggregator`);
755
- await aggregatorNode?.add(lightEndpoint);
756
- setInterval(async () => {
757
- const state = lightEndpoint.getAttribute(OnOffCluster.id, 'onOff');
758
- lightEndpoint.setAttribute(OnOffCluster.id, 'onOff', !state);
759
- this.log.notice(`Setting state for outletEndpoint${i} from:`, state, 'to:', !state);
760
- }, 10000);
761
- }
762
- */
763
530
  }
764
531
  }
765
- /*
766
- /*
767
- matterbridgeDevice.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.Xy, ColorControl.Feature.ColorTemperature), {
768
- colorCapabilities: { xy: true, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: true },
769
- colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
770
- enhancedColorMode: ColorControl.EnhancedColorMode.ColorTemperatureMireds,
771
- options: { executeIfOff: false },
772
- numberOfPrimaries: null,
773
- currentX: 24939,
774
- currentY: 24701,
775
- currentHue: 0,
776
- currentSaturation: 0,
777
- colorTemperatureMireds: 450,
778
- colorTempPhysicalMinMireds: 150,
779
- colorTempPhysicalMaxMireds: 450,
780
- coupleColorTempToLevelMinMireds: 150,
781
- startUpColorTemperatureMireds: null,
782
- });
783
- matterbridgeDevice.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.ColorTemperature), {
784
- colorCapabilities: { xy: false, hueSaturation: false, colorLoop: false, enhancedHue: false, colorTemperature: true },
785
- colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
786
- enhancedColorMode: ColorControl.EnhancedColorMode.ColorTemperatureMireds,
787
- options: { executeIfOff: false },
788
- numberOfPrimaries: null,
789
- colorTemperatureMireds: 450,
790
- colorTempPhysicalMinMireds: 150,
791
- colorTempPhysicalMaxMireds: 450,
792
- coupleColorTempToLevelMinMireds: 150,
793
- startUpColorTemperatureMireds: null,
794
- });
795
- */
796
- /*
797
- matterbridgeDevice.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.Xy), {
798
- colorCapabilities: { xy: true, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: false },
799
- colorMode: ColorControl.ColorMode.CurrentHueAndCurrentSaturation,
800
- enhancedColorMode: ColorControl.EnhancedColorMode.CurrentHueAndCurrentSaturation,
801
- options: { executeIfOff: false },
802
- numberOfPrimaries: null,
803
- currentX: 24939,
804
- currentY: 24701,
805
- currentHue: 0,
806
- currentSaturation: 0,
807
- });
808
- // node dist/matterbridgeEdge.js MatterbridgeEdge -debug -ssl -frontend 443
809
- if (process.argv.includes('MatterbridgeEdge')) {
810
- const matterbridge = await MatterbridgeEdge.loadInstance(true);
811
-
812
- process.on('SIGINT', async function () {
813
- // eslint-disable-next-line no-console
814
- console.log('Caught interrupt signal');
815
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
816
- if (matterbridge) await (matterbridge as any).cleanup('shutting down...', false);
817
- // if (matterbridge && matterbridge.matterServerNode && matterbridge.matterServerNodeContext) await matterbridge.stopServerNode(matterbridge.matterServerNode, matterbridge.matterServerNodeContext);
818
- const exit = setTimeout(() => {
819
- // eslint-disable-next-line no-console
820
- console.log('Exiting after caught interrupt signal');
821
- process.exit();
822
- }, 10000);
823
- exit.unref();
824
- });
825
- }
826
- */
827
- /*
828
- async startBridgeNode(): Promise<void> {
829
- this.log.notice(`Creating lightEndpoint1`);
830
- const lightEndpoint1 = new Endpoint(OnOffLightDevice.with(BridgedDeviceBasicInformationServer), {
831
- id: 'OnOffLight',
832
- bridgedDeviceBasicInformation: {
833
- vendorId: VendorId(await storageContext.get<number>('vendorId')),
834
- vendorName: await storageContext.get<string>('vendorName'),
835
-
836
- productName: 'Light',
837
- productLabel: 'Light',
838
- nodeLabel: 'Light',
839
-
840
- serialNumber: 'SN 0x123456789',
841
- uniqueId: '0x123456789',
842
- reachable: true,
843
- },
844
- });
845
- this.log.notice(`Adding lightEndpoint1 to ${await storageContext.get<string>('storeId')} aggregator`);
846
- await this.matterAggregatorNode.add(lightEndpoint1);
847
- // logEndpoint(EndpointServer.forEndpoint(lightEndpoint1));
848
-
849
- this.log.notice(`Creating switchEnpoint2`);
850
- const switchEnpoint2 = new Endpoint(GenericSwitchDevice.with(BridgedDeviceBasicInformationServer, SwitchServer.with('MomentarySwitch', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress', 'MomentarySwitchRelease')), {
851
- id: 'GenericSwitch',
852
- bridgedDeviceBasicInformation: {
853
- vendorId: VendorId(await storageContext.get<number>('vendorId')),
854
- vendorName: await storageContext.get<string>('vendorName'),
855
-
856
- productName: 'GenericSwitch',
857
- productLabel: 'GenericSwitch',
858
- nodeLabel: 'GenericSwitch',
859
-
860
- serialNumber: 'SN 0x123456739',
861
- uniqueId: '0x123456739',
862
- reachable: true,
863
- },
864
- switch: {
865
- numberOfPositions: 2,
866
- currentPosition: 0,
867
- multiPressMax: 2,
868
- },
869
- });
870
- this.log.notice(`Adding switchEnpoint2 to ${await storageContext.get<string>('storeId')} aggregator`);
871
- await this.matterAggregatorNode.add(switchEnpoint2);
872
- // logEndpoint(EndpointServer.forEndpoint(switchEnpoint2));
873
-
874
- // switchEnpoint2.events.identify.startIdentifying.on(() => this.log.notice('GenericSwitch.identify logic, ideally blink a light every 0.5s ...'));
875
- // switchEnpoint2.events.switch.currentPosition$Changed.on(() => this.log.notice('GenericSwitch.currentPosition changed ...'));
876
- // switchEnpoint2.act((agent) => agent.switch.events.initialPress.emit({ newPosition: 1 }, agent.context));
877
- // switchEnpoint2.events.switch.emit('initialPress', { newPosition: 1 }, switchEnpoint2.events.switch.context);
878
- */
879
- /*
880
- log.notice(`Creating matterbridge device ClimateSensor`);
881
- const matterbridgeDevice3 = new MatterbridgeDeviceV8(DeviceTypes.TEMPERATURE_SENSOR, { uniqueStorageKey: 'ClimateSensor' });
882
- matterbridgeDevice3.addDeviceTypeWithClusterServer([DeviceTypes.TEMPERATURE_SENSOR], [TemperatureMeasurement.Cluster.id]);
883
- matterbridgeDevice3.addDeviceTypeWithClusterServer([DeviceTypes.HUMIDITY_SENSOR], [RelativeHumidityMeasurement.Cluster.id]);
884
- matterbridgeDevice3.addDeviceTypeWithClusterServer([DeviceTypes.PRESSURE_SENSOR], [PressureMeasurement.Cluster.id]);
885
- matterbridgeDevice3.behaviors.require(IdentifyServer, {
886
- identifyTime: 5,
887
- });
888
- matterbridgeDevice3.behaviors.require(TemperatureMeasurementServer, {
889
- measuredValue: 25.0,
890
- minMeasuredValue: null,
891
- maxMeasuredValue: null,
892
- });
893
- */
894
- /*
895
- log.notice(`Adding BridgedDeviceBasicInformationServer to ClimateSensor`);
896
- matterbridgeDevice3.behaviors.require(BridgedDeviceBasicInformationServer, {
897
- vendorId: VendorId(await storageContext.get<number>('vendorId')),
898
- vendorName: await storageContext.get<string>('vendorName'),
899
-
900
- productName: 'ClimateSensor',
901
- productLabel: 'ClimateSensor',
902
- nodeLabel: 'ClimateSensor',
903
-
904
- serialNumber: '0x145433356739',
905
- uniqueId: '0x1254446739',
906
- reachable: true,
907
- });
908
-
909
- log.notice(`Adding DescriptorServer to ClimateSensor`);
910
- matterbridgeDevice3.behaviors.require(DescriptorServer, {
911
- deviceTypeList: [
912
- { deviceType: 0x0302, revision: 2 },
913
- { deviceType: 0x0307, revision: 2 },
914
- { deviceType: 0x0305, revision: 2 },
915
- ],
916
- });
917
-
918
- this.log.notice(`Adding ClimateSensor to ${await storageContext.get<string>('storeId')} aggregator`);
919
- await this.matterAggregator.add(matterbridgeDevice3);
920
- logEndpoint(EndpointServer.forEndpoint(matterbridgeDevice3));
921
- */
922
- /*
923
- await lightEndpoint1.set({
924
- onOff: {
925
- onOff: true,
926
- },
927
- });
928
- await switchEnpoint2.set({
929
- switch: {
930
- currentPosition: 1,
931
- },
932
- });
933
- switchEnpoint2.act((agent) => agent.switch.events.initialPress.emit({ newPosition: 1 }, agent.context));
934
- */
935
- /*
936
- await matterbridgeDevice3.set({
937
- temperatureMeasurement: {
938
- measuredValue: 20 * 100,
939
- },
940
- relativeHumidityMeasurement: {
941
- measuredValue: 50 * 100,
942
- },
943
- });
944
- */
945
- // logEndpoint(EndpointServer.forEndpoint(this.matterServerNode));
946
- /*
947
- logEndpoint(EndpointServer.forEndpoint(this.matterServerNode));
948
- logEndpoint(EndpointServer.forEndpoint(matterbridgeDevice3));
949
- console.log('matterbridgeDevice3\n', matterbridgeDevice3);
950
- console.log('matterbridgeDevice3.events\n', matterbridgeDevice3.events);
951
- console.log('matterbridgeDevice3.events.identify\n', matterbridgeDevice3.eventsOf(IdentifyServer));
952
- console.log('matterbridgeDevice3.state\n', matterbridgeDevice3.state);
953
- console.log('matterbridgeDevice3.state.temperatureMeasurement\n', matterbridgeDevice3.stateOf(TemperatureMeasurementServer));
954
- // matterbridgeDevice3.eventsOf(IdentifyServer);
955
- // matterbridgeDevice3.events.identify.startIdentifying.on(() => log.notice('Run identify logic, ideally blink a light every 0.5s ...'));
956
- }
957
- */
958
- //# sourceMappingURL=matterbridgeEdge.js.map