matterbridge 1.6.7-dev.3 → 1.6.7
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.
- package/CHANGELOG.md +5 -1
- package/dist/cli.d.ts +25 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -0
- package/dist/cluster/export.d.ts +2 -0
- package/dist/cluster/export.d.ts.map +1 -0
- package/dist/cluster/export.js +2 -0
- package/dist/cluster/export.js.map +1 -0
- package/dist/defaultConfigSchema.d.ts +27 -0
- package/dist/defaultConfigSchema.d.ts.map +1 -0
- package/dist/defaultConfigSchema.js +23 -0
- package/dist/defaultConfigSchema.js.map +1 -0
- package/dist/deviceManager.d.ts +46 -0
- package/dist/deviceManager.d.ts.map +1 -0
- package/dist/deviceManager.js +26 -1
- package/dist/deviceManager.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/export.d.ts +2 -0
- package/dist/logger/export.d.ts.map +1 -0
- package/dist/logger/export.js +1 -0
- package/dist/logger/export.js.map +1 -0
- package/dist/matter/export.d.ts +6 -0
- package/dist/matter/export.d.ts.map +1 -0
- package/dist/matter/export.js +1 -0
- package/dist/matter/export.js.map +1 -0
- package/dist/matterbridge.d.ts +466 -0
- package/dist/matterbridge.d.ts.map +1 -0
- package/dist/matterbridge.js +660 -61
- package/dist/matterbridge.js.map +1 -0
- package/dist/matterbridgeAccessoryPlatform.d.ts +39 -0
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +1 -0
- package/dist/matterbridgeAccessoryPlatform.js +33 -0
- package/dist/matterbridgeAccessoryPlatform.js.map +1 -0
- package/dist/matterbridgeBehaviors.d.ts +942 -0
- package/dist/matterbridgeBehaviors.d.ts.map +1 -0
- package/dist/matterbridgeBehaviors.js +29 -1
- package/dist/matterbridgeBehaviors.js.map +1 -0
- package/dist/matterbridgeDevice.d.ts +7063 -0
- package/dist/matterbridgeDevice.d.ts.map +1 -0
- package/dist/matterbridgeDevice.js +1026 -10
- package/dist/matterbridgeDevice.js.map +1 -0
- package/dist/matterbridgeDeviceTypes.d.ts +109 -0
- package/dist/matterbridgeDeviceTypes.d.ts.map +1 -0
- package/dist/matterbridgeDeviceTypes.js +98 -12
- package/dist/matterbridgeDeviceTypes.js.map +1 -0
- package/dist/matterbridgeDynamicPlatform.d.ts +39 -0
- package/dist/matterbridgeDynamicPlatform.d.ts.map +1 -0
- package/dist/matterbridgeDynamicPlatform.js +33 -0
- package/dist/matterbridgeDynamicPlatform.js.map +1 -0
- package/dist/matterbridgeEdge.d.ts +92 -0
- package/dist/matterbridgeEdge.d.ts.map +1 -0
- package/dist/matterbridgeEdge.js +530 -0
- package/dist/matterbridgeEdge.js.map +1 -0
- package/dist/matterbridgeEndpoint.d.ts +10164 -0
- package/dist/matterbridgeEndpoint.d.ts.map +1 -0
- package/dist/matterbridgeEndpoint.js +1163 -15
- package/dist/matterbridgeEndpoint.js.map +1 -0
- package/dist/matterbridgePlatform.d.ts +114 -0
- package/dist/matterbridgePlatform.d.ts.map +1 -0
- package/dist/matterbridgePlatform.js +91 -3
- package/dist/matterbridgePlatform.js.map +1 -0
- package/dist/matterbridgeTypes.d.ts +162 -0
- package/dist/matterbridgeTypes.d.ts.map +1 -0
- package/dist/matterbridgeTypes.js +24 -0
- package/dist/matterbridgeTypes.js.map +1 -0
- package/dist/matterbridgeWebsocket.d.ts +49 -0
- package/dist/matterbridgeWebsocket.d.ts.map +1 -0
- package/dist/matterbridgeWebsocket.js +45 -0
- package/dist/matterbridgeWebsocket.js.map +1 -0
- package/dist/pluginManager.d.ts +238 -0
- package/dist/pluginManager.d.ts.map +1 -0
- package/dist/pluginManager.js +238 -3
- package/dist/pluginManager.js.map +1 -0
- package/dist/storage/export.d.ts +2 -0
- package/dist/storage/export.d.ts.map +1 -0
- package/dist/storage/export.js +1 -0
- package/dist/storage/export.js.map +1 -0
- package/dist/utils/colorUtils.d.ts +61 -0
- package/dist/utils/colorUtils.d.ts.map +1 -0
- package/dist/utils/colorUtils.js +205 -2
- package/dist/utils/colorUtils.js.map +1 -0
- package/dist/utils/export.d.ts +3 -0
- package/dist/utils/export.d.ts.map +1 -0
- package/dist/utils/export.js +1 -0
- package/dist/utils/export.js.map +1 -0
- package/dist/utils/utils.d.ts +221 -0
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/utils/utils.js +252 -7
- package/dist/utils/utils.js.map +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -1
package/dist/matterbridgeEdge.js
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
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
|
|
1
26
|
import path from 'path';
|
|
2
27
|
import os from 'os';
|
|
3
28
|
import { randomBytes } from 'crypto';
|
|
29
|
+
// NodeStorage and AnsiLogger modules
|
|
4
30
|
import { rs, GREEN, debugStringify, er, zb, nf, db } from 'node-ansi-logger';
|
|
31
|
+
// Matterbridge
|
|
5
32
|
import { Matterbridge } from './matterbridge.js';
|
|
6
33
|
import { bridge } from './matterbridgeDeviceTypes.js';
|
|
7
34
|
import { dev, plg } from './matterbridgeTypes.js';
|
|
8
35
|
import { copyDirectory, getParameter, hasParameter } from './utils/utils.js';
|
|
36
|
+
// @matter
|
|
9
37
|
import { DeviceTypeId, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, VendorId, EndpointServer } from '@matter/main';
|
|
10
38
|
import { ServerNode, Endpoint as EndpointNode, Environment, StorageService } from '@matter/main';
|
|
11
39
|
import { BasicInformationCluster } from '@matter/main/clusters';
|
|
@@ -14,12 +42,20 @@ import { GenericSwitchDevice } from '@matter/main/devices';
|
|
|
14
42
|
import { AggregatorEndpoint } from '@matter/main/endpoints';
|
|
15
43
|
import { BridgedDeviceBasicInformationServer, SwitchServer } from '@matter/main/behaviors';
|
|
16
44
|
import { Device, logEndpoint } from '@project-chip/matter.js/device';
|
|
45
|
+
/**
|
|
46
|
+
* Represents the MatterbridgeEdge application.
|
|
47
|
+
*/
|
|
17
48
|
export class MatterbridgeEdge extends Matterbridge {
|
|
18
49
|
static instance;
|
|
50
|
+
// Matter environment
|
|
19
51
|
environment = Environment.default;
|
|
52
|
+
// Matter storage
|
|
20
53
|
matterStorageService;
|
|
54
|
+
// Mapping of CommissioningServer to ServerNode
|
|
21
55
|
csToServerNode = new Map();
|
|
56
|
+
// Mapping of Aggregator to AggregatorEndpoint
|
|
22
57
|
agToAggregatorEndpoint = new Map();
|
|
58
|
+
// Mapping of sessions
|
|
23
59
|
activeSessions = new Map();
|
|
24
60
|
constructor() {
|
|
25
61
|
super();
|
|
@@ -37,24 +73,30 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
37
73
|
async initialize() {
|
|
38
74
|
if (hasParameter('debug'))
|
|
39
75
|
console.log('Initializing MatterbridgeEdge...');
|
|
76
|
+
// Set the matterbridge directory
|
|
40
77
|
this.homeDirectory = getParameter('homedir') ?? os.homedir();
|
|
41
78
|
this.matterbridgeDirectory = path.join(this.homeDirectory, '.matterbridge');
|
|
42
79
|
this.matterStorageName = 'matterstorage' + (getParameter('profile') ? '.' + getParameter('profile') : '');
|
|
80
|
+
// Setup matter environment
|
|
43
81
|
this.environment.vars.set('log.level', MatterLogLevel.INFO);
|
|
44
82
|
this.environment.vars.set('log.format', MatterLogFormat.ANSI);
|
|
45
83
|
this.environment.vars.set('path.root', path.join(this.matterbridgeDirectory, this.matterStorageName));
|
|
46
84
|
this.environment.vars.set('runtime.signals', false);
|
|
47
85
|
this.environment.vars.set('runtime.exitcode', false);
|
|
86
|
+
// Setup Matter commissioning server
|
|
48
87
|
this.port = 5540;
|
|
49
88
|
this.passcode = PaseClient.generateRandomPasscode();
|
|
50
89
|
this.discriminator = PaseClient.generateRandomDiscriminator();
|
|
51
90
|
if (hasParameter('debug'))
|
|
52
91
|
console.log(`Initializing server node for Matterbridge... on port ${this.port} with passcode ${this.passcode} and discriminator ${this.discriminator}`);
|
|
92
|
+
// Initialize the base Matterbridge class
|
|
53
93
|
await super.initialize();
|
|
94
|
+
// Setup Matter mdnsInterface
|
|
54
95
|
if (this.mdnsInterface)
|
|
55
96
|
this.environment.vars.set('mdns.networkInterface', this.mdnsInterface);
|
|
56
97
|
}
|
|
57
98
|
async startMatterStorage(storageType, storageName) {
|
|
99
|
+
// Setup Matter storage
|
|
58
100
|
this.log.info(`Starting matter node storage...`);
|
|
59
101
|
this.matterStorageService = this.environment.get(StorageService);
|
|
60
102
|
this.log.info(`Matter node storage service created: ${this.matterStorageService.location}`);
|
|
@@ -62,6 +104,7 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
62
104
|
this.log.info('Matter node storage manager "Matterbridge" created');
|
|
63
105
|
this.matterbridgeContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', bridge.code, this.aggregatorVendorId, 'Matterbridge', this.aggregatorProductId, 'Matterbridge aggregator');
|
|
64
106
|
this.log.info('Matter node storage started');
|
|
107
|
+
// Backup matter storage since it is created/opened correctly
|
|
65
108
|
await this.backupMatterStorage(path.join(this.matterbridgeDirectory, this.matterStorageName), path.join(this.matterbridgeDirectory, this.matterStorageName + '.backup'));
|
|
66
109
|
}
|
|
67
110
|
async backupMatterStorage(storageName, backupName) {
|
|
@@ -77,6 +120,24 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
77
120
|
this.matterbridgeContext = undefined;
|
|
78
121
|
this.log.info('Matter node storage closed');
|
|
79
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Creates a server node storage context.
|
|
125
|
+
*
|
|
126
|
+
* @param pluginName - The name of the plugin.
|
|
127
|
+
* @param deviceName - The name of the device.
|
|
128
|
+
* @param deviceType - The deviceType of the device.
|
|
129
|
+
* @param vendorId - The vendor ID.
|
|
130
|
+
* @param vendorName - The vendor name.
|
|
131
|
+
* @param productId - The product ID.
|
|
132
|
+
* @param productName - The product name.
|
|
133
|
+
* @param serialNumber - The serial number of the device (optional).
|
|
134
|
+
* @param uniqueId - The unique ID of the device (optional).
|
|
135
|
+
* @param softwareVersion - The software version of the device (optional).
|
|
136
|
+
* @param softwareVersionString - The software version string of the device (optional).
|
|
137
|
+
* @param hardwareVersion - The hardware version of the device (optional).
|
|
138
|
+
* @param hardwareVersionString - The hardware version string of the device (optional).
|
|
139
|
+
* @returns The storage context for the commissioning server.
|
|
140
|
+
*/
|
|
80
141
|
async createServerNodeContext(pluginName, deviceName, deviceType, vendorId, vendorName, productId, productName, serialNumber) {
|
|
81
142
|
if (!this.matterStorageService)
|
|
82
143
|
throw new Error('No storage service initialized');
|
|
@@ -118,21 +179,33 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
118
179
|
this.log.debug(`- uniqueId: ${await storageContext.get('uniqueId')}`);
|
|
119
180
|
this.log.debug(`- softwareVersion: ${await storageContext.get('softwareVersion')} softwareVersionString: ${await storageContext.get('softwareVersionString')}`);
|
|
120
181
|
this.log.debug(`- hardwareVersion: ${await storageContext.get('hardwareVersion')} hardwareVersionString: ${await storageContext.get('hardwareVersionString')}`);
|
|
182
|
+
/**
|
|
183
|
+
* Create a Matter ServerNode, which contains the Root Endpoint and all relevant data and configuration
|
|
184
|
+
*/
|
|
121
185
|
const serverNode = await ServerNode.create({
|
|
186
|
+
// Required: Give the Node a unique ID which is used to store the state of this node
|
|
122
187
|
id: storeId,
|
|
188
|
+
// Provide Network relevant configuration like the port
|
|
189
|
+
// Optional when operating only one device on a host, Default port is 5540
|
|
123
190
|
network: {
|
|
124
191
|
listeningAddressIpv4: this.ipv4address,
|
|
125
192
|
listeningAddressIpv6: this.ipv6address,
|
|
126
193
|
port,
|
|
127
194
|
},
|
|
195
|
+
// Provide Commissioning relevant settings
|
|
196
|
+
// Optional for development/testing purposes
|
|
128
197
|
commissioning: {
|
|
129
198
|
passcode,
|
|
130
199
|
discriminator,
|
|
131
200
|
},
|
|
201
|
+
// Provide Node announcement settings
|
|
202
|
+
// Optional: If Ommitted some development defaults are used
|
|
132
203
|
productDescription: {
|
|
133
204
|
name: await storageContext.get('deviceName'),
|
|
134
205
|
deviceType: DeviceTypeId(await storageContext.get('deviceType')),
|
|
135
206
|
},
|
|
207
|
+
// Provide defaults for the BasicInformation cluster on the Root endpoint
|
|
208
|
+
// Optional: If Omitted some development defaults are used
|
|
136
209
|
basicInformation: {
|
|
137
210
|
vendorId: VendorId(await storageContext.get('vendorId')),
|
|
138
211
|
vendorName: await storageContext.get('vendorName'),
|
|
@@ -149,6 +222,7 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
149
222
|
},
|
|
150
223
|
});
|
|
151
224
|
const sanitizeFabrics = (fabrics) => {
|
|
225
|
+
// New type of fabric information: Record<FabricIndex, ExposedFabricInformation>
|
|
152
226
|
const sanitizedFabrics = this.sanitizeFabricInformations(Array.from(Object.values(serverNode.state.commissioning.fabrics)));
|
|
153
227
|
this.log.info(`Fabrics: ${debugStringify(sanitizedFabrics)}`);
|
|
154
228
|
if (this.bridgeMode === 'bridge') {
|
|
@@ -165,8 +239,14 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
165
239
|
}
|
|
166
240
|
}
|
|
167
241
|
};
|
|
242
|
+
/**
|
|
243
|
+
* This event is triggered when the device is initially commissioned successfully.
|
|
244
|
+
* This means: It is added to the first fabric.
|
|
245
|
+
*/
|
|
168
246
|
serverNode.lifecycle.commissioned.on(() => this.log.notice(`Server node for ${storeId} was initially commissioned successfully!`));
|
|
247
|
+
/** This event is triggered when all fabrics are removed from the device, usually it also does a factory reset then. */
|
|
169
248
|
serverNode.lifecycle.decommissioned.on(() => this.log.notice(`Server node for ${storeId} was fully decommissioned successfully!`));
|
|
249
|
+
/** This event is triggered when the device went online. This means that it is discoverable in the network. */
|
|
170
250
|
serverNode.lifecycle.online.on(() => {
|
|
171
251
|
this.log.notice(`Server node for ${storeId} is online`);
|
|
172
252
|
if (!serverNode.lifecycle.isCommissioned) {
|
|
@@ -201,6 +281,7 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
201
281
|
sanitizeFabrics(serverNode.state.commissioning.fabrics);
|
|
202
282
|
}
|
|
203
283
|
});
|
|
284
|
+
/** This event is triggered when the device went offline. it is not longer discoverable or connectable in the network. */
|
|
204
285
|
serverNode.lifecycle.offline.on(() => {
|
|
205
286
|
this.log.notice(`Server node for ${storeId} is offline`);
|
|
206
287
|
if (this.bridgeMode === 'bridge') {
|
|
@@ -212,6 +293,10 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
212
293
|
this.matterbridgeConnected = false;
|
|
213
294
|
}
|
|
214
295
|
});
|
|
296
|
+
/**
|
|
297
|
+
* This event is triggered when a fabric is added, removed or updated on the device. Use this if more granular
|
|
298
|
+
* information is needed.
|
|
299
|
+
*/
|
|
215
300
|
serverNode.events.commissioning.fabricsChanged.on((fabricIndex, fabricAction) => {
|
|
216
301
|
let action = '';
|
|
217
302
|
switch (fabricAction) {
|
|
@@ -244,14 +329,22 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
244
329
|
}
|
|
245
330
|
}
|
|
246
331
|
};
|
|
332
|
+
/**
|
|
333
|
+
* This event is triggered when an operative new session was opened by a Controller.
|
|
334
|
+
* It is not triggered for the initial commissioning process, just afterwards for real connections.
|
|
335
|
+
*/
|
|
247
336
|
serverNode.events.sessions.opened.on((session) => {
|
|
248
337
|
this.log.notice(`Session opened on server node for ${storeId}: ${debugStringify(session)}`);
|
|
249
338
|
sanitizeSessions(Object.values(serverNode.state.sessions.sessions));
|
|
250
339
|
});
|
|
340
|
+
/**
|
|
341
|
+
* This event is triggered when an operative session is closed by a Controller or because the Device goes offline.
|
|
342
|
+
*/
|
|
251
343
|
serverNode.events.sessions.closed.on((session) => {
|
|
252
344
|
this.log.notice(`Session closed on server node for ${storeId}: ${debugStringify(session)}`);
|
|
253
345
|
sanitizeSessions(Object.values(serverNode.state.sessions.sessions));
|
|
254
346
|
});
|
|
347
|
+
/** This event is triggered when a subscription gets added or removed on an operative session. */
|
|
255
348
|
serverNode.events.sessions.subscriptionsChanged.on((session) => {
|
|
256
349
|
this.log.notice(`Session subscriptions changed on server node for ${storeId}: ${debugStringify(session)}`);
|
|
257
350
|
sanitizeSessions(Object.values(serverNode.state.sessions.sessions));
|
|
@@ -277,11 +370,13 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
277
370
|
return aggregator;
|
|
278
371
|
}
|
|
279
372
|
async addBridgedEndpoint(pluginName, device) {
|
|
373
|
+
// Check if the plugin is registered
|
|
280
374
|
const plugin = this.plugins.get(pluginName);
|
|
281
375
|
if (!plugin) {
|
|
282
376
|
this.log.error(`Error adding bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.id}${er}) plugin ${plg}${pluginName}${er} not found`);
|
|
283
377
|
return;
|
|
284
378
|
}
|
|
379
|
+
// Register and add the device to the matterbridge aggregator node
|
|
285
380
|
if (this.bridgeMode === 'bridge') {
|
|
286
381
|
this.log.info(`Adding ${pluginName}:${device.deviceName} to Matterbridge aggregator node`);
|
|
287
382
|
const aggregatorNode = this.agToAggregatorEndpoint.get('Matterbridge')?.aggregatorNode;
|
|
@@ -317,16 +412,19 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
317
412
|
plugin.registeredDevices++;
|
|
318
413
|
if (plugin.addedDevices !== undefined)
|
|
319
414
|
plugin.addedDevices++;
|
|
415
|
+
// Add the device to the DeviceManager
|
|
320
416
|
this.devices.set(device);
|
|
321
417
|
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}`);
|
|
322
418
|
}
|
|
323
419
|
async removeBridgedEndpoint(pluginName, device) {
|
|
324
420
|
this.log.debug(`Removing bridged endpoint ${dev}${device.deviceName}${db} (${zb}${device.name}${db}) for plugin ${plg}${pluginName}${db}`);
|
|
421
|
+
// Check if the plugin is registered
|
|
325
422
|
const plugin = this.plugins.get(pluginName);
|
|
326
423
|
if (!plugin) {
|
|
327
424
|
this.log.error(`Error removing bridged endpoint ${dev}${device.deviceName}${er} (${zb}${device.name}${er}) for plugin ${plg}${pluginName}${er}: plugin not found`);
|
|
328
425
|
return;
|
|
329
426
|
}
|
|
427
|
+
// Register and add the device to the matterbridge aggregator node
|
|
330
428
|
if (this.bridgeMode === 'bridge') {
|
|
331
429
|
const aggregatoreNode = this.agToAggregatorEndpoint.get('Matterbridge')?.aggregatorNode;
|
|
332
430
|
if (!aggregatoreNode) {
|
|
@@ -342,6 +440,7 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
342
440
|
}
|
|
343
441
|
else if (this.bridgeMode === 'childbridge') {
|
|
344
442
|
if (plugin.type === 'AccessoryPlatform') {
|
|
443
|
+
// Nothing to do
|
|
345
444
|
}
|
|
346
445
|
else if (plugin.type === 'DynamicPlatform') {
|
|
347
446
|
const aggregatoreNode = this.agToAggregatorEndpoint.get(pluginName)?.aggregatorNode;
|
|
@@ -356,6 +455,7 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
356
455
|
plugin.registeredDevices--;
|
|
357
456
|
if (plugin.addedDevices !== undefined)
|
|
358
457
|
plugin.addedDevices--;
|
|
458
|
+
// Close the server node
|
|
359
459
|
if (plugin.registeredDevices === 0 && plugin.addedDevices === 0) {
|
|
360
460
|
const serverNode = this.csToServerNode.get(pluginName)?.serverNode;
|
|
361
461
|
if (serverNode)
|
|
@@ -364,6 +464,7 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
364
464
|
this.log.info(`Removed server node for plugin ${plg}${pluginName}${nf}`);
|
|
365
465
|
}
|
|
366
466
|
}
|
|
467
|
+
// Remove the device from the DeviceManager
|
|
367
468
|
this.devices.remove(device);
|
|
368
469
|
}
|
|
369
470
|
async removeAllBridgedEndpoints(pluginName) {
|
|
@@ -372,6 +473,9 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
372
473
|
await this.removeBridgedEndpoint(pluginName, device);
|
|
373
474
|
}
|
|
374
475
|
}
|
|
476
|
+
/**
|
|
477
|
+
* override from Matterbridge
|
|
478
|
+
*/
|
|
375
479
|
createMatterServer(storageManager) {
|
|
376
480
|
if (hasParameter('debug'))
|
|
377
481
|
this.log.warn('createMatterServer() => mock MatterServer.addCommissioningServer()');
|
|
@@ -435,6 +539,7 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
435
539
|
const commissioningServer = {
|
|
436
540
|
getPort: () => port,
|
|
437
541
|
addDevice: async (device) => {
|
|
542
|
+
// if (hasParameter('debug')) this.log.warn('CommissioningServer.addDevice()', device.name);
|
|
438
543
|
if (device instanceof Device) {
|
|
439
544
|
if (hasParameter('debug'))
|
|
440
545
|
this.log.warn('CommissioningServer.addDevice() => Device');
|
|
@@ -449,6 +554,7 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
449
554
|
await serverNode.add(aggregatorNode);
|
|
450
555
|
if (!this.test) {
|
|
451
556
|
this.test = true;
|
|
557
|
+
// await this.testEndpoints();
|
|
452
558
|
}
|
|
453
559
|
}
|
|
454
560
|
},
|
|
@@ -505,6 +611,37 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
505
611
|
const aggregatorNode = this.agToAggregatorEndpoint.get('Matterbridge')?.aggregatorNode;
|
|
506
612
|
if (!aggregatorNode)
|
|
507
613
|
return;
|
|
614
|
+
/*
|
|
615
|
+
this.log.notice(`Creating OnOffLight1`);
|
|
616
|
+
const lightEndpoint = new MatterbridgeEndpoint(onOffLight, { uniqueStorageKey: 'OnOffLight1' }, true);
|
|
617
|
+
lightEndpoint.addDeviceType(bridgedNode);
|
|
618
|
+
lightEndpoint.createDefaultBridgedDeviceBasicInformationClusterServer('OnOffLight 1', '123456789', 0xfff1, 'Matterbridge', 'Light');
|
|
619
|
+
lightEndpoint.addDeviceType(powerSource);
|
|
620
|
+
lightEndpoint.createDefaultPowerSourceWiredClusterServer();
|
|
621
|
+
lightEndpoint.addDeviceType(electricalSensor);
|
|
622
|
+
lightEndpoint.addClusterServer(lightEndpoint.getDefaultElectricalEnergyMeasurementClusterServer());
|
|
623
|
+
lightEndpoint.addClusterServer(lightEndpoint.getDefaultElectricalPowerMeasurementClusterServer());
|
|
624
|
+
lightEndpoint.addRequiredClusterServers(lightEndpoint);
|
|
625
|
+
this.log.notice(`Adding OnOffLight1 to ${await this.matterbridgeContext.get<string>('storeId')} aggregator`);
|
|
626
|
+
await aggregatorNode.add(lightEndpoint);
|
|
627
|
+
logEndpoint(EndpointServer.forEndpoint(lightEndpoint));
|
|
628
|
+
|
|
629
|
+
this.log.notice(`Creating Outlet1`);
|
|
630
|
+
const outletEndpoint = new MatterbridgeEndpoint(onOffOutlet, { uniqueStorageKey: 'OnOffOutlet1' }, true);
|
|
631
|
+
outletEndpoint.addDeviceType(bridgedNode);
|
|
632
|
+
outletEndpoint.createDefaultBridgedDeviceBasicInformationClusterServer('OnOffOutlet 1', '123456789', 0xfff1, 'Matterbridge', 'Outlet');
|
|
633
|
+
outletEndpoint.addDeviceType(powerSource);
|
|
634
|
+
outletEndpoint.createDefaultPowerSourceReplaceableBatteryClusterServer();
|
|
635
|
+
outletEndpoint.addDeviceType(electricalSensor);
|
|
636
|
+
outletEndpoint.addClusterServer(outletEndpoint.getDefaultElectricalEnergyMeasurementClusterServer());
|
|
637
|
+
outletEndpoint.addClusterServer(outletEndpoint.getDefaultElectricalPowerMeasurementClusterServer());
|
|
638
|
+
outletEndpoint.addRequiredClusterServers(outletEndpoint);
|
|
639
|
+
const input0 = outletEndpoint.addChildDeviceTypeWithClusterServer('Input:0', [genericSwitch], undefined, undefined, true);
|
|
640
|
+
const input1 = outletEndpoint.addChildDeviceTypeWithClusterServer('Input:1', [genericSwitch], undefined, undefined, true);
|
|
641
|
+
this.log.notice(`Adding OnOffOutlet1 to ${await this.matterbridgeContext.get<string>('storeId')} aggregator`);
|
|
642
|
+
await aggregatorNode.add(outletEndpoint);
|
|
643
|
+
logEndpoint(EndpointServer.forEndpoint(outletEndpoint));
|
|
644
|
+
*/
|
|
508
645
|
this.log.notice(`Creating switchEnpoint1`);
|
|
509
646
|
const switchEnpoint1 = new EndpointNode(GenericSwitchDevice.with(BridgedDeviceBasicInformationServer, SwitchServer.with('MomentarySwitch', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress', 'MomentarySwitchRelease')), {
|
|
510
647
|
id: 'GenericSwitch',
|
|
@@ -527,5 +664,398 @@ export class MatterbridgeEdge extends Matterbridge {
|
|
|
527
664
|
this.log.notice(`Adding switchEnpoint1 to ${await this.matterbridgeContext.get('storeId')} aggregator`);
|
|
528
665
|
await aggregatorNode.add(switchEnpoint1);
|
|
529
666
|
logEndpoint(EndpointServer.forEndpoint(switchEnpoint1), { logNotSupportedClusterAttributes: true, logNotSupportedClusterEvents: true, logNotSupportedClusterCommands: true });
|
|
667
|
+
// if (switchEnpoint2.behaviors.has(SwitchServer)) this.log.notice(`SwitchServer found`);
|
|
668
|
+
// switchEnpoint2.act((agent) => agent['switch'].events['initialPress'].emit({ newPosition: 1 }, agent.context));
|
|
669
|
+
/*
|
|
670
|
+
const device = new MatterbridgeEndpoint(genericSwitch, { uniqueStorageKey: 'GenericSwitch 2' }, true);
|
|
671
|
+
device.createDefaultSwitchClusterServer();
|
|
672
|
+
device.addRequiredClusterServers(device);
|
|
673
|
+
await aggregatorNode.add(device);
|
|
674
|
+
logEndpoint(EndpointServer.forEndpoint(device));
|
|
675
|
+
await device.triggerSwitchEvent('Single', this.log);
|
|
676
|
+
await device.triggerSwitchEvent('Double', this.log);
|
|
677
|
+
await device.triggerSwitchEvent('Long', this.log);
|
|
678
|
+
|
|
679
|
+
const device1 = new MatterbridgeEndpoint(genericSwitch, { uniqueStorageKey: 'GenericSwitch 3' }, true);
|
|
680
|
+
device1.createDefaultLatchingSwitchClusterServer();
|
|
681
|
+
device1.addRequiredClusterServers(device1);
|
|
682
|
+
await aggregatorNode.add(device1);
|
|
683
|
+
logEndpoint(EndpointServer.forEndpoint(device1));
|
|
684
|
+
await device1.triggerSwitchEvent('Press', this.log);
|
|
685
|
+
await device1.triggerSwitchEvent('Release', this.log);
|
|
686
|
+
|
|
687
|
+
this.log.notice(`Creating TestLight`);
|
|
688
|
+
const matterbridgeDevice = new MatterbridgeEndpoint(onOffLight, { uniqueStorageKey: 'Test .Light:2' }, true);
|
|
689
|
+
matterbridgeDevice.behaviors.require(MatterbridgeIdentifyServer, {
|
|
690
|
+
identifyTime: 0,
|
|
691
|
+
identifyType: Identify.IdentifyType.None,
|
|
692
|
+
});
|
|
693
|
+
matterbridgeDevice.behaviors.require(GroupsServer);
|
|
694
|
+
matterbridgeDevice.behaviors.require(MatterbridgeOnOffServer, {
|
|
695
|
+
onOff: false,
|
|
696
|
+
});
|
|
697
|
+
matterbridgeDevice.behaviors.require(MatterbridgeLevelControlServer, {
|
|
698
|
+
currentLevel: 0,
|
|
699
|
+
options: { executeIfOff: false },
|
|
700
|
+
});
|
|
701
|
+
matterbridgeDevice.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.Xy, ColorControl.Feature.ColorTemperature), {
|
|
702
|
+
colorCapabilities: { xy: true, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: true },
|
|
703
|
+
colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
|
|
704
|
+
enhancedColorMode: ColorControl.EnhancedColorMode.ColorTemperatureMireds,
|
|
705
|
+
options: { executeIfOff: false },
|
|
706
|
+
numberOfPrimaries: null,
|
|
707
|
+
currentX: 24939,
|
|
708
|
+
currentY: 24701,
|
|
709
|
+
currentHue: 0,
|
|
710
|
+
currentSaturation: 0,
|
|
711
|
+
colorTemperatureMireds: 450,
|
|
712
|
+
colorTempPhysicalMinMireds: 150,
|
|
713
|
+
colorTempPhysicalMaxMireds: 450,
|
|
714
|
+
coupleColorTempToLevelMinMireds: 150,
|
|
715
|
+
startUpColorTemperatureMireds: null,
|
|
716
|
+
});
|
|
717
|
+
matterbridgeDevice.behaviors.require(BridgedDeviceBasicInformationServer, {
|
|
718
|
+
vendorId: VendorId(await this.matterbridgeContext.get<number>('vendorId')),
|
|
719
|
+
vendorName: await this.matterbridgeContext.get<string>('vendorName'),
|
|
720
|
+
productName: 'TestLight2',
|
|
721
|
+
productLabel: 'TestLight2',
|
|
722
|
+
nodeLabel: 'TestLight2',
|
|
723
|
+
serialNumber: 'SN 0x123456789',
|
|
724
|
+
uniqueId: '0x123456789',
|
|
725
|
+
reachable: true,
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
// await matterbridgeDevice.setTagList(null, 0x07, 1, 'endpoint 2');
|
|
729
|
+
// await matterbridgeDevice.configureColorControlCluster(false, false, true, ColorControl.ColorMode.ColorTemperatureMireds);
|
|
730
|
+
|
|
731
|
+
this.log.notice(`Adding TestLight`);
|
|
732
|
+
await aggregatorNode?.add(matterbridgeDevice);
|
|
733
|
+
|
|
734
|
+
this.log.notice(`Creating switchEnpoint1`);
|
|
735
|
+
const switchEnpoint2 = new EndpointNode(
|
|
736
|
+
GenericSwitchDevice.with(DescriptorServer.with(Descriptor.Feature.TagList), BridgedDeviceBasicInformationServer, SwitchServer.with('MomentarySwitch', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress', 'MomentarySwitchRelease')),
|
|
737
|
+
{
|
|
738
|
+
id: 'GenericSwitch1',
|
|
739
|
+
descriptor: {
|
|
740
|
+
tagList: [{ mfgCode: null, namespaceId: 0x07, tag: 1, label: 'Switch1' }],
|
|
741
|
+
},
|
|
742
|
+
bridgedDeviceBasicInformation: {
|
|
743
|
+
vendorId: VendorId(await this.matterbridgeContext.get<number>('vendorId')),
|
|
744
|
+
vendorName: await this.matterbridgeContext.get<string>('vendorName'),
|
|
745
|
+
|
|
746
|
+
productName: 'GenericSwitch',
|
|
747
|
+
productLabel: 'GenericSwitch',
|
|
748
|
+
nodeLabel: 'GenericSwitch',
|
|
749
|
+
|
|
750
|
+
serialNumber: 'SN 0x1234567397',
|
|
751
|
+
uniqueId: '0x1234567397',
|
|
752
|
+
reachable: true,
|
|
753
|
+
},
|
|
754
|
+
switch: {
|
|
755
|
+
numberOfPositions: 2,
|
|
756
|
+
currentPosition: 0,
|
|
757
|
+
multiPressMax: 2,
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
);
|
|
761
|
+
this.log.notice(`Creating switchEnpoint2`);
|
|
762
|
+
await aggregatorNode?.add(switchEnpoint2);
|
|
763
|
+
*/
|
|
764
|
+
/*
|
|
765
|
+
const lightEndpoint1 = new EndpointNode(ColorTemperatureLightDevice.with(BridgedDeviceBasicInformationServer), {
|
|
766
|
+
// }, MatterbridgeIdentifyServer, MatterbridgeOnOffServer, MatterbridgeLevelControlServer, MatterbridgeColorControlServer), {
|
|
767
|
+
id: 'OnOffLight',
|
|
768
|
+
bridgedDeviceBasicInformation: {
|
|
769
|
+
vendorId: VendorId(await this.matterbridgeContext.get<number>('vendorId')),
|
|
770
|
+
vendorName: await this.matterbridgeContext.get<string>('vendorName'),
|
|
771
|
+
|
|
772
|
+
productName: 'Light',
|
|
773
|
+
productLabel: 'Light',
|
|
774
|
+
nodeLabel: 'Light',
|
|
775
|
+
|
|
776
|
+
serialNumber: 'SN 0x123456789',
|
|
777
|
+
uniqueId: '0x123456789',
|
|
778
|
+
reachable: true,
|
|
779
|
+
},
|
|
780
|
+
levelControl: {
|
|
781
|
+
currentLevel: 0,
|
|
782
|
+
options: { executeIfOff: false, coupleColorTempToLevel: false },
|
|
783
|
+
},
|
|
784
|
+
colorControl: {
|
|
785
|
+
colorTemperatureMireds: 450,
|
|
786
|
+
colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
|
|
787
|
+
colorTempPhysicalMinMireds: 150,
|
|
788
|
+
colorTempPhysicalMaxMireds: 450,
|
|
789
|
+
coupleColorTempToLevelMinMireds: 150,
|
|
790
|
+
startUpColorTemperatureMireds: 450,
|
|
791
|
+
},
|
|
792
|
+
});
|
|
793
|
+
lightEndpoint1.behaviors.require(ColorControlServer.with('ColorTemperature'), {
|
|
794
|
+
colorTemperatureMireds: 450,
|
|
795
|
+
colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
|
|
796
|
+
colorTempPhysicalMinMireds: 150,
|
|
797
|
+
colorTempPhysicalMaxMireds: 450,
|
|
798
|
+
coupleColorTempToLevelMinMireds: 150,
|
|
799
|
+
startUpColorTemperatureMireds: 450,
|
|
800
|
+
});
|
|
801
|
+
await aggregatorNode?.add(lightEndpoint1);
|
|
802
|
+
|
|
803
|
+
/*
|
|
804
|
+
lightEndpoint1.behaviors.require(MatterbridgeIdentifyServer);
|
|
805
|
+
lightEndpoint1.behaviors.require(MatterbridgeOnOffServer);
|
|
806
|
+
lightEndpoint1.behaviors.require(MatterbridgeLevelControlServer);
|
|
807
|
+
lightEndpoint1.behaviors.require(MatterbridgeColorControlServer, {
|
|
808
|
+
colorTemperatureMireds: 250,
|
|
809
|
+
colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
|
|
810
|
+
colorTempPhysicalMinMireds: 150,
|
|
811
|
+
colorTempPhysicalMaxMireds: 450,
|
|
812
|
+
coupleColorTempToLevelMinMireds: 150,
|
|
813
|
+
startUpColorTemperatureMireds: 450,
|
|
814
|
+
});
|
|
815
|
+
await aggregatorNode?.add(lightEndpoint1);
|
|
816
|
+
|
|
817
|
+
this.log.notice(`Creating switchEnpoint2`);
|
|
818
|
+
const switchEnpoint2 = new EndpointNode(GenericSwitchDevice.with(BridgedDeviceBasicInformationServer, SwitchServer.with('MomentarySwitch', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress', 'MomentarySwitchRelease')), {
|
|
819
|
+
id: 'GenericSwitch',
|
|
820
|
+
bridgedDeviceBasicInformation: {
|
|
821
|
+
vendorId: VendorId(await this.matterbridgeContext.get<number>('vendorId')),
|
|
822
|
+
vendorName: await this.matterbridgeContext.get<string>('vendorName'),
|
|
823
|
+
|
|
824
|
+
productName: 'GenericSwitch',
|
|
825
|
+
productLabel: 'GenericSwitch',
|
|
826
|
+
nodeLabel: 'GenericSwitch',
|
|
827
|
+
|
|
828
|
+
serialNumber: 'SN 0x123456739',
|
|
829
|
+
uniqueId: '0x123456739',
|
|
830
|
+
reachable: true,
|
|
831
|
+
},
|
|
832
|
+
switch: {
|
|
833
|
+
numberOfPositions: 2,
|
|
834
|
+
currentPosition: 0,
|
|
835
|
+
multiPressMax: 2,
|
|
836
|
+
},
|
|
837
|
+
});
|
|
838
|
+
await aggregatorNode?.add(switchEnpoint2);
|
|
839
|
+
*/
|
|
840
|
+
/*
|
|
841
|
+
for (let i = 1; i <= max; i++) {
|
|
842
|
+
this.log.notice(`Creating lightEndpoint${i}`);
|
|
843
|
+
const lightEndpoint = new MatterbridgeEndpoint(onOffLight, { uniqueStorageKey: 'OnOffLight' + i });
|
|
844
|
+
lightEndpoint.addClusterServer(lightEndpoint.getDefaultBridgedDeviceBasicInformationClusterServer('OnOffLight' + i, '123456789', 0xfff1, 'Matterbridge', 'Light'));
|
|
845
|
+
this.log.notice(`Adding lightEndpoint${i} to ${await this.matterbridgeContext.get<string>('storeId')} aggregator`);
|
|
846
|
+
await aggregatorNode?.add(lightEndpoint);
|
|
847
|
+
setInterval(async () => {
|
|
848
|
+
const state = lightEndpoint.getAttribute(OnOffCluster.id, 'onOff');
|
|
849
|
+
lightEndpoint.setAttribute(OnOffCluster.id, 'onOff', !state);
|
|
850
|
+
this.log.notice(`Setting state for lightEndpoint${i} from:`, state, 'to:', !state);
|
|
851
|
+
}, 10000);
|
|
852
|
+
}
|
|
853
|
+
for (let i = 1; i <= max; i++) {
|
|
854
|
+
this.log.notice(`Creating outletEndpoint${i}`);
|
|
855
|
+
const lightEndpoint = new MatterbridgeEndpoint(onOffOutlet, { uniqueStorageKey: 'OnOffOutlet' + i });
|
|
856
|
+
lightEndpoint.addClusterServer(lightEndpoint.getDefaultBridgedDeviceBasicInformationClusterServer('OnOffOutlet' + i, '123456789', 0xfff1, 'Matterbridge', 'Outlet'));
|
|
857
|
+
this.log.notice(`Adding outletEndpoint${i} to ${await this.matterbridgeContext.get<string>('storeId')} aggregator`);
|
|
858
|
+
await aggregatorNode?.add(lightEndpoint);
|
|
859
|
+
setInterval(async () => {
|
|
860
|
+
const state = lightEndpoint.getAttribute(OnOffCluster.id, 'onOff');
|
|
861
|
+
lightEndpoint.setAttribute(OnOffCluster.id, 'onOff', !state);
|
|
862
|
+
this.log.notice(`Setting state for outletEndpoint${i} from:`, state, 'to:', !state);
|
|
863
|
+
}, 10000);
|
|
864
|
+
}
|
|
865
|
+
*/
|
|
530
866
|
}
|
|
531
867
|
}
|
|
868
|
+
/*
|
|
869
|
+
/*
|
|
870
|
+
matterbridgeDevice.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.Xy, ColorControl.Feature.ColorTemperature), {
|
|
871
|
+
colorCapabilities: { xy: true, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: true },
|
|
872
|
+
colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
|
|
873
|
+
enhancedColorMode: ColorControl.EnhancedColorMode.ColorTemperatureMireds,
|
|
874
|
+
options: { executeIfOff: false },
|
|
875
|
+
numberOfPrimaries: null,
|
|
876
|
+
currentX: 24939,
|
|
877
|
+
currentY: 24701,
|
|
878
|
+
currentHue: 0,
|
|
879
|
+
currentSaturation: 0,
|
|
880
|
+
colorTemperatureMireds: 450,
|
|
881
|
+
colorTempPhysicalMinMireds: 150,
|
|
882
|
+
colorTempPhysicalMaxMireds: 450,
|
|
883
|
+
coupleColorTempToLevelMinMireds: 150,
|
|
884
|
+
startUpColorTemperatureMireds: null,
|
|
885
|
+
});
|
|
886
|
+
matterbridgeDevice.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.ColorTemperature), {
|
|
887
|
+
colorCapabilities: { xy: false, hueSaturation: false, colorLoop: false, enhancedHue: false, colorTemperature: true },
|
|
888
|
+
colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
|
|
889
|
+
enhancedColorMode: ColorControl.EnhancedColorMode.ColorTemperatureMireds,
|
|
890
|
+
options: { executeIfOff: false },
|
|
891
|
+
numberOfPrimaries: null,
|
|
892
|
+
colorTemperatureMireds: 450,
|
|
893
|
+
colorTempPhysicalMinMireds: 150,
|
|
894
|
+
colorTempPhysicalMaxMireds: 450,
|
|
895
|
+
coupleColorTempToLevelMinMireds: 150,
|
|
896
|
+
startUpColorTemperatureMireds: null,
|
|
897
|
+
});
|
|
898
|
+
*/
|
|
899
|
+
/*
|
|
900
|
+
matterbridgeDevice.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.Xy), {
|
|
901
|
+
colorCapabilities: { xy: true, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: false },
|
|
902
|
+
colorMode: ColorControl.ColorMode.CurrentHueAndCurrentSaturation,
|
|
903
|
+
enhancedColorMode: ColorControl.EnhancedColorMode.CurrentHueAndCurrentSaturation,
|
|
904
|
+
options: { executeIfOff: false },
|
|
905
|
+
numberOfPrimaries: null,
|
|
906
|
+
currentX: 24939,
|
|
907
|
+
currentY: 24701,
|
|
908
|
+
currentHue: 0,
|
|
909
|
+
currentSaturation: 0,
|
|
910
|
+
});
|
|
911
|
+
// node dist/matterbridgeEdge.js MatterbridgeEdge -debug -ssl -frontend 443
|
|
912
|
+
if (process.argv.includes('MatterbridgeEdge')) {
|
|
913
|
+
const matterbridge = await MatterbridgeEdge.loadInstance(true);
|
|
914
|
+
|
|
915
|
+
process.on('SIGINT', async function () {
|
|
916
|
+
// eslint-disable-next-line no-console
|
|
917
|
+
console.log('Caught interrupt signal');
|
|
918
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
919
|
+
if (matterbridge) await (matterbridge as any).cleanup('shutting down...', false);
|
|
920
|
+
// if (matterbridge && matterbridge.matterServerNode && matterbridge.matterServerNodeContext) await matterbridge.stopServerNode(matterbridge.matterServerNode, matterbridge.matterServerNodeContext);
|
|
921
|
+
const exit = setTimeout(() => {
|
|
922
|
+
// eslint-disable-next-line no-console
|
|
923
|
+
console.log('Exiting after caught interrupt signal');
|
|
924
|
+
process.exit();
|
|
925
|
+
}, 10000);
|
|
926
|
+
exit.unref();
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
*/
|
|
930
|
+
/*
|
|
931
|
+
async startBridgeNode(): Promise<void> {
|
|
932
|
+
this.log.notice(`Creating lightEndpoint1`);
|
|
933
|
+
const lightEndpoint1 = new Endpoint(OnOffLightDevice.with(BridgedDeviceBasicInformationServer), {
|
|
934
|
+
id: 'OnOffLight',
|
|
935
|
+
bridgedDeviceBasicInformation: {
|
|
936
|
+
vendorId: VendorId(await storageContext.get<number>('vendorId')),
|
|
937
|
+
vendorName: await storageContext.get<string>('vendorName'),
|
|
938
|
+
|
|
939
|
+
productName: 'Light',
|
|
940
|
+
productLabel: 'Light',
|
|
941
|
+
nodeLabel: 'Light',
|
|
942
|
+
|
|
943
|
+
serialNumber: 'SN 0x123456789',
|
|
944
|
+
uniqueId: '0x123456789',
|
|
945
|
+
reachable: true,
|
|
946
|
+
},
|
|
947
|
+
});
|
|
948
|
+
this.log.notice(`Adding lightEndpoint1 to ${await storageContext.get<string>('storeId')} aggregator`);
|
|
949
|
+
await this.matterAggregatorNode.add(lightEndpoint1);
|
|
950
|
+
// logEndpoint(EndpointServer.forEndpoint(lightEndpoint1));
|
|
951
|
+
|
|
952
|
+
this.log.notice(`Creating switchEnpoint2`);
|
|
953
|
+
const switchEnpoint2 = new Endpoint(GenericSwitchDevice.with(BridgedDeviceBasicInformationServer, SwitchServer.with('MomentarySwitch', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress', 'MomentarySwitchRelease')), {
|
|
954
|
+
id: 'GenericSwitch',
|
|
955
|
+
bridgedDeviceBasicInformation: {
|
|
956
|
+
vendorId: VendorId(await storageContext.get<number>('vendorId')),
|
|
957
|
+
vendorName: await storageContext.get<string>('vendorName'),
|
|
958
|
+
|
|
959
|
+
productName: 'GenericSwitch',
|
|
960
|
+
productLabel: 'GenericSwitch',
|
|
961
|
+
nodeLabel: 'GenericSwitch',
|
|
962
|
+
|
|
963
|
+
serialNumber: 'SN 0x123456739',
|
|
964
|
+
uniqueId: '0x123456739',
|
|
965
|
+
reachable: true,
|
|
966
|
+
},
|
|
967
|
+
switch: {
|
|
968
|
+
numberOfPositions: 2,
|
|
969
|
+
currentPosition: 0,
|
|
970
|
+
multiPressMax: 2,
|
|
971
|
+
},
|
|
972
|
+
});
|
|
973
|
+
this.log.notice(`Adding switchEnpoint2 to ${await storageContext.get<string>('storeId')} aggregator`);
|
|
974
|
+
await this.matterAggregatorNode.add(switchEnpoint2);
|
|
975
|
+
// logEndpoint(EndpointServer.forEndpoint(switchEnpoint2));
|
|
976
|
+
|
|
977
|
+
// switchEnpoint2.events.identify.startIdentifying.on(() => this.log.notice('GenericSwitch.identify logic, ideally blink a light every 0.5s ...'));
|
|
978
|
+
// switchEnpoint2.events.switch.currentPosition$Changed.on(() => this.log.notice('GenericSwitch.currentPosition changed ...'));
|
|
979
|
+
// switchEnpoint2.act((agent) => agent.switch.events.initialPress.emit({ newPosition: 1 }, agent.context));
|
|
980
|
+
// switchEnpoint2.events.switch.emit('initialPress', { newPosition: 1 }, switchEnpoint2.events.switch.context);
|
|
981
|
+
*/
|
|
982
|
+
/*
|
|
983
|
+
log.notice(`Creating matterbridge device ClimateSensor`);
|
|
984
|
+
const matterbridgeDevice3 = new MatterbridgeDeviceV8(DeviceTypes.TEMPERATURE_SENSOR, { uniqueStorageKey: 'ClimateSensor' });
|
|
985
|
+
matterbridgeDevice3.addDeviceTypeWithClusterServer([DeviceTypes.TEMPERATURE_SENSOR], [TemperatureMeasurement.Cluster.id]);
|
|
986
|
+
matterbridgeDevice3.addDeviceTypeWithClusterServer([DeviceTypes.HUMIDITY_SENSOR], [RelativeHumidityMeasurement.Cluster.id]);
|
|
987
|
+
matterbridgeDevice3.addDeviceTypeWithClusterServer([DeviceTypes.PRESSURE_SENSOR], [PressureMeasurement.Cluster.id]);
|
|
988
|
+
matterbridgeDevice3.behaviors.require(IdentifyServer, {
|
|
989
|
+
identifyTime: 5,
|
|
990
|
+
});
|
|
991
|
+
matterbridgeDevice3.behaviors.require(TemperatureMeasurementServer, {
|
|
992
|
+
measuredValue: 25.0,
|
|
993
|
+
minMeasuredValue: null,
|
|
994
|
+
maxMeasuredValue: null,
|
|
995
|
+
});
|
|
996
|
+
*/
|
|
997
|
+
/*
|
|
998
|
+
log.notice(`Adding BridgedDeviceBasicInformationServer to ClimateSensor`);
|
|
999
|
+
matterbridgeDevice3.behaviors.require(BridgedDeviceBasicInformationServer, {
|
|
1000
|
+
vendorId: VendorId(await storageContext.get<number>('vendorId')),
|
|
1001
|
+
vendorName: await storageContext.get<string>('vendorName'),
|
|
1002
|
+
|
|
1003
|
+
productName: 'ClimateSensor',
|
|
1004
|
+
productLabel: 'ClimateSensor',
|
|
1005
|
+
nodeLabel: 'ClimateSensor',
|
|
1006
|
+
|
|
1007
|
+
serialNumber: '0x145433356739',
|
|
1008
|
+
uniqueId: '0x1254446739',
|
|
1009
|
+
reachable: true,
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
log.notice(`Adding DescriptorServer to ClimateSensor`);
|
|
1013
|
+
matterbridgeDevice3.behaviors.require(DescriptorServer, {
|
|
1014
|
+
deviceTypeList: [
|
|
1015
|
+
{ deviceType: 0x0302, revision: 2 },
|
|
1016
|
+
{ deviceType: 0x0307, revision: 2 },
|
|
1017
|
+
{ deviceType: 0x0305, revision: 2 },
|
|
1018
|
+
],
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
this.log.notice(`Adding ClimateSensor to ${await storageContext.get<string>('storeId')} aggregator`);
|
|
1022
|
+
await this.matterAggregator.add(matterbridgeDevice3);
|
|
1023
|
+
logEndpoint(EndpointServer.forEndpoint(matterbridgeDevice3));
|
|
1024
|
+
*/
|
|
1025
|
+
/*
|
|
1026
|
+
await lightEndpoint1.set({
|
|
1027
|
+
onOff: {
|
|
1028
|
+
onOff: true,
|
|
1029
|
+
},
|
|
1030
|
+
});
|
|
1031
|
+
await switchEnpoint2.set({
|
|
1032
|
+
switch: {
|
|
1033
|
+
currentPosition: 1,
|
|
1034
|
+
},
|
|
1035
|
+
});
|
|
1036
|
+
switchEnpoint2.act((agent) => agent.switch.events.initialPress.emit({ newPosition: 1 }, agent.context));
|
|
1037
|
+
*/
|
|
1038
|
+
/*
|
|
1039
|
+
await matterbridgeDevice3.set({
|
|
1040
|
+
temperatureMeasurement: {
|
|
1041
|
+
measuredValue: 20 * 100,
|
|
1042
|
+
},
|
|
1043
|
+
relativeHumidityMeasurement: {
|
|
1044
|
+
measuredValue: 50 * 100,
|
|
1045
|
+
},
|
|
1046
|
+
});
|
|
1047
|
+
*/
|
|
1048
|
+
// logEndpoint(EndpointServer.forEndpoint(this.matterServerNode));
|
|
1049
|
+
/*
|
|
1050
|
+
logEndpoint(EndpointServer.forEndpoint(this.matterServerNode));
|
|
1051
|
+
logEndpoint(EndpointServer.forEndpoint(matterbridgeDevice3));
|
|
1052
|
+
console.log('matterbridgeDevice3\n', matterbridgeDevice3);
|
|
1053
|
+
console.log('matterbridgeDevice3.events\n', matterbridgeDevice3.events);
|
|
1054
|
+
console.log('matterbridgeDevice3.events.identify\n', matterbridgeDevice3.eventsOf(IdentifyServer));
|
|
1055
|
+
console.log('matterbridgeDevice3.state\n', matterbridgeDevice3.state);
|
|
1056
|
+
console.log('matterbridgeDevice3.state.temperatureMeasurement\n', matterbridgeDevice3.stateOf(TemperatureMeasurementServer));
|
|
1057
|
+
// matterbridgeDevice3.eventsOf(IdentifyServer);
|
|
1058
|
+
// matterbridgeDevice3.events.identify.startIdentifying.on(() => log.notice('Run identify logic, ideally blink a light every 0.5s ...'));
|
|
1059
|
+
}
|
|
1060
|
+
*/
|
|
1061
|
+
//# sourceMappingURL=matterbridgeEdge.js.map
|