@riddix/hamh 2.1.0-alpha.866 → 2.1.0-alpha.868
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/backend/cli.js
CHANGED
|
@@ -132397,6 +132397,18 @@ var init_bridge_config_schema = __esm({
|
|
|
132397
132397
|
type: "boolean",
|
|
132398
132398
|
default: false
|
|
132399
132399
|
},
|
|
132400
|
+
supportTermsAndConditions: {
|
|
132401
|
+
title: "Accept Terms and Conditions commands (Alexa pairing diagnostic)",
|
|
132402
|
+
description: "Advertise the Matter 1.4 TermsAndConditions feature and accept the SetTcAcknowledgements command instead of rejecting it as unsupported. No terms are enforced, the bridge accepts any acknowledgement. Alexa sends this command during pairing and some Echo firmwares may stall when it fails (#449). Restart the bridge and re-pair after changing it. Default off.",
|
|
132403
|
+
type: "boolean",
|
|
132404
|
+
default: false
|
|
132405
|
+
},
|
|
132406
|
+
enableMatterTcp: {
|
|
132407
|
+
title: "Matter over TCP (Alexa pairing diagnostic)",
|
|
132408
|
+
description: "Open a Matter TCP listener and advertise TCP support alongside UDP. Some controllers support Matter over TCP and may attempt it, the Echo Dot advertises it (#449). Camera bridges enable this automatically already. Restart the bridge and re-pair after enabling it. Disabling needs a matterhub restart. Default off.",
|
|
132409
|
+
type: "boolean",
|
|
132410
|
+
default: false
|
|
132411
|
+
},
|
|
132400
132412
|
fastSessionRecovery: {
|
|
132401
132413
|
title: "Fast Session Recovery (Google offline workaround)",
|
|
132402
132414
|
description: "When a controller drops all subscriptions, clean up the dead session and re-announce after 5 seconds instead of 60. Opt-in for Google Home users whose devices go offline after a cancelled subscription (#386). It shortens the offline window but cannot stop the controller from rejecting the subscription. Default off.",
|
|
@@ -155230,6 +155242,32 @@ init_esm5();
|
|
|
155230
155242
|
// src/matter/endpoints/server-mode-server-node.ts
|
|
155231
155243
|
init_types2();
|
|
155232
155244
|
|
|
155245
|
+
// src/plugins/builtin/camera/camera-tcp-requirement.ts
|
|
155246
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
155247
|
+
var CAMERA_TCP_CONFIG = { incoming: true, outgoing: false };
|
|
155248
|
+
async function applyTcpFlagBeforeStart(server, flags2) {
|
|
155249
|
+
if (!flags2?.enableMatterTcp || server.state.network.tcp) {
|
|
155250
|
+
return;
|
|
155251
|
+
}
|
|
155252
|
+
await server.set({ network: { tcp: CAMERA_TCP_CONFIG } });
|
|
155253
|
+
}
|
|
155254
|
+
function parseCameraList(cameras) {
|
|
155255
|
+
if (typeof cameras !== "string") return [];
|
|
155256
|
+
return cameras.split(",").map((s) => s.trim()).filter(Boolean);
|
|
155257
|
+
}
|
|
155258
|
+
function bridgeNeedsTcpForCameras(storageDir, bridgeId) {
|
|
155259
|
+
try {
|
|
155260
|
+
const raw = readFileSync6(
|
|
155261
|
+
pluginStorageFilePath(storageDir, bridgeId, "camera"),
|
|
155262
|
+
"utf-8"
|
|
155263
|
+
);
|
|
155264
|
+
const json = JSON.parse(raw);
|
|
155265
|
+
return parseCameraList(json.config?.cameras).length > 0;
|
|
155266
|
+
} catch {
|
|
155267
|
+
return false;
|
|
155268
|
+
}
|
|
155269
|
+
}
|
|
155270
|
+
|
|
155233
155271
|
// src/utils/sanitize-matter-string.ts
|
|
155234
155272
|
function sanitizeMatterString(value) {
|
|
155235
155273
|
return value.replace(/[*!~\x00-\x1f\x7f]/g, "").trim();
|
|
@@ -155281,165 +155319,6 @@ function matterSubscriptionOptions() {
|
|
|
155281
155319
|
};
|
|
155282
155320
|
}
|
|
155283
155321
|
|
|
155284
|
-
// src/matter/endpoints/server-mode-server-node.ts
|
|
155285
|
-
var logger196 = Logger.get("ServerModeServerNode");
|
|
155286
|
-
var ServerModeServerNode = class extends ServerNode {
|
|
155287
|
-
deviceEndpoints = /* @__PURE__ */ new Map();
|
|
155288
|
-
featureFlags;
|
|
155289
|
-
serialNumberSuffix;
|
|
155290
|
-
constructor(env, bridgeData) {
|
|
155291
|
-
super({
|
|
155292
|
-
id: bridgeData.id,
|
|
155293
|
-
environment: env,
|
|
155294
|
-
network: {
|
|
155295
|
-
port: bridgeData.port,
|
|
155296
|
-
// Shared zero-jitter window, see matterSubscriptionOptions: 60s max so
|
|
155297
|
-
// iOS does not show a stale "Updating" tile (#287), no jitter so the
|
|
155298
|
-
// keepalive stays inside a controller's ceiling (#386).
|
|
155299
|
-
subscriptionOptions: matterSubscriptionOptions()
|
|
155300
|
-
},
|
|
155301
|
-
productDescription: {
|
|
155302
|
-
name: bridgeData.name,
|
|
155303
|
-
deviceType: DeviceTypeId(RoboticVacuumCleanerDevice.deviceType)
|
|
155304
|
-
},
|
|
155305
|
-
basicInformation: {
|
|
155306
|
-
...legacySpecBasicInformation(bridgeData.featureFlags),
|
|
155307
|
-
uniqueId: bridgeData.id,
|
|
155308
|
-
nodeLabel: trimToLength(bridgeData.name, 32, "..."),
|
|
155309
|
-
vendorId: VendorId(bridgeData.basicInformation.vendorId),
|
|
155310
|
-
vendorName: bridgeData.basicInformation.vendorName,
|
|
155311
|
-
productId: bridgeData.basicInformation.productId,
|
|
155312
|
-
productName: bridgeData.basicInformation.productName,
|
|
155313
|
-
productLabel: bridgeData.basicInformation.productLabel,
|
|
155314
|
-
serialNumber: `server-${bridgeData.id}`.substring(0, 32),
|
|
155315
|
-
hardwareVersion: bridgeData.basicInformation.hardwareVersion,
|
|
155316
|
-
softwareVersion: bridgeData.basicInformation.softwareVersion,
|
|
155317
|
-
hardwareVersionString: bridgeData.basicInformation.hardwareVersionString,
|
|
155318
|
-
softwareVersionString: bridgeData.basicInformation.softwareVersionString ?? String(bridgeData.basicInformation.softwareVersion),
|
|
155319
|
-
...bridgeData.countryCode ? { location: bridgeData.countryCode } : {}
|
|
155320
|
-
},
|
|
155321
|
-
subscriptions: {
|
|
155322
|
-
persistenceEnabled: false
|
|
155323
|
-
}
|
|
155324
|
-
});
|
|
155325
|
-
this.featureFlags = bridgeData.featureFlags;
|
|
155326
|
-
this.serialNumberSuffix = bridgeData.serialNumberSuffix;
|
|
155327
|
-
}
|
|
155328
|
-
/** Number of device endpoints currently attached. */
|
|
155329
|
-
get deviceCount() {
|
|
155330
|
-
return this.deviceEndpoints.size;
|
|
155331
|
-
}
|
|
155332
|
-
/**
|
|
155333
|
-
* Add a device endpoint to this server node. Several endpoints per node are
|
|
155334
|
-
* supported (#301); the call is idempotent per endpoint id.
|
|
155335
|
-
*/
|
|
155336
|
-
async addDevice(endpoint) {
|
|
155337
|
-
if (this.deviceEndpoints.has(endpoint.id)) {
|
|
155338
|
-
return;
|
|
155339
|
-
}
|
|
155340
|
-
this.deviceEndpoints.set(endpoint.id, endpoint);
|
|
155341
|
-
await this.add(endpoint);
|
|
155342
|
-
}
|
|
155343
|
-
/**
|
|
155344
|
-
* Drop one device reference after the endpoint has been deleted externally.
|
|
155345
|
-
* Must be called before re-adding an endpoint with the same id.
|
|
155346
|
-
*/
|
|
155347
|
-
forgetDevice(endpoint) {
|
|
155348
|
-
this.deviceEndpoints.delete(endpoint.id);
|
|
155349
|
-
}
|
|
155350
|
-
/** Drop all device references after the endpoints were deleted externally. */
|
|
155351
|
-
clearDevices() {
|
|
155352
|
-
this.deviceEndpoints.clear();
|
|
155353
|
-
}
|
|
155354
|
-
/**
|
|
155355
|
-
* Update root-level BasicInformation with entity-specific data.
|
|
155356
|
-
* In server mode, controllers (Apple Home, Alexa) read the root node's
|
|
155357
|
-
* BasicInformation, not the device endpoint's BridgedDeviceBasicInformation.
|
|
155358
|
-
* Without this, server-mode devices show bridge defaults (e.g. "riddix" / "MatterHub").
|
|
155359
|
-
*/
|
|
155360
|
-
async updateDeviceIdentity(entityId, device, mapping, friendlyName) {
|
|
155361
|
-
const nodeLabel = trimToLength(mapping?.customName, 32, "...") ?? trimToLength(friendlyName, 32, "...") ?? trimToLength(entityId, 32, "...");
|
|
155362
|
-
const productNameFromNodeLabel = this.featureFlags?.productNameFromNodeLabel === true ? trimToLength(sanitizeMatterString(nodeLabel ?? ""), 32, "...") ?? void 0 : void 0;
|
|
155363
|
-
const maxRawLen = 32 - (this.serialNumberSuffix?.length ?? 0);
|
|
155364
|
-
const registrySerial = this.featureFlags?.useHaRegistrySerial ? trimToLength(device?.serial_number, maxRawLen, "...") : void 0;
|
|
155365
|
-
const rawSerial = trimToLength(mapping?.customSerialNumber, maxRawLen, "...") ?? registrySerial;
|
|
155366
|
-
const serialNumber = rawSerial && this.serialNumberSuffix ? `${rawSerial}${this.serialNumberSuffix}` : rawSerial;
|
|
155367
|
-
const basicInformation = dropUndefined({
|
|
155368
|
-
vendorName: trimToLength(mapping?.customVendorName, 32, "...") ?? trimToLength(device?.manufacturer, 32, "..."),
|
|
155369
|
-
productName: trimToLength(mapping?.customProductName, 32, "...") ?? productNameFromNodeLabel ?? trimToLength(device?.model_id, 32, "...") ?? trimToLength(device?.model, 32, "..."),
|
|
155370
|
-
productLabel: trimToLength(device?.model, 64, "..."),
|
|
155371
|
-
nodeLabel,
|
|
155372
|
-
serialNumber,
|
|
155373
|
-
hardwareVersionString: trimToLength(device?.hw_version, 64, "..."),
|
|
155374
|
-
softwareVersionString: trimToLength(device?.sw_version, 64, "...")
|
|
155375
|
-
});
|
|
155376
|
-
if (Object.keys(basicInformation).length === 0) {
|
|
155377
|
-
return;
|
|
155378
|
-
}
|
|
155379
|
-
try {
|
|
155380
|
-
await this.set({ basicInformation });
|
|
155381
|
-
} catch (e) {
|
|
155382
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
155383
|
-
logger196.warn(
|
|
155384
|
-
`Failed to apply server-mode identity for ${entityId}: ${msg}`
|
|
155385
|
-
);
|
|
155386
|
-
}
|
|
155387
|
-
}
|
|
155388
|
-
// align the pairing device-type hint with the real device (default is vacuum)
|
|
155389
|
-
async updateAdvertisedDeviceType(deviceType) {
|
|
155390
|
-
try {
|
|
155391
|
-
await this.set({ productDescription: { deviceType } });
|
|
155392
|
-
} catch (e) {
|
|
155393
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
155394
|
-
logger196.warn(`Failed to set server-mode device type: ${msg}`);
|
|
155395
|
-
}
|
|
155396
|
-
}
|
|
155397
|
-
async factoryReset() {
|
|
155398
|
-
await this.cancel();
|
|
155399
|
-
await this.erase();
|
|
155400
|
-
}
|
|
155401
|
-
};
|
|
155402
|
-
function dropUndefined(obj) {
|
|
155403
|
-
const result = {};
|
|
155404
|
-
for (const key in obj) {
|
|
155405
|
-
if (obj[key] !== void 0) {
|
|
155406
|
-
result[key] = obj[key];
|
|
155407
|
-
}
|
|
155408
|
-
}
|
|
155409
|
-
return result;
|
|
155410
|
-
}
|
|
155411
|
-
|
|
155412
|
-
// src/plugins/builtin/camera/camera-tcp-requirement.ts
|
|
155413
|
-
import { readFileSync as readFileSync6 } from "node:fs";
|
|
155414
|
-
var CAMERA_TCP_CONFIG = { incoming: true, outgoing: false };
|
|
155415
|
-
function parseCameraList(cameras) {
|
|
155416
|
-
if (typeof cameras !== "string") return [];
|
|
155417
|
-
return cameras.split(",").map((s) => s.trim()).filter(Boolean);
|
|
155418
|
-
}
|
|
155419
|
-
function bridgeNeedsTcpForCameras(storageDir, bridgeId) {
|
|
155420
|
-
try {
|
|
155421
|
-
const raw = readFileSync6(
|
|
155422
|
-
pluginStorageFilePath(storageDir, bridgeId, "camera"),
|
|
155423
|
-
"utf-8"
|
|
155424
|
-
);
|
|
155425
|
-
const json = JSON.parse(raw);
|
|
155426
|
-
return parseCameraList(json.config?.cameras).length > 0;
|
|
155427
|
-
} catch {
|
|
155428
|
-
return false;
|
|
155429
|
-
}
|
|
155430
|
-
}
|
|
155431
|
-
|
|
155432
|
-
// src/plugins/plugin-manager.ts
|
|
155433
|
-
init_esm();
|
|
155434
|
-
import * as fs10 from "node:fs";
|
|
155435
|
-
import * as path12 from "node:path";
|
|
155436
|
-
|
|
155437
|
-
// src/plugins/plugin-device-factory.ts
|
|
155438
|
-
init_esm();
|
|
155439
|
-
|
|
155440
|
-
// src/matter/behaviors/identify-server.ts
|
|
155441
|
-
init_esm();
|
|
155442
|
-
|
|
155443
155322
|
// ../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/behaviors.js
|
|
155444
155323
|
init_nodejs();
|
|
155445
155324
|
|
|
@@ -155733,7 +155612,7 @@ init_esm4();
|
|
|
155733
155612
|
init_esm3();
|
|
155734
155613
|
init_access_control();
|
|
155735
155614
|
init_groupcast();
|
|
155736
|
-
var
|
|
155615
|
+
var logger196 = Logger.get("GroupcastServer");
|
|
155737
155616
|
var UNMAPPED_KEYSET_ID = 65535;
|
|
155738
155617
|
var GROUPCAST_IS_PROVISIONAL = true;
|
|
155739
155618
|
var GroupcastServer = class extends GroupcastBehavior {
|
|
@@ -156150,7 +156029,7 @@ var GroupcastServer = class extends GroupcastBehavior {
|
|
|
156150
156029
|
if (hasMembership) continue;
|
|
156151
156030
|
const fabricGroups = gkmState.groupTable.filter((g) => g.fabricIndex === fi);
|
|
156152
156031
|
if (fabricGroups.length === 0) continue;
|
|
156153
|
-
|
|
156032
|
+
logger196.info(`Migrating ${fabricGroups.length} legacy group(s) for fabric ${fi} to Groupcast`);
|
|
156154
156033
|
const newEntries = fabricGroups.map((group) => {
|
|
156155
156034
|
const keyMapping = gkmState.groupKeyMap.find((m) => m.fabricIndex === fi && m.groupId === group.groupId);
|
|
156156
156035
|
const mcastAddrPolicy = this.features.perGroup ? Groupcast3.MulticastAddrPolicy.PerGroup : Groupcast3.MulticastAddrPolicy.IanaAddr;
|
|
@@ -156172,7 +156051,7 @@ var GroupcastServer = class extends GroupcastBehavior {
|
|
|
156172
156051
|
}
|
|
156173
156052
|
if (migrated) {
|
|
156174
156053
|
this.#updateUsedMcastAddrCount();
|
|
156175
|
-
|
|
156054
|
+
logger196.info("Groupcast migration complete");
|
|
156176
156055
|
}
|
|
156177
156056
|
}
|
|
156178
156057
|
async [Symbol.asyncDispose]() {
|
|
@@ -156706,7 +156585,174 @@ var WebRtcTransportDefinitions3 = ClusterType(WebRtcTransportDefinitions2);
|
|
|
156706
156585
|
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
156707
156586
|
init_wi_fi_network_diagnostics();
|
|
156708
156587
|
|
|
156588
|
+
// src/matter/tc-general-commissioning.ts
|
|
156589
|
+
var TcBase = GeneralCommissioningServer.with(
|
|
156590
|
+
GeneralCommissioning3.Feature.TermsAndConditions
|
|
156591
|
+
);
|
|
156592
|
+
var TcGeneralCommissioningServer = class extends TcBase {
|
|
156593
|
+
setTcAcknowledgements({
|
|
156594
|
+
tcVersion
|
|
156595
|
+
}) {
|
|
156596
|
+
this.state.tcAcceptedVersion = tcVersion;
|
|
156597
|
+
return { errorCode: GeneralCommissioning3.CommissioningError.Ok };
|
|
156598
|
+
}
|
|
156599
|
+
};
|
|
156600
|
+
((TcGeneralCommissioningServer2) => {
|
|
156601
|
+
class State extends TcBase.State {
|
|
156602
|
+
tcAcceptedVersion = 0;
|
|
156603
|
+
tcMinRequiredVersion = 0;
|
|
156604
|
+
// typed number upstream, managed as a bitmap object at runtime
|
|
156605
|
+
tcAcknowledgements = {};
|
|
156606
|
+
// model default is true, but nothing is enforced here
|
|
156607
|
+
tcAcknowledgementsRequired = false;
|
|
156608
|
+
tcUpdateDeadline = null;
|
|
156609
|
+
}
|
|
156610
|
+
TcGeneralCommissioningServer2.State = State;
|
|
156611
|
+
})(TcGeneralCommissioningServer || (TcGeneralCommissioningServer = {}));
|
|
156612
|
+
function rootEndpointType(flags2) {
|
|
156613
|
+
return flags2?.supportTermsAndConditions ? ServerNode.RootEndpoint.with(TcGeneralCommissioningServer) : ServerNode.RootEndpoint;
|
|
156614
|
+
}
|
|
156615
|
+
|
|
156616
|
+
// src/matter/endpoints/server-mode-server-node.ts
|
|
156617
|
+
var logger197 = Logger.get("ServerModeServerNode");
|
|
156618
|
+
var ServerModeServerNode = class extends ServerNode {
|
|
156619
|
+
deviceEndpoints = /* @__PURE__ */ new Map();
|
|
156620
|
+
featureFlags;
|
|
156621
|
+
serialNumberSuffix;
|
|
156622
|
+
constructor(env, bridgeData) {
|
|
156623
|
+
super({
|
|
156624
|
+
type: rootEndpointType(bridgeData.featureFlags),
|
|
156625
|
+
id: bridgeData.id,
|
|
156626
|
+
environment: env,
|
|
156627
|
+
network: {
|
|
156628
|
+
port: bridgeData.port,
|
|
156629
|
+
// Shared zero-jitter window, see matterSubscriptionOptions: 60s max so
|
|
156630
|
+
// iOS does not show a stale "Updating" tile (#287), no jitter so the
|
|
156631
|
+
// keepalive stays inside a controller's ceiling (#386).
|
|
156632
|
+
subscriptionOptions: matterSubscriptionOptions(),
|
|
156633
|
+
...bridgeData.featureFlags?.enableMatterTcp ? { tcp: CAMERA_TCP_CONFIG } : {}
|
|
156634
|
+
},
|
|
156635
|
+
productDescription: {
|
|
156636
|
+
name: bridgeData.name,
|
|
156637
|
+
deviceType: DeviceTypeId(RoboticVacuumCleanerDevice.deviceType)
|
|
156638
|
+
},
|
|
156639
|
+
basicInformation: {
|
|
156640
|
+
...legacySpecBasicInformation(bridgeData.featureFlags),
|
|
156641
|
+
uniqueId: bridgeData.id,
|
|
156642
|
+
nodeLabel: trimToLength(bridgeData.name, 32, "..."),
|
|
156643
|
+
vendorId: VendorId(bridgeData.basicInformation.vendorId),
|
|
156644
|
+
vendorName: bridgeData.basicInformation.vendorName,
|
|
156645
|
+
productId: bridgeData.basicInformation.productId,
|
|
156646
|
+
productName: bridgeData.basicInformation.productName,
|
|
156647
|
+
productLabel: bridgeData.basicInformation.productLabel,
|
|
156648
|
+
serialNumber: `server-${bridgeData.id}`.substring(0, 32),
|
|
156649
|
+
hardwareVersion: bridgeData.basicInformation.hardwareVersion,
|
|
156650
|
+
softwareVersion: bridgeData.basicInformation.softwareVersion,
|
|
156651
|
+
hardwareVersionString: bridgeData.basicInformation.hardwareVersionString,
|
|
156652
|
+
softwareVersionString: bridgeData.basicInformation.softwareVersionString ?? String(bridgeData.basicInformation.softwareVersion),
|
|
156653
|
+
...bridgeData.countryCode ? { location: bridgeData.countryCode } : {}
|
|
156654
|
+
},
|
|
156655
|
+
subscriptions: {
|
|
156656
|
+
persistenceEnabled: false
|
|
156657
|
+
}
|
|
156658
|
+
});
|
|
156659
|
+
this.featureFlags = bridgeData.featureFlags;
|
|
156660
|
+
this.serialNumberSuffix = bridgeData.serialNumberSuffix;
|
|
156661
|
+
}
|
|
156662
|
+
/** Number of device endpoints currently attached. */
|
|
156663
|
+
get deviceCount() {
|
|
156664
|
+
return this.deviceEndpoints.size;
|
|
156665
|
+
}
|
|
156666
|
+
/**
|
|
156667
|
+
* Add a device endpoint to this server node. Several endpoints per node are
|
|
156668
|
+
* supported (#301); the call is idempotent per endpoint id.
|
|
156669
|
+
*/
|
|
156670
|
+
async addDevice(endpoint) {
|
|
156671
|
+
if (this.deviceEndpoints.has(endpoint.id)) {
|
|
156672
|
+
return;
|
|
156673
|
+
}
|
|
156674
|
+
this.deviceEndpoints.set(endpoint.id, endpoint);
|
|
156675
|
+
await this.add(endpoint);
|
|
156676
|
+
}
|
|
156677
|
+
/**
|
|
156678
|
+
* Drop one device reference after the endpoint has been deleted externally.
|
|
156679
|
+
* Must be called before re-adding an endpoint with the same id.
|
|
156680
|
+
*/
|
|
156681
|
+
forgetDevice(endpoint) {
|
|
156682
|
+
this.deviceEndpoints.delete(endpoint.id);
|
|
156683
|
+
}
|
|
156684
|
+
/** Drop all device references after the endpoints were deleted externally. */
|
|
156685
|
+
clearDevices() {
|
|
156686
|
+
this.deviceEndpoints.clear();
|
|
156687
|
+
}
|
|
156688
|
+
/**
|
|
156689
|
+
* Update root-level BasicInformation with entity-specific data.
|
|
156690
|
+
* In server mode, controllers (Apple Home, Alexa) read the root node's
|
|
156691
|
+
* BasicInformation, not the device endpoint's BridgedDeviceBasicInformation.
|
|
156692
|
+
* Without this, server-mode devices show bridge defaults (e.g. "riddix" / "MatterHub").
|
|
156693
|
+
*/
|
|
156694
|
+
async updateDeviceIdentity(entityId, device, mapping, friendlyName) {
|
|
156695
|
+
const nodeLabel = trimToLength(mapping?.customName, 32, "...") ?? trimToLength(friendlyName, 32, "...") ?? trimToLength(entityId, 32, "...");
|
|
156696
|
+
const productNameFromNodeLabel = this.featureFlags?.productNameFromNodeLabel === true ? trimToLength(sanitizeMatterString(nodeLabel ?? ""), 32, "...") ?? void 0 : void 0;
|
|
156697
|
+
const maxRawLen = 32 - (this.serialNumberSuffix?.length ?? 0);
|
|
156698
|
+
const registrySerial = this.featureFlags?.useHaRegistrySerial ? trimToLength(device?.serial_number, maxRawLen, "...") : void 0;
|
|
156699
|
+
const rawSerial = trimToLength(mapping?.customSerialNumber, maxRawLen, "...") ?? registrySerial;
|
|
156700
|
+
const serialNumber = rawSerial && this.serialNumberSuffix ? `${rawSerial}${this.serialNumberSuffix}` : rawSerial;
|
|
156701
|
+
const basicInformation = dropUndefined({
|
|
156702
|
+
vendorName: trimToLength(mapping?.customVendorName, 32, "...") ?? trimToLength(device?.manufacturer, 32, "..."),
|
|
156703
|
+
productName: trimToLength(mapping?.customProductName, 32, "...") ?? productNameFromNodeLabel ?? trimToLength(device?.model_id, 32, "...") ?? trimToLength(device?.model, 32, "..."),
|
|
156704
|
+
productLabel: trimToLength(device?.model, 64, "..."),
|
|
156705
|
+
nodeLabel,
|
|
156706
|
+
serialNumber,
|
|
156707
|
+
hardwareVersionString: trimToLength(device?.hw_version, 64, "..."),
|
|
156708
|
+
softwareVersionString: trimToLength(device?.sw_version, 64, "...")
|
|
156709
|
+
});
|
|
156710
|
+
if (Object.keys(basicInformation).length === 0) {
|
|
156711
|
+
return;
|
|
156712
|
+
}
|
|
156713
|
+
try {
|
|
156714
|
+
await this.set({ basicInformation });
|
|
156715
|
+
} catch (e) {
|
|
156716
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
156717
|
+
logger197.warn(
|
|
156718
|
+
`Failed to apply server-mode identity for ${entityId}: ${msg}`
|
|
156719
|
+
);
|
|
156720
|
+
}
|
|
156721
|
+
}
|
|
156722
|
+
// align the pairing device-type hint with the real device (default is vacuum)
|
|
156723
|
+
async updateAdvertisedDeviceType(deviceType) {
|
|
156724
|
+
try {
|
|
156725
|
+
await this.set({ productDescription: { deviceType } });
|
|
156726
|
+
} catch (e) {
|
|
156727
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
156728
|
+
logger197.warn(`Failed to set server-mode device type: ${msg}`);
|
|
156729
|
+
}
|
|
156730
|
+
}
|
|
156731
|
+
async factoryReset() {
|
|
156732
|
+
await this.cancel();
|
|
156733
|
+
await this.erase();
|
|
156734
|
+
}
|
|
156735
|
+
};
|
|
156736
|
+
function dropUndefined(obj) {
|
|
156737
|
+
const result = {};
|
|
156738
|
+
for (const key in obj) {
|
|
156739
|
+
if (obj[key] !== void 0) {
|
|
156740
|
+
result[key] = obj[key];
|
|
156741
|
+
}
|
|
156742
|
+
}
|
|
156743
|
+
return result;
|
|
156744
|
+
}
|
|
156745
|
+
|
|
156746
|
+
// src/plugins/plugin-manager.ts
|
|
156747
|
+
init_esm();
|
|
156748
|
+
import * as fs10 from "node:fs";
|
|
156749
|
+
import * as path12 from "node:path";
|
|
156750
|
+
|
|
156751
|
+
// src/plugins/plugin-device-factory.ts
|
|
156752
|
+
init_esm();
|
|
156753
|
+
|
|
156709
156754
|
// src/matter/behaviors/identify-server.ts
|
|
156755
|
+
init_esm();
|
|
156710
156756
|
init_home_assistant_entity_behavior();
|
|
156711
156757
|
var logger198 = Logger.get("IdentifyServer");
|
|
156712
156758
|
var IDENTIFY_BUTTON_SUFFIXES = ["_identify", "_locate", "_find_me"];
|
|
@@ -158079,12 +158125,13 @@ Object.freeze(SecondaryNetworkInterfaceEndpointDefinition);
|
|
|
158079
158125
|
init_types2();
|
|
158080
158126
|
function createBridgeServerConfig(data, options) {
|
|
158081
158127
|
return {
|
|
158082
|
-
type:
|
|
158128
|
+
type: rootEndpointType(data.featureFlags),
|
|
158083
158129
|
id: data.id,
|
|
158084
158130
|
network: {
|
|
158085
158131
|
port: data.port,
|
|
158086
158132
|
subscriptionOptions: matterSubscriptionOptions(),
|
|
158087
|
-
|
|
158133
|
+
// camera serverOptions win, the flag reuses the same listener config
|
|
158134
|
+
...options?.tcp ? { tcp: options.tcp } : data.featureFlags?.enableMatterTcp ? { tcp: CAMERA_TCP_CONFIG } : {}
|
|
158088
158135
|
},
|
|
158089
158136
|
productDescription: {
|
|
158090
158137
|
name: data.name,
|
|
@@ -158596,7 +158643,7 @@ var Bridge = class {
|
|
|
158596
158643
|
// message size. Match the bridge listener to the saved camera list. Changing
|
|
158597
158644
|
// network config takes effect on (re)start, so bounce the bridge if running.
|
|
158598
158645
|
async applyCameraTcp(config8) {
|
|
158599
|
-
const want = parseCameraList(config8.cameras).length > 0;
|
|
158646
|
+
const want = parseCameraList(config8.cameras).length > 0 || !!this.dataProvider.featureFlags?.enableMatterTcp;
|
|
158600
158647
|
const have = !!this.server.state.network.tcp;
|
|
158601
158648
|
if (want === have) {
|
|
158602
158649
|
return;
|
|
@@ -158680,6 +158727,10 @@ var Bridge = class {
|
|
|
158680
158727
|
BasicInformationServer,
|
|
158681
158728
|
specVersionValues(this.dataProvider.featureFlags)
|
|
158682
158729
|
);
|
|
158730
|
+
await applyTcpFlagBeforeStart(
|
|
158731
|
+
this.server,
|
|
158732
|
+
this.dataProvider.featureFlags
|
|
158733
|
+
);
|
|
158683
158734
|
await this.server.start();
|
|
158684
158735
|
await this.endpointManager.startPlugins();
|
|
158685
158736
|
this.setStatus({ code: BridgeStatus.Running });
|
|
@@ -179318,6 +179369,10 @@ var ServerModeBridge = class {
|
|
|
179318
179369
|
BasicInformationServer,
|
|
179319
179370
|
specVersionValues(this.dataProvider.featureFlags)
|
|
179320
179371
|
);
|
|
179372
|
+
await applyTcpFlagBeforeStart(
|
|
179373
|
+
this.server,
|
|
179374
|
+
this.dataProvider.featureFlags
|
|
179375
|
+
);
|
|
179321
179376
|
await this.server.start();
|
|
179322
179377
|
this.setStatus({ code: BridgeStatus.Running });
|
|
179323
179378
|
this.startAutoForceSyncIfEnabled();
|