@riddix/hamh 2.1.0-alpha.584 → 2.1.0-alpha.585
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
|
@@ -164899,6 +164899,74 @@ init_esm5();
|
|
|
164899
164899
|
init_nodejs();
|
|
164900
164900
|
init_esm3();
|
|
164901
164901
|
|
|
164902
|
+
// src/utils/apply-patch-state.ts
|
|
164903
|
+
init_esm();
|
|
164904
|
+
var logger157 = Logger.get("ApplyPatchState");
|
|
164905
|
+
function applyPatchState(state, patch, options) {
|
|
164906
|
+
return applyPatch(state, patch, options?.force);
|
|
164907
|
+
}
|
|
164908
|
+
function applyPatch(state, patch, force = false) {
|
|
164909
|
+
const actualPatch = {};
|
|
164910
|
+
for (const key in patch) {
|
|
164911
|
+
if (Object.hasOwn(patch, key)) {
|
|
164912
|
+
const patchValue = patch[key];
|
|
164913
|
+
if (patchValue !== void 0) {
|
|
164914
|
+
const stateValue = state[key];
|
|
164915
|
+
if (force || !deepEqual(stateValue, patchValue)) {
|
|
164916
|
+
actualPatch[key] = patchValue;
|
|
164917
|
+
}
|
|
164918
|
+
}
|
|
164919
|
+
}
|
|
164920
|
+
}
|
|
164921
|
+
const failedKeys = [];
|
|
164922
|
+
for (const key in actualPatch) {
|
|
164923
|
+
if (!Object.hasOwn(actualPatch, key)) continue;
|
|
164924
|
+
try {
|
|
164925
|
+
state[key] = actualPatch[key];
|
|
164926
|
+
} catch (e) {
|
|
164927
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
164928
|
+
if (errorMessage.includes(
|
|
164929
|
+
"Endpoint storage inaccessible because endpoint is not a node and is not owned by another endpoint"
|
|
164930
|
+
)) {
|
|
164931
|
+
logger157.debug(
|
|
164932
|
+
`Suppressed endpoint storage error, patch not applied: ${JSON.stringify(actualPatch)}`
|
|
164933
|
+
);
|
|
164934
|
+
return actualPatch;
|
|
164935
|
+
}
|
|
164936
|
+
if (errorMessage.includes("synchronous-transaction-conflict")) {
|
|
164937
|
+
logger157.warn(
|
|
164938
|
+
`Transaction conflict, state update DROPPED: ${JSON.stringify(actualPatch)}`
|
|
164939
|
+
);
|
|
164940
|
+
return actualPatch;
|
|
164941
|
+
}
|
|
164942
|
+
failedKeys.push(key);
|
|
164943
|
+
logger157.warn(`Failed to set property '${key}': ${errorMessage}`);
|
|
164944
|
+
}
|
|
164945
|
+
}
|
|
164946
|
+
if (failedKeys.length > 0) {
|
|
164947
|
+
logger157.warn(
|
|
164948
|
+
`${failedKeys.length} properties failed to update: [${failedKeys.join(", ")}]`
|
|
164949
|
+
);
|
|
164950
|
+
}
|
|
164951
|
+
return actualPatch;
|
|
164952
|
+
}
|
|
164953
|
+
function deepEqual(a, b) {
|
|
164954
|
+
if (a == null || b == null) {
|
|
164955
|
+
return a === b;
|
|
164956
|
+
}
|
|
164957
|
+
if (typeof a !== typeof b || Array.isArray(a) !== Array.isArray(b)) {
|
|
164958
|
+
return false;
|
|
164959
|
+
}
|
|
164960
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
164961
|
+
return a.length === b.length && a.every((vA, idx) => deepEqual(vA, b[idx]));
|
|
164962
|
+
}
|
|
164963
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
164964
|
+
const keys3 = Object.keys({ ...a, ...b });
|
|
164965
|
+
return keys3.every((key) => deepEqual(a[key], b[key]));
|
|
164966
|
+
}
|
|
164967
|
+
return a === b;
|
|
164968
|
+
}
|
|
164969
|
+
|
|
164902
164970
|
// src/utils/trim-to-length.ts
|
|
164903
164971
|
function trimToLength(value, maxLength, suffix) {
|
|
164904
164972
|
const stringValue = value?.toString();
|
|
@@ -164962,6 +165030,23 @@ var ServerModeServerNode = class extends ServerNode {
|
|
|
164962
165030
|
clearDevice() {
|
|
164963
165031
|
this.deviceEndpoint = void 0;
|
|
164964
165032
|
}
|
|
165033
|
+
/**
|
|
165034
|
+
* Update root-level BasicInformation with entity-specific data.
|
|
165035
|
+
* In server mode, controllers (Apple Home, Alexa) read the root node's
|
|
165036
|
+
* BasicInformation — not the device endpoint's BridgedDeviceBasicInformation.
|
|
165037
|
+
* Without this, server-mode devices show bridge defaults (e.g. "riddix" / "MatterHub").
|
|
165038
|
+
*/
|
|
165039
|
+
updateDeviceIdentity(entityId, device, mapping, friendlyName) {
|
|
165040
|
+
applyPatchState(this.state.basicInformation, {
|
|
165041
|
+
vendorName: trimToLength(mapping?.customVendorName, 32, "...") ?? trimToLength(device?.manufacturer, 32, "..."),
|
|
165042
|
+
productName: trimToLength(mapping?.customProductName, 32, "...") ?? trimToLength(device?.model_id, 32, "...") ?? trimToLength(device?.model, 32, "..."),
|
|
165043
|
+
productLabel: trimToLength(device?.model, 64, "..."),
|
|
165044
|
+
nodeLabel: trimToLength(mapping?.customName, 32, "...") ?? trimToLength(friendlyName, 32, "...") ?? trimToLength(entityId, 32, "..."),
|
|
165045
|
+
serialNumber: trimToLength(mapping?.customSerialNumber, 32, "..."),
|
|
165046
|
+
hardwareVersionString: trimToLength(device?.hw_version, 64, "..."),
|
|
165047
|
+
softwareVersionString: trimToLength(device?.sw_version, 64, "...")
|
|
165048
|
+
});
|
|
165049
|
+
}
|
|
164965
165050
|
async factoryReset() {
|
|
164966
165051
|
await this.cancel();
|
|
164967
165052
|
await this.erase();
|
|
@@ -165053,7 +165138,7 @@ init_basic_information2();
|
|
|
165053
165138
|
init_descriptor2();
|
|
165054
165139
|
init_aggregator();
|
|
165055
165140
|
init_esm();
|
|
165056
|
-
var
|
|
165141
|
+
var logger158 = Logger.get("BridgedDeviceBasicInformationServer");
|
|
165057
165142
|
var BridgedDeviceBasicInformationServer = class extends BridgedDeviceBasicInformationBehavior {
|
|
165058
165143
|
async initialize() {
|
|
165059
165144
|
if (this.endpoint.lifecycle.isInstalled) {
|
|
@@ -165068,7 +165153,7 @@ var BridgedDeviceBasicInformationServer = class extends BridgedDeviceBasicInform
|
|
|
165068
165153
|
this.state.uniqueId = BasicInformationServer.createUniqueId();
|
|
165069
165154
|
}
|
|
165070
165155
|
if (serialNumber !== void 0 && uniqueId === this.state.serialNumber) {
|
|
165071
|
-
|
|
165156
|
+
logger158.warn("uniqueId and serialNumber shall not be the same.");
|
|
165072
165157
|
}
|
|
165073
165158
|
}
|
|
165074
165159
|
static schema = BasicInformationServer.enableUniqueIdPersistence(
|
|
@@ -165940,7 +166025,7 @@ var IdentifyServer2 = class extends IdentifyServer {
|
|
|
165940
166025
|
// src/matter/endpoints/validate-endpoint-type.ts
|
|
165941
166026
|
init_esm();
|
|
165942
166027
|
init_esm7();
|
|
165943
|
-
var
|
|
166028
|
+
var logger159 = Logger.get("EndpointValidation");
|
|
165944
166029
|
function toCamelCase(name) {
|
|
165945
166030
|
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
165946
166031
|
}
|
|
@@ -165970,12 +166055,12 @@ function validateEndpointType(endpointType, entityId) {
|
|
|
165970
166055
|
}
|
|
165971
166056
|
const prefix = entityId ? `[${entityId}] ` : "";
|
|
165972
166057
|
if (missingMandatory.length > 0) {
|
|
165973
|
-
|
|
166058
|
+
logger159.warn(
|
|
165974
166059
|
`${prefix}${deviceTypeModel.name} (0x${endpointType.deviceType.toString(16)}): missing mandatory clusters: ${missingMandatory.join(", ")}`
|
|
165975
166060
|
);
|
|
165976
166061
|
}
|
|
165977
166062
|
if (availableOptional.length > 0) {
|
|
165978
|
-
|
|
166063
|
+
logger159.debug(
|
|
165979
166064
|
`${prefix}${deviceTypeModel.name} (0x${endpointType.deviceType.toString(16)}): optional clusters not used: ${availableOptional.join(", ")}`
|
|
165980
166065
|
);
|
|
165981
166066
|
}
|
|
@@ -166078,74 +166163,6 @@ var BridgeDataProvider = class extends Service {
|
|
|
166078
166163
|
}
|
|
166079
166164
|
};
|
|
166080
166165
|
|
|
166081
|
-
// src/utils/apply-patch-state.ts
|
|
166082
|
-
init_esm();
|
|
166083
|
-
var logger159 = Logger.get("ApplyPatchState");
|
|
166084
|
-
function applyPatchState(state, patch, options) {
|
|
166085
|
-
return applyPatch(state, patch, options?.force);
|
|
166086
|
-
}
|
|
166087
|
-
function applyPatch(state, patch, force = false) {
|
|
166088
|
-
const actualPatch = {};
|
|
166089
|
-
for (const key in patch) {
|
|
166090
|
-
if (Object.hasOwn(patch, key)) {
|
|
166091
|
-
const patchValue = patch[key];
|
|
166092
|
-
if (patchValue !== void 0) {
|
|
166093
|
-
const stateValue = state[key];
|
|
166094
|
-
if (force || !deepEqual(stateValue, patchValue)) {
|
|
166095
|
-
actualPatch[key] = patchValue;
|
|
166096
|
-
}
|
|
166097
|
-
}
|
|
166098
|
-
}
|
|
166099
|
-
}
|
|
166100
|
-
const failedKeys = [];
|
|
166101
|
-
for (const key in actualPatch) {
|
|
166102
|
-
if (!Object.hasOwn(actualPatch, key)) continue;
|
|
166103
|
-
try {
|
|
166104
|
-
state[key] = actualPatch[key];
|
|
166105
|
-
} catch (e) {
|
|
166106
|
-
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
166107
|
-
if (errorMessage.includes(
|
|
166108
|
-
"Endpoint storage inaccessible because endpoint is not a node and is not owned by another endpoint"
|
|
166109
|
-
)) {
|
|
166110
|
-
logger159.debug(
|
|
166111
|
-
`Suppressed endpoint storage error, patch not applied: ${JSON.stringify(actualPatch)}`
|
|
166112
|
-
);
|
|
166113
|
-
return actualPatch;
|
|
166114
|
-
}
|
|
166115
|
-
if (errorMessage.includes("synchronous-transaction-conflict")) {
|
|
166116
|
-
logger159.warn(
|
|
166117
|
-
`Transaction conflict, state update DROPPED: ${JSON.stringify(actualPatch)}`
|
|
166118
|
-
);
|
|
166119
|
-
return actualPatch;
|
|
166120
|
-
}
|
|
166121
|
-
failedKeys.push(key);
|
|
166122
|
-
logger159.warn(`Failed to set property '${key}': ${errorMessage}`);
|
|
166123
|
-
}
|
|
166124
|
-
}
|
|
166125
|
-
if (failedKeys.length > 0) {
|
|
166126
|
-
logger159.warn(
|
|
166127
|
-
`${failedKeys.length} properties failed to update: [${failedKeys.join(", ")}]`
|
|
166128
|
-
);
|
|
166129
|
-
}
|
|
166130
|
-
return actualPatch;
|
|
166131
|
-
}
|
|
166132
|
-
function deepEqual(a, b) {
|
|
166133
|
-
if (a == null || b == null) {
|
|
166134
|
-
return a === b;
|
|
166135
|
-
}
|
|
166136
|
-
if (typeof a !== typeof b || Array.isArray(a) !== Array.isArray(b)) {
|
|
166137
|
-
return false;
|
|
166138
|
-
}
|
|
166139
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
166140
|
-
return a.length === b.length && a.every((vA, idx) => deepEqual(vA, b[idx]));
|
|
166141
|
-
}
|
|
166142
|
-
if (typeof a === "object" && typeof b === "object") {
|
|
166143
|
-
const keys3 = Object.keys({ ...a, ...b });
|
|
166144
|
-
return keys3.every((key) => deepEqual(a[key], b[key]));
|
|
166145
|
-
}
|
|
166146
|
-
return a === b;
|
|
166147
|
-
}
|
|
166148
|
-
|
|
166149
166166
|
// src/plugins/plugin-behavior.ts
|
|
166150
166167
|
init_esm7();
|
|
166151
166168
|
var PluginDeviceBehavior = class extends Behavior {
|
|
@@ -181592,6 +181609,7 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
181592
181609
|
await this.serverNode.addDevice(endpoint2);
|
|
181593
181610
|
this.deviceEndpoint = endpoint2;
|
|
181594
181611
|
this.mappingFingerprint = currentFp;
|
|
181612
|
+
this.updateServerNodeIdentity(entityId, mapping);
|
|
181595
181613
|
this.log.info(
|
|
181596
181614
|
`Server mode: Added vacuum ${entityId} as standalone device`
|
|
181597
181615
|
);
|
|
@@ -181612,6 +181630,7 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
181612
181630
|
await this.serverNode.addDevice(endpoint);
|
|
181613
181631
|
this.deviceEndpoint = endpoint;
|
|
181614
181632
|
this.mappingFingerprint = currentFp;
|
|
181633
|
+
this.updateServerNodeIdentity(entityId, mapping);
|
|
181615
181634
|
this.log.info(`Server mode: Added device ${entityId}`);
|
|
181616
181635
|
} catch (e) {
|
|
181617
181636
|
const reason = e instanceof Error ? e.message : String(e);
|
|
@@ -181632,6 +181651,17 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
181632
181651
|
}
|
|
181633
181652
|
}
|
|
181634
181653
|
}
|
|
181654
|
+
updateServerNodeIdentity(entityId, mapping) {
|
|
181655
|
+
const device = this.registry.deviceOf(entityId);
|
|
181656
|
+
const state = this.registry.initialState(entityId);
|
|
181657
|
+
const friendlyName = state?.attributes?.friendly_name;
|
|
181658
|
+
this.serverNode.updateDeviceIdentity(
|
|
181659
|
+
entityId,
|
|
181660
|
+
device,
|
|
181661
|
+
mapping,
|
|
181662
|
+
friendlyName
|
|
181663
|
+
);
|
|
181664
|
+
}
|
|
181635
181665
|
/**
|
|
181636
181666
|
* Creates a Server Mode Vacuum endpoint without BridgedDeviceBasicInformation.
|
|
181637
181667
|
* This makes the vacuum appear as a standalone Matter device, which is required
|