@matterbridge/core 3.10.0-dev-20260716-572b03b → 3.10.0-dev-20260716-7f8762c
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/dist/deviceManager.js +3 -1
- package/dist/matterNode.d.ts +1 -1
- package/dist/matterNode.js +36 -13
- package/dist/matterbridge.js +19 -11
- package/dist/matterbridgeEndpoint.d.ts +5 -3
- package/dist/matterbridgeEndpoint.js +39 -11
- package/dist/matterbridgeEndpointTypes.d.ts +7 -0
- package/dist/matterbridgePlatform.js +1 -1
- package/package.json +5 -5
package/dist/deviceManager.js
CHANGED
|
@@ -16,11 +16,13 @@ export function toBaseDevice(device) {
|
|
|
16
16
|
vendorName: device.vendorName,
|
|
17
17
|
productId: device.productId,
|
|
18
18
|
productName: device.productName,
|
|
19
|
+
productLabel: device.productLabel,
|
|
20
|
+
productUrl: device.productUrl,
|
|
21
|
+
configurationVersion: device.configurationVersion,
|
|
19
22
|
softwareVersion: device.softwareVersion,
|
|
20
23
|
softwareVersionString: device.softwareVersionString,
|
|
21
24
|
hardwareVersion: device.hardwareVersion,
|
|
22
25
|
hardwareVersionString: device.hardwareVersionString,
|
|
23
|
-
productUrl: device.productUrl,
|
|
24
26
|
tagList: device.tagList,
|
|
25
27
|
originalId: device.originalId,
|
|
26
28
|
name: device.name,
|
package/dist/matterNode.d.ts
CHANGED
|
@@ -58,7 +58,7 @@ export declare class MatterNode extends EventEmitter<MatterEvents> {
|
|
|
58
58
|
startMatterStorage(): Promise<void>;
|
|
59
59
|
backupMatterStorage(storageName: string, backupName: string): Promise<void>;
|
|
60
60
|
stopMatterStorage(): Promise<void>;
|
|
61
|
-
createServerNodeContext(storeId: string, deviceName: string, deviceType: DeviceTypeId, vendorId: VendorId, vendorName: string, productId: number, productName: string, serialNumber?: string, uniqueId?: string): Promise<StorageContext>;
|
|
61
|
+
createServerNodeContext(storeId: string, deviceName: string, deviceType: DeviceTypeId, vendorId: VendorId, vendorName: string, productId: number, productName: string, serialNumber?: string, uniqueId?: string, softwareVersion?: number, softwareVersionString?: string, hardwareVersion?: number, hardwareVersionString?: string, productLabel?: string, productUrl?: string, configurationVersion?: number): Promise<StorageContext>;
|
|
62
62
|
createServerNode(port?: number, passcode?: number, discriminator?: number): Promise<ServerNode>;
|
|
63
63
|
getServerNodeData(serverNode: ServerNode): ApiMatter;
|
|
64
64
|
startServerNode(timeout?: number): Promise<void>;
|
package/dist/matterNode.js
CHANGED
|
@@ -15,7 +15,7 @@ import { getIntParameter, getParameter, hasParameter } from '@matterbridge/utils
|
|
|
15
15
|
import { copyDirectory } from '@matterbridge/utils/copy-dir';
|
|
16
16
|
import { getErrorMessage, inspectError } from '@matterbridge/utils/error';
|
|
17
17
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
18
|
-
import {
|
|
18
|
+
import { isValidInteger, isValidString, parseVersionString } from '@matterbridge/utils/validate';
|
|
19
19
|
import { wait, withTimeout } from '@matterbridge/utils/wait';
|
|
20
20
|
import { AnsiLogger, BLUE, CYAN, db, debugStringify, er, nf, or, zb } from 'node-ansi-logger';
|
|
21
21
|
import { NodeStorageManager } from 'node-persist-manager';
|
|
@@ -328,7 +328,7 @@ export class MatterNode extends EventEmitter {
|
|
|
328
328
|
this.log.info('Closed matter node storage');
|
|
329
329
|
this.emit('closed');
|
|
330
330
|
}
|
|
331
|
-
async createServerNodeContext(storeId, deviceName, deviceType, vendorId, vendorName, productId, productName, serialNumber, uniqueId) {
|
|
331
|
+
async createServerNodeContext(storeId, deviceName, deviceType, vendorId, vendorName, productId, productName, serialNumber, uniqueId, softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0', productLabel = 'Matter Endpoint', productUrl = 'https://matterbridge.io', configurationVersion = 1) {
|
|
332
332
|
if (!this.matterStorageService) {
|
|
333
333
|
throw new Error('No storage service initialized');
|
|
334
334
|
}
|
|
@@ -344,14 +344,16 @@ export class MatterNode extends EventEmitter {
|
|
|
344
344
|
await storageContext.set('vendorName', vendorName.slice(0, 32));
|
|
345
345
|
await storageContext.set('productId', productId);
|
|
346
346
|
await storageContext.set('productName', productName.slice(0, 32));
|
|
347
|
-
await storageContext.set('
|
|
348
|
-
await storageContext.set('
|
|
347
|
+
await storageContext.set('productLabel', productLabel.replace(vendorName, '').trim().slice(0, 64));
|
|
348
|
+
await storageContext.set('productUrl', isValidString(productUrl, 8, 256) && productUrl.startsWith('https://') ? productUrl : 'https://matterbridge.io');
|
|
349
|
+
await storageContext.set('nodeLabel', deviceName.slice(0, 32));
|
|
349
350
|
await storageContext.set('serialNumber', await storageContext.get('serialNumber', serialNumber ? serialNumber.slice(0, 32) : 'SN' + random));
|
|
350
351
|
await storageContext.set('uniqueId', await storageContext.get('uniqueId', uniqueId ? uniqueId.slice(0, 32) : 'UI' + random));
|
|
351
|
-
await storageContext.set('softwareVersion',
|
|
352
|
-
await storageContext.set('softwareVersionString', isValidString(
|
|
353
|
-
await storageContext.set('hardwareVersion',
|
|
354
|
-
await storageContext.set('hardwareVersionString', isValidString(
|
|
352
|
+
await storageContext.set('softwareVersion', isValidInteger(softwareVersion, 0, UINT32_MAX) ? softwareVersion : 1);
|
|
353
|
+
await storageContext.set('softwareVersionString', isValidString(softwareVersionString, 1, 64) ? softwareVersionString : '1.0.0');
|
|
354
|
+
await storageContext.set('hardwareVersion', isValidInteger(hardwareVersion, 0, UINT16_MAX) ? hardwareVersion : 1);
|
|
355
|
+
await storageContext.set('hardwareVersionString', isValidString(hardwareVersionString, 1, 64) ? hardwareVersionString : '1.0.0');
|
|
356
|
+
await storageContext.set('configurationVersion', isValidInteger(configurationVersion, 1, UINT32_MAX) ? configurationVersion : 1);
|
|
355
357
|
this.log.debug(`Created server node storage context "${storeId}.persist" for ${storeId}:`);
|
|
356
358
|
this.log.debug(`- storeId: ${await storageContext.get('storeId')}`);
|
|
357
359
|
this.log.debug(`- deviceName: ${await storageContext.get('deviceName')}`);
|
|
@@ -360,14 +362,16 @@ export class MatterNode extends EventEmitter {
|
|
|
360
362
|
this.log.debug(`- vendorName: ${await storageContext.get('vendorName')}`);
|
|
361
363
|
this.log.debug(`- productId: ${await storageContext.get('productId')}`);
|
|
362
364
|
this.log.debug(`- productName: ${await storageContext.get('productName')}`);
|
|
363
|
-
this.log.debug(`- nodeLabel: ${await storageContext.get('nodeLabel')}`);
|
|
364
365
|
this.log.debug(`- productLabel: ${await storageContext.get('productLabel')}`);
|
|
366
|
+
this.log.debug(`- productUrl: ${await storageContext.get('productUrl')}`);
|
|
367
|
+
this.log.debug(`- nodeLabel: ${await storageContext.get('nodeLabel')}`);
|
|
365
368
|
this.log.debug(`- serialNumber: ${await storageContext.get('serialNumber')}`);
|
|
366
369
|
this.log.debug(`- uniqueId: ${await storageContext.get('uniqueId')}`);
|
|
367
370
|
this.log.debug(`- softwareVersion: ${await storageContext.get('softwareVersion')}`);
|
|
368
371
|
this.log.debug(`- softwareVersionString: ${await storageContext.get('softwareVersionString')}`);
|
|
369
372
|
this.log.debug(`- hardwareVersion: ${await storageContext.get('hardwareVersion')}`);
|
|
370
373
|
this.log.debug(`- hardwareVersionString: ${await storageContext.get('hardwareVersionString')}`);
|
|
374
|
+
this.log.debug(`- configurationVersion: ${await storageContext.get('configurationVersion')}`);
|
|
371
375
|
return storageContext;
|
|
372
376
|
}
|
|
373
377
|
async createServerNode(port = 5540, passcode = 20252026, discriminator = 3850) {
|
|
@@ -376,6 +380,23 @@ export class MatterNode extends EventEmitter {
|
|
|
376
380
|
}
|
|
377
381
|
const storeId = await this.matterStorageContext.get('storeId');
|
|
378
382
|
this.log.notice(`Creating server node for ${storeId} on port ${port} with passcode ${passcode} and discriminator ${discriminator}...`);
|
|
383
|
+
this.log.debug(`- storeId: ${await this.matterStorageContext.get('storeId')}`);
|
|
384
|
+
this.log.debug(`- deviceName: ${await this.matterStorageContext.get('deviceName')}`);
|
|
385
|
+
this.log.debug(`- deviceType: ${await this.matterStorageContext.get('deviceType')}(0x${(await this.matterStorageContext.get('deviceType'))?.toString(16).padStart(4, '0')})`);
|
|
386
|
+
this.log.debug(`- vendorId: ${await this.matterStorageContext.get('vendorId')}`);
|
|
387
|
+
this.log.debug(`- vendorName: ${await this.matterStorageContext.get('vendorName')}`);
|
|
388
|
+
this.log.debug(`- productId: ${await this.matterStorageContext.get('productId')}`);
|
|
389
|
+
this.log.debug(`- productName: ${await this.matterStorageContext.get('productName')}`);
|
|
390
|
+
this.log.debug(`- productLabel: ${await this.matterStorageContext.get('productLabel')}`);
|
|
391
|
+
this.log.debug(`- productUrl: ${await this.matterStorageContext.get('productUrl')}`);
|
|
392
|
+
this.log.debug(`- nodeLabel: ${await this.matterStorageContext.get('nodeLabel')}`);
|
|
393
|
+
this.log.debug(`- serialNumber: ${await this.matterStorageContext.get('serialNumber')}`);
|
|
394
|
+
this.log.debug(`- uniqueId: ${await this.matterStorageContext.get('uniqueId')}`);
|
|
395
|
+
this.log.debug(`- softwareVersion: ${await this.matterStorageContext.get('softwareVersion')}`);
|
|
396
|
+
this.log.debug(`- softwareVersionString: ${await this.matterStorageContext.get('softwareVersionString')}`);
|
|
397
|
+
this.log.debug(`- hardwareVersion: ${await this.matterStorageContext.get('hardwareVersion')}`);
|
|
398
|
+
this.log.debug(`- hardwareVersionString: ${await this.matterStorageContext.get('hardwareVersionString')}`);
|
|
399
|
+
this.log.debug(`- configurationVersion: ${await this.matterStorageContext.get('configurationVersion')}`);
|
|
379
400
|
if (passcode < 0 || passcode > 99999999) {
|
|
380
401
|
this.log.warn(`Invalid passcode ${passcode} for server node ${storeId}. Passcode must be between 0 and 99999999. Generating a random passcode...`);
|
|
381
402
|
passcode = PaseClient.generateRandomPasscode(this.environment.get(Crypto));
|
|
@@ -413,6 +434,7 @@ export class MatterNode extends EventEmitter {
|
|
|
413
434
|
productId: await this.matterStorageContext.get('productId'),
|
|
414
435
|
productName: await this.matterStorageContext.get('productName'),
|
|
415
436
|
productLabel: await this.matterStorageContext.get('productLabel'),
|
|
437
|
+
productUrl: await this.matterStorageContext.get('productUrl'),
|
|
416
438
|
nodeLabel: await this.matterStorageContext.get('nodeLabel'),
|
|
417
439
|
serialNumber: await this.matterStorageContext.get('serialNumber'),
|
|
418
440
|
uniqueId: await this.matterStorageContext.get('uniqueId'),
|
|
@@ -420,6 +442,7 @@ export class MatterNode extends EventEmitter {
|
|
|
420
442
|
softwareVersionString: await this.matterStorageContext.get('softwareVersionString'),
|
|
421
443
|
hardwareVersion: await this.matterStorageContext.get('hardwareVersion'),
|
|
422
444
|
hardwareVersionString: await this.matterStorageContext.get('hardwareVersionString'),
|
|
445
|
+
configurationVersion: await this.matterStorageContext.get('configurationVersion'),
|
|
423
446
|
reachable: true,
|
|
424
447
|
},
|
|
425
448
|
});
|
|
@@ -544,7 +567,7 @@ export class MatterNode extends EventEmitter {
|
|
|
544
567
|
}
|
|
545
568
|
async createMatterbridgeServerNode() {
|
|
546
569
|
this.log.debug(`Creating ${plg}Matterbridge${db} server node...`);
|
|
547
|
-
this.matterStorageContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, this.aggregatorSerialNumber, this.aggregatorUniqueId);
|
|
570
|
+
this.matterStorageContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, this.aggregatorSerialNumber, this.aggregatorUniqueId, parseVersionString(this.matterbridge.matterbridgeVersion), this.matterbridge.matterbridgeVersion, parseVersionString(this.matterbridge.systemInformation.osRelease), this.matterbridge.systemInformation.osRelease, 'Matter Bridge', 'https://matterbridge.io', 1);
|
|
548
571
|
this.serverNode = await this.createServerNode(this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
|
|
549
572
|
this.aggregatorNode = await this.createAggregatorNode();
|
|
550
573
|
this.log.debug(`Adding ${plg}Matterbridge${db} aggregator node...`);
|
|
@@ -565,7 +588,7 @@ export class MatterNode extends EventEmitter {
|
|
|
565
588
|
if (!plugin.locked && device.deviceType && device.deviceName && device.vendorId && device.vendorName && device.productId && device.productName) {
|
|
566
589
|
plugin.locked = true;
|
|
567
590
|
this.log.debug(`Creating accessory plugin ${plg}${plugin.name}${db} server node...`);
|
|
568
|
-
this.matterStorageContext = await this.createServerNodeContext(plugin.name, device.deviceName, DeviceTypeId(device.deviceType), VendorId(device.vendorId), device.vendorName, device.productId, device.productName);
|
|
591
|
+
this.matterStorageContext = await this.createServerNodeContext(plugin.name, device.deviceName, DeviceTypeId(device.deviceType), VendorId(device.vendorId), device.vendorName, device.productId, device.productName, device.serialNumber, device.uniqueId, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString, device.productLabel, device.productUrl, device.configurationVersion);
|
|
569
592
|
this.serverNode = await this.createServerNode(this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
|
|
570
593
|
this.log.debug(`Adding ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} to ${plg}${plugin.name}${db} server node...`);
|
|
571
594
|
await this.serverNode.add(device);
|
|
@@ -586,7 +609,7 @@ export class MatterNode extends EventEmitter {
|
|
|
586
609
|
if (!plugin.locked) {
|
|
587
610
|
plugin.locked = true;
|
|
588
611
|
this.log.debug(`Creating dynamic plugin ${plg}${plugin.name}${db} server node...`);
|
|
589
|
-
this.matterStorageContext = await this.createServerNodeContext(plugin.name,
|
|
612
|
+
this.matterStorageContext = await this.createServerNodeContext(plugin.name, plugin.description, this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, undefined, undefined, parseVersionString(this.matterbridge.matterbridgeVersion), this.matterbridge.matterbridgeVersion, parseVersionString(this.matterbridge.systemInformation.osRelease), this.matterbridge.systemInformation.osRelease, plugin.description, plugin.homepage ?? 'https://matterbridge.io', 1);
|
|
590
613
|
this.serverNode = await this.createServerNode(this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
|
|
591
614
|
this.log.debug(`Creating dynamic plugin ${plg}${plugin.name}${db} aggregator node...`);
|
|
592
615
|
this.aggregatorNode = await this.createAggregatorNode();
|
|
@@ -608,7 +631,7 @@ export class MatterNode extends EventEmitter {
|
|
|
608
631
|
}
|
|
609
632
|
if (device.mode === 'server' && device.deviceType && device.deviceName && device.vendorId && device.vendorName && device.productId && device.productName) {
|
|
610
633
|
this.log.debug(`Creating device ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} server node...`);
|
|
611
|
-
this.matterStorageContext = await this.createServerNodeContext(device.deviceName.replace(/[ .]/g, ''), device.deviceName, DeviceTypeId(device.deviceType), VendorId(device.vendorId), device.vendorName, device.productId, device.productName);
|
|
634
|
+
this.matterStorageContext = await this.createServerNodeContext(device.deviceName.replace(/[ .]/g, ''), device.deviceName, DeviceTypeId(device.deviceType), VendorId(device.vendorId), device.vendorName, device.productId, device.productName, device.serialNumber, device.uniqueId, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString, device.productLabel, device.productUrl, device.configurationVersion);
|
|
612
635
|
this.serverNode = await this.createServerNode(this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
|
|
613
636
|
this.log.debug(`Adding ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} to server node...`);
|
|
614
637
|
await this.serverNode.add(device);
|
package/dist/matterbridge.js
CHANGED
|
@@ -22,7 +22,7 @@ import { getErrorMessage, inspectError, logError } from '@matterbridge/utils/err
|
|
|
22
22
|
import { formatBytes, formatPercent, formatUptime } from '@matterbridge/utils/format';
|
|
23
23
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
24
24
|
import { excludedInterfaceNamePattern } from '@matterbridge/utils/network';
|
|
25
|
-
import { isValidNumber, isValidObject, isValidString, parseVersionString } from '@matterbridge/utils/validate';
|
|
25
|
+
import { isValidInteger, isValidNumber, isValidObject, isValidString, parseVersionString } from '@matterbridge/utils/validate';
|
|
26
26
|
import { fireAndForget, wait } from '@matterbridge/utils/wait';
|
|
27
27
|
import { AnsiLogger, BLUE, BRIGHT, CYAN, db, debugStringify, er, GREEN, nf, nt, or, RED, RESET, rs, UNDERLINE, UNDERLINEOFF, wr, zb, } from 'node-ansi-logger';
|
|
28
28
|
import { NodeStorageManager } from 'node-persist-manager';
|
|
@@ -1751,7 +1751,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1751
1751
|
await createDirectory(path.join(this.matterbridgeDirectory, MATTER_STORAGE_DIR, 'Matterbridge'), `Matter node storage directory for Matterbridge`, this.log);
|
|
1752
1752
|
this.matterStorageManager = await this.matterStorageService.open('Matterbridge');
|
|
1753
1753
|
this.log.info('Matter node storage manager "Matterbridge" created');
|
|
1754
|
-
this.matterbridgeContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, this.aggregatorSerialNumber, this.aggregatorUniqueId);
|
|
1754
|
+
this.matterbridgeContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, this.aggregatorSerialNumber, this.aggregatorUniqueId, parseVersionString(this.matterbridgeVersion), this.matterbridgeVersion, parseVersionString(this.systemInformation.osRelease), this.systemInformation.osRelease, 'Matter Bridge', 'https://matterbridge.io', 1);
|
|
1755
1755
|
this.log.info('Matter node storage started');
|
|
1756
1756
|
await this.backupMatterStorage(path.join(this.matterbridgeDirectory, MATTER_STORAGE_DIR), path.join(this.matterbridgeDirectory, MATTER_STORAGE_DIR + '.backup'));
|
|
1757
1757
|
}
|
|
@@ -1779,7 +1779,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1779
1779
|
this.controllerContext = undefined;
|
|
1780
1780
|
this.log.info('Matter node storage closed');
|
|
1781
1781
|
}
|
|
1782
|
-
async createServerNodeContext(storeId, deviceName, deviceType, vendorId, vendorName, productId, productName, serialNumber, uniqueId) {
|
|
1782
|
+
async createServerNodeContext(storeId, deviceName, deviceType, vendorId, vendorName, productId, productName, serialNumber, uniqueId, softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0', productLabel = 'Matter Endpoint', productUrl = 'https://matterbridge.io', configurationVersion = 1) {
|
|
1783
1783
|
const { randomBytes } = await import('node:crypto');
|
|
1784
1784
|
if (!this.matterStorageService)
|
|
1785
1785
|
throw new Error('No storage service initialized');
|
|
@@ -1797,14 +1797,16 @@ export class Matterbridge extends EventEmitter {
|
|
|
1797
1797
|
await storageContext.set('vendorName', vendorName.slice(0, 32));
|
|
1798
1798
|
await storageContext.set('productId', productId);
|
|
1799
1799
|
await storageContext.set('productName', productName.slice(0, 32));
|
|
1800
|
-
await storageContext.set('productLabel',
|
|
1800
|
+
await storageContext.set('productLabel', productLabel.replace(vendorName, '').trim().slice(0, 64));
|
|
1801
|
+
await storageContext.set('productUrl', isValidString(productUrl, 8, 256) && productUrl.startsWith('https://') ? productUrl : 'https://matterbridge.io');
|
|
1801
1802
|
await storageContext.set('nodeLabel', deviceName.slice(0, 32));
|
|
1802
1803
|
await storageContext.set('serialNumber', await storageContext.get('serialNumber', serialNumber ? serialNumber.slice(0, 32) : 'SN' + random));
|
|
1803
1804
|
await storageContext.set('uniqueId', await storageContext.get('uniqueId', uniqueId ? uniqueId.slice(0, 32) : 'UI' + random));
|
|
1804
|
-
await storageContext.set('softwareVersion',
|
|
1805
|
-
await storageContext.set('softwareVersionString', isValidString(
|
|
1806
|
-
await storageContext.set('hardwareVersion',
|
|
1807
|
-
await storageContext.set('hardwareVersionString', isValidString(
|
|
1805
|
+
await storageContext.set('softwareVersion', isValidInteger(softwareVersion, 0, UINT32_MAX) ? softwareVersion : 1);
|
|
1806
|
+
await storageContext.set('softwareVersionString', isValidString(softwareVersionString, 1, 64) ? softwareVersionString : '1.0.0');
|
|
1807
|
+
await storageContext.set('hardwareVersion', isValidInteger(hardwareVersion, 0, UINT16_MAX) ? hardwareVersion : 1);
|
|
1808
|
+
await storageContext.set('hardwareVersionString', isValidString(hardwareVersionString, 1, 64) ? hardwareVersionString : '1.0.0');
|
|
1809
|
+
await storageContext.set('configurationVersion', isValidInteger(configurationVersion, 1, UINT32_MAX) ? configurationVersion : 1);
|
|
1808
1810
|
this.log.debug(`Created server node storage context "${storeId}.persist" for ${storeId}:`);
|
|
1809
1811
|
this.log.debug(`- storeId: ${await storageContext.get('storeId')}`);
|
|
1810
1812
|
this.log.debug(`- deviceName: ${await storageContext.get('deviceName')}`);
|
|
@@ -1814,6 +1816,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1814
1816
|
this.log.debug(`- productId: ${await storageContext.get('productId')}`);
|
|
1815
1817
|
this.log.debug(`- productName: ${await storageContext.get('productName')}`);
|
|
1816
1818
|
this.log.debug(`- productLabel: ${await storageContext.get('productLabel')}`);
|
|
1819
|
+
this.log.debug(`- productUrl: ${await storageContext.get('productUrl')}`);
|
|
1817
1820
|
this.log.debug(`- nodeLabel: ${await storageContext.get('nodeLabel')}`);
|
|
1818
1821
|
this.log.debug(`- serialNumber: ${await storageContext.get('serialNumber')}`);
|
|
1819
1822
|
this.log.debug(`- uniqueId: ${await storageContext.get('uniqueId')}`);
|
|
@@ -1821,6 +1824,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1821
1824
|
this.log.debug(`- softwareVersionString: ${await storageContext.get('softwareVersionString')}`);
|
|
1822
1825
|
this.log.debug(`- hardwareVersion: ${await storageContext.get('hardwareVersion')}`);
|
|
1823
1826
|
this.log.debug(`- hardwareVersionString: ${await storageContext.get('hardwareVersionString')}`);
|
|
1827
|
+
this.log.debug(`- configurationVersion: ${await storageContext.get('configurationVersion')}`);
|
|
1824
1828
|
return storageContext;
|
|
1825
1829
|
}
|
|
1826
1830
|
async createServerNode(storageContext, port = 5540, passcode = 20242025, discriminator = 3850) {
|
|
@@ -1834,6 +1838,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1834
1838
|
this.log.debug(`- productId: ${await storageContext.get('productId')}`);
|
|
1835
1839
|
this.log.debug(`- productName: ${await storageContext.get('productName')}`);
|
|
1836
1840
|
this.log.debug(`- productLabel: ${await storageContext.get('productLabel')}`);
|
|
1841
|
+
this.log.debug(`- productUrl: ${await storageContext.get('productUrl')}`);
|
|
1837
1842
|
this.log.debug(`- nodeLabel: ${await storageContext.get('nodeLabel')}`);
|
|
1838
1843
|
this.log.debug(`- serialNumber: ${await storageContext.get('serialNumber')}`);
|
|
1839
1844
|
this.log.debug(`- uniqueId: ${await storageContext.get('uniqueId')}`);
|
|
@@ -1841,6 +1846,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1841
1846
|
this.log.debug(`- softwareVersionString: ${await storageContext.get('softwareVersionString')}`);
|
|
1842
1847
|
this.log.debug(`- hardwareVersion: ${await storageContext.get('hardwareVersion')}`);
|
|
1843
1848
|
this.log.debug(`- hardwareVersionString: ${await storageContext.get('hardwareVersionString')}`);
|
|
1849
|
+
this.log.debug(`- configurationVersion: ${await storageContext.get('configurationVersion')}`);
|
|
1844
1850
|
if (passcode < 0 || passcode > 99999999) {
|
|
1845
1851
|
this.log.warn(`Invalid passcode ${passcode} for server node ${storeId}. Passcode must be between 0 and 99999999. Generating a random passcode...`);
|
|
1846
1852
|
passcode = PaseClient.generateRandomPasscode(this.environment.get(Crypto));
|
|
@@ -1877,12 +1883,14 @@ export class Matterbridge extends EventEmitter {
|
|
|
1877
1883
|
productId: await storageContext.get('productId'),
|
|
1878
1884
|
productName: await storageContext.get('productName'),
|
|
1879
1885
|
productLabel: await storageContext.get('productLabel'),
|
|
1886
|
+
productUrl: await storageContext.get('productUrl'),
|
|
1880
1887
|
serialNumber: await storageContext.get('serialNumber'),
|
|
1881
1888
|
uniqueId: await storageContext.get('uniqueId'),
|
|
1882
1889
|
softwareVersion: await storageContext.get('softwareVersion'),
|
|
1883
1890
|
softwareVersionString: await storageContext.get('softwareVersionString'),
|
|
1884
1891
|
hardwareVersion: await storageContext.get('hardwareVersion'),
|
|
1885
1892
|
hardwareVersionString: await storageContext.get('hardwareVersionString'),
|
|
1893
|
+
configurationVersion: await storageContext.get('configurationVersion'),
|
|
1886
1894
|
reachable: true,
|
|
1887
1895
|
},
|
|
1888
1896
|
});
|
|
@@ -2002,7 +2010,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2002
2010
|
plugin.locked = true;
|
|
2003
2011
|
plugin.device = device;
|
|
2004
2012
|
this.log.debug(`Creating accessory plugin ${plg}${plugin.name}${db} server node...`);
|
|
2005
|
-
plugin.storageContext = await this.createServerNodeContext(plugin.name, device.deviceName, DeviceTypeId(device.deviceType), device.vendorId, device.vendorName, device.productId, device.productName, device.serialNumber, device.uniqueId);
|
|
2013
|
+
plugin.storageContext = await this.createServerNodeContext(plugin.name, device.deviceName, DeviceTypeId(device.deviceType), device.vendorId, device.vendorName, device.productId, device.productName, device.serialNumber, device.uniqueId, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString, device.productLabel, device.productUrl, device.configurationVersion);
|
|
2006
2014
|
plugin.serverNode = await this.createServerNode(plugin.storageContext, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
|
|
2007
2015
|
this.log.debug(`Adding ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} to ${plg}${plugin.name}${db} server node...`);
|
|
2008
2016
|
await plugin.serverNode.add(device);
|
|
@@ -2012,7 +2020,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2012
2020
|
if (!plugin.locked) {
|
|
2013
2021
|
plugin.locked = true;
|
|
2014
2022
|
this.log.debug(`Creating dynamic plugin ${plg}${plugin.name}${db} server node...`);
|
|
2015
|
-
plugin.storageContext = await this.createServerNodeContext(plugin.name, plugin.description, this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName);
|
|
2023
|
+
plugin.storageContext = await this.createServerNodeContext(plugin.name, plugin.description, this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, undefined, undefined, parseVersionString(this.matterbridgeVersion), this.matterbridgeVersion, parseVersionString(this.systemInformation.osRelease), this.systemInformation.osRelease, plugin.description, plugin.homepage ?? 'https://matterbridge.io', 1);
|
|
2016
2024
|
plugin.serverNode = await this.createServerNode(plugin.storageContext, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
|
|
2017
2025
|
this.log.debug(`Creating dynamic plugin ${plg}${plugin.name}${db} aggregator node...`);
|
|
2018
2026
|
plugin.aggregatorNode = await this.createAggregatorNode(plugin.storageContext);
|
|
@@ -2030,7 +2038,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2030
2038
|
device.productId &&
|
|
2031
2039
|
device.productName) {
|
|
2032
2040
|
this.log.debug(`Creating device ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} server node...`);
|
|
2033
|
-
const context = await this.createServerNodeContext(device.deviceName.replace(/[ .]/g, ''), device.deviceName, DeviceTypeId(device.deviceType), device.vendorId, device.vendorName, device.productId, device.productName, device.serialNumber, device.uniqueId);
|
|
2041
|
+
const context = await this.createServerNodeContext(device.deviceName.replace(/[ .]/g, ''), device.deviceName, DeviceTypeId(device.deviceType), device.vendorId, device.vendorName, device.productId, device.productName, device.serialNumber, device.uniqueId, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString, device.productLabel, device.productUrl, device.configurationVersion);
|
|
2034
2042
|
device.serverNode = await this.createServerNode(context, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
|
|
2035
2043
|
this.log.debug(`Adding ${plg}${plugin.name}${db}:${dev}${device.deviceName}${db} to server node...`);
|
|
2036
2044
|
await device.serverNode.add(device);
|
|
@@ -70,11 +70,13 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
70
70
|
vendorName: string | undefined;
|
|
71
71
|
productId: number | undefined;
|
|
72
72
|
productName: string | undefined;
|
|
73
|
+
productLabel: string | undefined;
|
|
74
|
+
productUrl: string;
|
|
73
75
|
softwareVersion: number | undefined;
|
|
74
76
|
softwareVersionString: string | undefined;
|
|
75
77
|
hardwareVersion: number | undefined;
|
|
76
78
|
hardwareVersionString: string | undefined;
|
|
77
|
-
|
|
79
|
+
configurationVersion: number;
|
|
78
80
|
tagList: Semtag[] | undefined;
|
|
79
81
|
originalId: string | undefined;
|
|
80
82
|
name: string | undefined;
|
|
@@ -138,8 +140,8 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
138
140
|
createDefaultPowerSourceBatteryClusterServer(batPercentRemaining?: null | number, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: null | number, batReplaceability?: PowerSource.BatReplaceability): this;
|
|
139
141
|
createDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining?: number | null, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: number | null, batReplacementDescription?: string, batQuantity?: number, batReplaceability?: PowerSource.BatReplaceability): this;
|
|
140
142
|
createDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining?: number | null, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: number | null, batReplaceability?: PowerSource.BatReplaceability): this;
|
|
141
|
-
createDefaultBasicInformationClusterServer(deviceName: string, serialNumber: string, vendorId?: number, vendorName?: string, productId?: number, productName?: string, softwareVersion?: number, softwareVersionString?: string, hardwareVersion?: number, hardwareVersionString?: string): this;
|
|
142
|
-
createDefaultBridgedDeviceBasicInformationClusterServer(deviceName: string, serialNumber: string, vendorId?: number, vendorName?: string, productName?: string, softwareVersion?: number, softwareVersionString?: string, hardwareVersion?: number, hardwareVersionString?: string): this;
|
|
143
|
+
createDefaultBasicInformationClusterServer(deviceName: string, serialNumber: string, vendorId?: number, vendorName?: string, productId?: number, productName?: string, softwareVersion?: number, softwareVersionString?: string, hardwareVersion?: number, hardwareVersionString?: string, productLabel?: string, productUrl?: string, configurationVersion?: number): this;
|
|
144
|
+
createDefaultBridgedDeviceBasicInformationClusterServer(deviceName: string, serialNumber: string, vendorId?: number, vendorName?: string, productName?: string, softwareVersion?: number, softwareVersionString?: string, hardwareVersion?: number, hardwareVersionString?: string, productLabel?: string, productUrl?: string, configurationVersion?: number): this;
|
|
143
145
|
createDefaultPowerTopologyClusterServer(): this;
|
|
144
146
|
createDefaultElectricalEnergyMeasurementClusterServer(energyImported?: number | bigint | null, energyExported?: number | bigint | null): this;
|
|
145
147
|
createDefaultElectricalPowerMeasurementClusterServer(voltage?: number | bigint | null, current?: number | bigint | null, power?: number | bigint | null, frequency?: number | bigint | null): this;
|
|
@@ -32,6 +32,7 @@ import { ThermostatUserInterfaceConfigurationServer } from '@matter/node/behavio
|
|
|
32
32
|
import { TotalVolatileOrganicCompoundsConcentrationMeasurementServer } from '@matter/node/behaviors/total-volatile-organic-compounds-concentration-measurement';
|
|
33
33
|
import { getClusterNameById } from '@matter/types/cluster';
|
|
34
34
|
import { AirQuality } from '@matter/types/clusters/air-quality';
|
|
35
|
+
import { BasicInformation } from '@matter/types/clusters/basic-information';
|
|
35
36
|
import { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
|
|
36
37
|
import { BridgedDeviceBasicInformation } from '@matter/types/clusters/bridged-device-basic-information';
|
|
37
38
|
import { ColorControl } from '@matter/types/clusters/color-control';
|
|
@@ -60,7 +61,7 @@ import { WindowCovering } from '@matter/types/clusters/window-covering';
|
|
|
60
61
|
import { VendorId } from '@matter/types/datatype';
|
|
61
62
|
import { inspectError } from '@matterbridge/utils/error';
|
|
62
63
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
63
|
-
import { isValidNumber, isValidObject, isValidString } from '@matterbridge/utils/validate';
|
|
64
|
+
import { isValidInteger, isValidNumber, isValidObject, isValidString } from '@matterbridge/utils/validate';
|
|
64
65
|
import { AnsiLogger, CYAN, db, debugStringify, hk, or, YELLOW, zb } from 'node-ansi-logger';
|
|
65
66
|
import { MatterbridgeActivatedCarbonFilterMonitoringServer } from './behaviors/activatedCarbonFilterMonitoringServer.js';
|
|
66
67
|
import { MatterbridgeBooleanStateConfigurationServer } from './behaviors/booleanStateConfigurationServer.js';
|
|
@@ -115,11 +116,13 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
115
116
|
vendorName = undefined;
|
|
116
117
|
productId = undefined;
|
|
117
118
|
productName = undefined;
|
|
119
|
+
productLabel = undefined;
|
|
120
|
+
productUrl = 'https://matterbridge.io';
|
|
118
121
|
softwareVersion = undefined;
|
|
119
122
|
softwareVersionString = undefined;
|
|
120
123
|
hardwareVersion = undefined;
|
|
121
124
|
hardwareVersionString = undefined;
|
|
122
|
-
|
|
125
|
+
configurationVersion = 1;
|
|
123
126
|
tagList = undefined;
|
|
124
127
|
originalId = undefined;
|
|
125
128
|
name = undefined;
|
|
@@ -468,6 +471,13 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
468
471
|
uniqueId: device.uniqueId,
|
|
469
472
|
productId: device.productId,
|
|
470
473
|
productName: device.productName,
|
|
474
|
+
productLabel: device.productLabel,
|
|
475
|
+
productUrl: device.productUrl,
|
|
476
|
+
configurationVersion: device.configurationVersion,
|
|
477
|
+
softwareVersion: device.softwareVersion,
|
|
478
|
+
softwareVersionString: device.softwareVersionString,
|
|
479
|
+
hardwareVersion: device.hardwareVersion,
|
|
480
|
+
hardwareVersionString: device.hardwareVersionString,
|
|
471
481
|
vendorId: device.vendorId,
|
|
472
482
|
vendorName: device.vendorName,
|
|
473
483
|
deviceTypes: Array.from(device.deviceTypes.values()),
|
|
@@ -478,6 +488,8 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
478
488
|
Object.keys(device.behaviors.supported).forEach((behaviorName) => {
|
|
479
489
|
if (behaviorName === 'bridgedDeviceBasicInformation')
|
|
480
490
|
serialized.clusterServersId.push(BridgedDeviceBasicInformation.id);
|
|
491
|
+
if (behaviorName === 'basicInformation')
|
|
492
|
+
serialized.clusterServersId.push(BasicInformation.id);
|
|
481
493
|
if (behaviorName === 'powerSource')
|
|
482
494
|
serialized.clusterServersId.push(PowerSource.id);
|
|
483
495
|
});
|
|
@@ -493,9 +505,18 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
493
505
|
device.vendorName = serializedDevice.vendorName;
|
|
494
506
|
device.productId = serializedDevice.productId;
|
|
495
507
|
device.productName = serializedDevice.productName;
|
|
508
|
+
device.productLabel = serializedDevice.productLabel;
|
|
509
|
+
device.productUrl = serializedDevice.productUrl;
|
|
510
|
+
device.configurationVersion = serializedDevice.configurationVersion;
|
|
511
|
+
device.softwareVersion = serializedDevice.softwareVersion;
|
|
512
|
+
device.softwareVersionString = serializedDevice.softwareVersionString;
|
|
513
|
+
device.hardwareVersion = serializedDevice.hardwareVersion;
|
|
514
|
+
device.hardwareVersionString = serializedDevice.hardwareVersionString;
|
|
496
515
|
for (const clusterId of serializedDevice.clusterServersId) {
|
|
497
516
|
if (clusterId === BridgedDeviceBasicInformation.id)
|
|
498
|
-
device.createDefaultBridgedDeviceBasicInformationClusterServer(serializedDevice.deviceName, serializedDevice.serialNumber, serializedDevice.vendorId ?? 0xfff1, serializedDevice.vendorName ?? 'Matterbridge', serializedDevice.productName ?? 'Matterbridge device');
|
|
517
|
+
device.createDefaultBridgedDeviceBasicInformationClusterServer(serializedDevice.deviceName, serializedDevice.serialNumber, serializedDevice.vendorId ?? 0xfff1, serializedDevice.vendorName ?? 'Matterbridge', serializedDevice.productName ?? 'Matterbridge device', serializedDevice.softwareVersion, serializedDevice.softwareVersionString, serializedDevice.hardwareVersion, serializedDevice.hardwareVersionString, serializedDevice.productLabel, serializedDevice.productUrl, serializedDevice.configurationVersion);
|
|
518
|
+
else if (clusterId === BasicInformation.id)
|
|
519
|
+
device.createDefaultBasicInformationClusterServer(serializedDevice.deviceName, serializedDevice.serialNumber, serializedDevice.vendorId ?? 0xfff1, serializedDevice.vendorName ?? 'Matterbridge', serializedDevice.productId ?? 0x8000, serializedDevice.productName ?? 'Matterbridge device', serializedDevice.softwareVersion, serializedDevice.softwareVersionString, serializedDevice.hardwareVersion, serializedDevice.hardwareVersionString, serializedDevice.productLabel, serializedDevice.productUrl, serializedDevice.configurationVersion);
|
|
499
520
|
else if (clusterId === PowerSource.id)
|
|
500
521
|
device.createDefaultPowerSourceWiredClusterServer();
|
|
501
522
|
}
|
|
@@ -517,49 +538,56 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
517
538
|
this.behaviors.require(MatterbridgePowerSourceServer.with(PowerSource.Feature.Battery, PowerSource.Feature.Rechargeable), getDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining, batChargeLevel, batVoltage, batReplaceability));
|
|
518
539
|
return this;
|
|
519
540
|
}
|
|
520
|
-
createDefaultBasicInformationClusterServer(deviceName, serialNumber, vendorId = 0xfff1, vendorName = 'Matterbridge', productId = 0x8000, productName = 'Matterbridge device', softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0') {
|
|
541
|
+
createDefaultBasicInformationClusterServer(deviceName, serialNumber, vendorId = 0xfff1, vendorName = 'Matterbridge', productId = 0x8000, productName = 'Matterbridge device', softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0', productLabel = 'Matter Endpoint', productUrl = 'https://matterbridge.io', configurationVersion = 1) {
|
|
521
542
|
this.log.logName = deviceName;
|
|
522
543
|
this.deviceName = deviceName;
|
|
523
544
|
this.serialNumber = serialNumber;
|
|
524
545
|
this.uniqueId = createUniqueId(deviceName, serialNumber, vendorName, productName);
|
|
525
546
|
this.productId = productId;
|
|
526
547
|
this.productName = productName;
|
|
548
|
+
this.productLabel = productLabel;
|
|
549
|
+
this.productUrl = productUrl;
|
|
527
550
|
this.vendorId = vendorId;
|
|
528
551
|
this.vendorName = vendorName;
|
|
529
552
|
this.softwareVersion = softwareVersion;
|
|
530
553
|
this.softwareVersionString = softwareVersionString;
|
|
531
554
|
this.hardwareVersion = hardwareVersion;
|
|
532
555
|
this.hardwareVersionString = hardwareVersionString;
|
|
556
|
+
this.configurationVersion = configurationVersion;
|
|
533
557
|
return this;
|
|
534
558
|
}
|
|
535
|
-
createDefaultBridgedDeviceBasicInformationClusterServer(deviceName, serialNumber, vendorId = 0xfff1, vendorName = 'Matterbridge', productName = 'Matterbridge device', softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0') {
|
|
559
|
+
createDefaultBridgedDeviceBasicInformationClusterServer(deviceName, serialNumber, vendorId = 0xfff1, vendorName = 'Matterbridge', productName = 'Matterbridge device', softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0', productLabel = 'Matter Bridged Endpoint', productUrl = 'https://matterbridge.io', configurationVersion = 1) {
|
|
536
560
|
this.log.logName = deviceName;
|
|
537
561
|
this.deviceName = deviceName;
|
|
538
562
|
this.serialNumber = serialNumber;
|
|
539
563
|
this.uniqueId = createUniqueId(deviceName, serialNumber, vendorName, productName);
|
|
540
564
|
this.productId = undefined;
|
|
541
565
|
this.productName = productName;
|
|
566
|
+
this.productLabel = productLabel;
|
|
567
|
+
this.productUrl = productUrl;
|
|
542
568
|
this.vendorId = vendorId;
|
|
543
569
|
this.vendorName = vendorName;
|
|
544
570
|
this.softwareVersion = softwareVersion;
|
|
545
571
|
this.softwareVersionString = softwareVersionString;
|
|
546
572
|
this.hardwareVersion = hardwareVersion;
|
|
547
573
|
this.hardwareVersionString = hardwareVersionString;
|
|
574
|
+
this.configurationVersion = configurationVersion;
|
|
548
575
|
this.behaviors.require(BridgedDeviceBasicInformationServer.enable({
|
|
549
576
|
events: { leave: true, reachableChanged: true },
|
|
550
577
|
}), {
|
|
551
578
|
vendorId: VendorId(vendorId),
|
|
552
579
|
vendorName: vendorName.slice(0, 32),
|
|
553
580
|
productName: productName.slice(0, 32),
|
|
554
|
-
|
|
555
|
-
|
|
581
|
+
productLabel: productLabel.replace(vendorName, '').trim().slice(0, 64),
|
|
582
|
+
productUrl: isValidString(productUrl, 8, 256) && productUrl.startsWith('https://') ? productUrl : 'https://matterbridge.io',
|
|
556
583
|
nodeLabel: deviceName.slice(0, 32),
|
|
557
584
|
serialNumber: serialNumber.slice(0, 32),
|
|
558
585
|
uniqueId: this.uniqueId.slice(0, 32),
|
|
559
|
-
softwareVersion:
|
|
560
|
-
softwareVersionString: isValidString(softwareVersionString) ? softwareVersionString
|
|
561
|
-
hardwareVersion:
|
|
562
|
-
hardwareVersionString: isValidString(hardwareVersionString) ? hardwareVersionString
|
|
586
|
+
softwareVersion: isValidInteger(softwareVersion, 0, UINT32_MAX) ? softwareVersion : 1,
|
|
587
|
+
softwareVersionString: isValidString(softwareVersionString, 1, 64) ? softwareVersionString : '1.0.0',
|
|
588
|
+
hardwareVersion: isValidInteger(hardwareVersion, 0, UINT16_MAX) ? hardwareVersion : 1,
|
|
589
|
+
hardwareVersionString: isValidString(hardwareVersionString, 1, 64) ? hardwareVersionString : '1.0.0',
|
|
590
|
+
configurationVersion: isValidInteger(configurationVersion, 1, UINT32_MAX) ? configurationVersion : 1,
|
|
563
591
|
reachable: true,
|
|
564
592
|
});
|
|
565
593
|
return this;
|
|
@@ -9,6 +9,13 @@ export interface SerializedMatterbridgeEndpoint {
|
|
|
9
9
|
uniqueId: string;
|
|
10
10
|
productId?: number;
|
|
11
11
|
productName?: string;
|
|
12
|
+
productUrl: string;
|
|
13
|
+
productLabel?: string;
|
|
14
|
+
configurationVersion: number;
|
|
15
|
+
softwareVersion?: number;
|
|
16
|
+
softwareVersionString?: string;
|
|
17
|
+
hardwareVersion?: number;
|
|
18
|
+
hardwareVersionString?: string;
|
|
12
19
|
vendorId?: number;
|
|
13
20
|
vendorName?: string;
|
|
14
21
|
deviceTypes: DeviceTypeDefinition[];
|
|
@@ -247,7 +247,7 @@ export class MatterbridgePlatform {
|
|
|
247
247
|
}
|
|
248
248
|
if (!device.hasClusterServer(BridgedDeviceBasicInformation.id)) {
|
|
249
249
|
this.log.debug(`Device with name ${CYAN}${device.deviceName}${db} has no BridgedDeviceBasicInformation cluster. Adding it...`);
|
|
250
|
-
device.createDefaultBridgedDeviceBasicInformationClusterServer(device.deviceName, device.serialNumber, device.vendorId, device.vendorName, device.productName, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString);
|
|
250
|
+
device.createDefaultBridgedDeviceBasicInformationClusterServer(device.deviceName, device.serialNumber, device.vendorId, device.vendorName, device.productName, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString, device.productLabel === 'Matter Endpoint' ? 'Matter Bridged Endpoint' : device.productLabel, device.productUrl, device.configurationVersion);
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
await this.#addBridgedEndpoint?.(this.name, device);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.10.0-dev-20260716-
|
|
3
|
+
"version": "3.10.0-dev-20260716-7f8762c",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -132,10 +132,10 @@
|
|
|
132
132
|
},
|
|
133
133
|
"dependencies": {
|
|
134
134
|
"@matter/main": "0.17.5",
|
|
135
|
-
"@matterbridge/dgram": "3.10.0-dev-20260716-
|
|
136
|
-
"@matterbridge/thread": "3.10.0-dev-20260716-
|
|
137
|
-
"@matterbridge/types": "3.10.0-dev-20260716-
|
|
138
|
-
"@matterbridge/utils": "3.10.0-dev-20260716-
|
|
135
|
+
"@matterbridge/dgram": "3.10.0-dev-20260716-7f8762c",
|
|
136
|
+
"@matterbridge/thread": "3.10.0-dev-20260716-7f8762c",
|
|
137
|
+
"@matterbridge/types": "3.10.0-dev-20260716-7f8762c",
|
|
138
|
+
"@matterbridge/utils": "3.10.0-dev-20260716-7f8762c",
|
|
139
139
|
"escape-html": "1.0.3",
|
|
140
140
|
"express": "5.2.1",
|
|
141
141
|
"express-rate-limit": "8.5.2",
|