@camstack/addon-provider-homeassistant 1.2.152 → 1.2.153
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/addon.js +40 -10
- package/dist/addon.mjs +40 -10
- package/dist/{dist-nbfaHTXG.js → dist-DMn4t1u_.js} +539 -80
- package/dist/{dist-BITMr6s5.mjs → dist-evNLjXgk.mjs} +539 -80
- package/dist/ha-export/ha-export.addon.js +1 -1
- package/dist/ha-export/ha-export.addon.mjs +1 -1
- package/package.json +1 -3
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-DMn4t1u_.js");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let node_zlib = require("node:zlib");
|
|
5
5
|
//#region src/ha-admin-link.ts
|
|
@@ -960,7 +960,9 @@ var HaBinarySensorDevice = class extends HaBaseChildDevice {
|
|
|
960
960
|
this.capName = capName;
|
|
961
961
|
this.registerCap(capName);
|
|
962
962
|
const stored = this.runtimeState.getCapState(capName);
|
|
963
|
-
|
|
963
|
+
const seededActive = storedActiveLevel(capName, stored) ?? false;
|
|
964
|
+
const seededChangedAt = storedChangedAt(capName, stored) ?? 0;
|
|
965
|
+
this.runtimeState.setCapState(this.capName, buildSlice(capName, seededActive, seededChangedAt, stored));
|
|
964
966
|
}
|
|
965
967
|
handleStatePush(state) {
|
|
966
968
|
if (state.state === "unavailable" || state.state === "unknown") return;
|
|
@@ -1052,6 +1054,32 @@ function priorLastDetectedAt(prior) {
|
|
|
1052
1054
|
const raw = prior?.["lastDetectedAt"];
|
|
1053
1055
|
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : null;
|
|
1054
1056
|
}
|
|
1057
|
+
/** The boolean field this cap's slice uses as "active". */
|
|
1058
|
+
function activeFieldName(capName) {
|
|
1059
|
+
switch (capName) {
|
|
1060
|
+
case "contact": return "entryOpen";
|
|
1061
|
+
case "flood": return "flooded";
|
|
1062
|
+
case "tamper": return "tampered";
|
|
1063
|
+
case "connectivity": return "connected";
|
|
1064
|
+
case "binary": return "on";
|
|
1065
|
+
case "smoke":
|
|
1066
|
+
case "carbon-monoxide":
|
|
1067
|
+
case "gas":
|
|
1068
|
+
case "vibration":
|
|
1069
|
+
case "motion": return "detected";
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
function storedActiveLevel(capName, stored) {
|
|
1073
|
+
if (stored === void 0) return void 0;
|
|
1074
|
+
const raw = stored[activeFieldName(capName)];
|
|
1075
|
+
return typeof raw === "boolean" ? raw : void 0;
|
|
1076
|
+
}
|
|
1077
|
+
function storedChangedAt(capName, stored) {
|
|
1078
|
+
if (stored === void 0) return void 0;
|
|
1079
|
+
if (capName === "motion") return priorLastDetectedAt(stored) ?? void 0;
|
|
1080
|
+
const raw = stored["lastChangedAt"];
|
|
1081
|
+
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : void 0;
|
|
1082
|
+
}
|
|
1055
1083
|
function buildSlice(capName, active, lastChangedAt, prior) {
|
|
1056
1084
|
switch (capName) {
|
|
1057
1085
|
case "contact": return {
|
|
@@ -7371,11 +7399,14 @@ function buildFreshStandaloneSpec(entity) {
|
|
|
7371
7399
|
/** Stable key over the class-affecting fields — drives the drift decision.
|
|
7372
7400
|
* Excludes `type` (compared directly) but folds it in so a pure type change
|
|
7373
7401
|
* (same caps, different DeviceType — shouldn't happen but defensively safe)
|
|
7374
|
-
* still counts.
|
|
7402
|
+
* still counts. **Role is deliberately omitted**: after adopt, Role is
|
|
7403
|
+
* operator-owned (`setRole` in the UI). Including it here made every mapping
|
|
7404
|
+
* / capability drift re-push the derived role via `applyDerivedSpec` and
|
|
7405
|
+
* revert the Role select by itself.
|
|
7406
|
+
*/
|
|
7375
7407
|
function standaloneDerivedKey(s) {
|
|
7376
7408
|
return JSON.stringify({
|
|
7377
7409
|
type: s.type,
|
|
7378
|
-
role: s.role ?? null,
|
|
7379
7410
|
capabilities: [...s.capabilities],
|
|
7380
7411
|
unitOfMeasurement: s.unitOfMeasurement ?? null,
|
|
7381
7412
|
deviceClass: s.deviceClass ?? null,
|
|
@@ -7385,7 +7416,8 @@ function standaloneDerivedKey(s) {
|
|
|
7385
7416
|
});
|
|
7386
7417
|
}
|
|
7387
7418
|
/** The config patch pushed via `applyDerivedSpec` on drift — the class-affecting
|
|
7388
|
-
* fields only (mirrors the Container reconcile's `childConfigPatch`)
|
|
7419
|
+
* fields only (mirrors the Container reconcile's `childConfigPatch`), minus
|
|
7420
|
+
* `role` which is operator-owned after adopt and must not be clobbered. */
|
|
7389
7421
|
function standaloneConfigPatch(s) {
|
|
7390
7422
|
return {
|
|
7391
7423
|
capabilities: [...s.capabilities],
|
|
@@ -7393,22 +7425,21 @@ function standaloneConfigPatch(s) {
|
|
|
7393
7425
|
...s.deviceClass !== void 0 ? { deviceClass: s.deviceClass } : {},
|
|
7394
7426
|
...s.options !== void 0 ? { options: [...s.options] } : {},
|
|
7395
7427
|
...s.features !== void 0 ? { features: [...s.features] } : {},
|
|
7396
|
-
...s.role !== void 0 ? { role: s.role } : {},
|
|
7397
7428
|
...s.dateTimeFormat !== void 0 ? { dateTimeFormat: s.dateTimeFormat } : {}
|
|
7398
7429
|
};
|
|
7399
7430
|
}
|
|
7400
7431
|
/**
|
|
7401
7432
|
* Diff a persisted standalone entity device against the fresh HA mapping. Pure —
|
|
7402
|
-
* no I/O. On drift the caller pushes `{ type,
|
|
7433
|
+
* no I/O. On drift the caller pushes `{ type, config }` through
|
|
7403
7434
|
* `kernel.devices.applyDerivedSpec(deviceId, …)`; the captured cap-re-derive
|
|
7404
7435
|
* factory rebuilds the concrete per-domain class from the new `capabilities`.
|
|
7436
|
+
* Role is never part of the patch — it is operator-owned after adopt.
|
|
7405
7437
|
*/
|
|
7406
7438
|
function diffStandaloneEntity(persisted, fresh) {
|
|
7407
7439
|
if (standaloneDerivedKey(persisted) === standaloneDerivedKey(fresh)) return { changed: false };
|
|
7408
7440
|
return {
|
|
7409
7441
|
changed: true,
|
|
7410
7442
|
type: fresh.type,
|
|
7411
|
-
...fresh.role !== void 0 ? { role: fresh.role } : {},
|
|
7412
7443
|
config: standaloneConfigPatch(fresh)
|
|
7413
7444
|
};
|
|
7414
7445
|
}
|
|
@@ -7438,7 +7469,7 @@ function standaloneEntityId(device) {
|
|
|
7438
7469
|
* Pure re-sync planner. Given the broker's live registry `devices` and the
|
|
7439
7470
|
* FRESH entity inventory (by entityId), enumerate the broker's STANDALONE entity
|
|
7440
7471
|
* devices and produce one `applyDerivedSpec` action per device whose
|
|
7441
|
-
* capability/class
|
|
7472
|
+
* capability/class drifted. Role is never re-derived (operator-owned). No I/O.
|
|
7442
7473
|
*
|
|
7443
7474
|
* - Non-standalone / other-broker / Container / accessory-child devices →
|
|
7444
7475
|
* skipped (via {@link isStandaloneEntityDevice}).
|
|
@@ -7460,7 +7491,6 @@ function planStandaloneReconcile(devices, freshById, brokerId) {
|
|
|
7460
7491
|
actions.push({
|
|
7461
7492
|
deviceId: device.id,
|
|
7462
7493
|
...diff.type !== void 0 ? { type: diff.type } : {},
|
|
7463
|
-
...diff.role !== void 0 ? { role: diff.role } : {},
|
|
7464
7494
|
...diff.config !== void 0 ? { config: diff.config } : {}
|
|
7465
7495
|
});
|
|
7466
7496
|
}
|
package/dist/addon.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as parseAdminBase, A as contactCapability, At as union, B as gasCapability, C as buildAddonRouteProvider, Ct as array, D as climateControlCapability, Dt as object, E as carbonMonoxideCapability, Et as number, G as lockControlCapability, H as humiditySensorCapability, I as enumSensorCapability, J as normalizeUnit, K as mediaPlayerCapability, L as eventEmitterCapability, M as coverCapability, Mt as url, N as deviceAdminLinkCapability, Nt as EventCategory, O as colorCapability, Ot as record, P as deviceAdoptionCapability, R as fanControlCapability, S as brokerCapability, St as _enum, T as buttonCapability, Tt as literal, U as imageCapability, V as humidifierCapability, W as lawnMowerControlCapability, X as notifierCapability, Y as notificationOutputCapability, Z as numericSensorCapability, _ as automationControlCapability, _t as DeviceType, at as smokeCapability, b as binaryCapability, bt as createEvent, ct as temperatureSensorCapability, d as TargetSchema, dt as valveCapability, et as powerMeterCapability, f as accessoriesCapability, ft as vibrationCapability, g as ambientLightSensorCapability, gt as DeviceRole, h as alarmPanelCapability, ht as DeviceFeature, it as scriptRunnerCapability, j as controlCapability, jt as unknown, k as connectivityCapability, kt as string, lt as updateCapability, m as airQualitySensorCapability, mt as weatherCapability, n as BaseDevice, nt as presenceCapability, ot as switchCapability, p as addonRoutesCapability, pt as waterHeaterCapability, q as motionCapability, r as BaseDeviceProvider, rt as pressureSensorCapability, s as EnumSensorDateTimeFormatSchema, st as tamperCapability, tt as prepareNotification, ut as vacuumControlCapability, v as batteryCapability, vt as errMsg, w as buildDeviceAdminUrl, wt as discriminatedUnion, x as brightnessCapability, y as bestLocationMatch, z as floodCapability } from "./dist-
|
|
1
|
+
import { $ as parseAdminBase, A as contactCapability, At as union, B as gasCapability, C as buildAddonRouteProvider, Ct as array, D as climateControlCapability, Dt as object, E as carbonMonoxideCapability, Et as number, G as lockControlCapability, H as humiditySensorCapability, I as enumSensorCapability, J as normalizeUnit, K as mediaPlayerCapability, L as eventEmitterCapability, M as coverCapability, Mt as url, N as deviceAdminLinkCapability, Nt as EventCategory, O as colorCapability, Ot as record, P as deviceAdoptionCapability, R as fanControlCapability, S as brokerCapability, St as _enum, T as buttonCapability, Tt as literal, U as imageCapability, V as humidifierCapability, W as lawnMowerControlCapability, X as notifierCapability, Y as notificationOutputCapability, Z as numericSensorCapability, _ as automationControlCapability, _t as DeviceType, at as smokeCapability, b as binaryCapability, bt as createEvent, ct as temperatureSensorCapability, d as TargetSchema, dt as valveCapability, et as powerMeterCapability, f as accessoriesCapability, ft as vibrationCapability, g as ambientLightSensorCapability, gt as DeviceRole, h as alarmPanelCapability, ht as DeviceFeature, it as scriptRunnerCapability, j as controlCapability, jt as unknown, k as connectivityCapability, kt as string, lt as updateCapability, m as airQualitySensorCapability, mt as weatherCapability, n as BaseDevice, nt as presenceCapability, ot as switchCapability, p as addonRoutesCapability, pt as waterHeaterCapability, q as motionCapability, r as BaseDeviceProvider, rt as pressureSensorCapability, s as EnumSensorDateTimeFormatSchema, st as tamperCapability, tt as prepareNotification, ut as vacuumControlCapability, v as batteryCapability, vt as errMsg, w as buildDeviceAdminUrl, wt as discriminatedUnion, x as brightnessCapability, y as bestLocationMatch, z as floodCapability } from "./dist-evNLjXgk.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
|
|
4
4
|
//#region src/ha-admin-link.ts
|
|
@@ -959,7 +959,9 @@ var HaBinarySensorDevice = class extends HaBaseChildDevice {
|
|
|
959
959
|
this.capName = capName;
|
|
960
960
|
this.registerCap(capName);
|
|
961
961
|
const stored = this.runtimeState.getCapState(capName);
|
|
962
|
-
|
|
962
|
+
const seededActive = storedActiveLevel(capName, stored) ?? false;
|
|
963
|
+
const seededChangedAt = storedChangedAt(capName, stored) ?? 0;
|
|
964
|
+
this.runtimeState.setCapState(this.capName, buildSlice(capName, seededActive, seededChangedAt, stored));
|
|
963
965
|
}
|
|
964
966
|
handleStatePush(state) {
|
|
965
967
|
if (state.state === "unavailable" || state.state === "unknown") return;
|
|
@@ -1051,6 +1053,32 @@ function priorLastDetectedAt(prior) {
|
|
|
1051
1053
|
const raw = prior?.["lastDetectedAt"];
|
|
1052
1054
|
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : null;
|
|
1053
1055
|
}
|
|
1056
|
+
/** The boolean field this cap's slice uses as "active". */
|
|
1057
|
+
function activeFieldName(capName) {
|
|
1058
|
+
switch (capName) {
|
|
1059
|
+
case "contact": return "entryOpen";
|
|
1060
|
+
case "flood": return "flooded";
|
|
1061
|
+
case "tamper": return "tampered";
|
|
1062
|
+
case "connectivity": return "connected";
|
|
1063
|
+
case "binary": return "on";
|
|
1064
|
+
case "smoke":
|
|
1065
|
+
case "carbon-monoxide":
|
|
1066
|
+
case "gas":
|
|
1067
|
+
case "vibration":
|
|
1068
|
+
case "motion": return "detected";
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
function storedActiveLevel(capName, stored) {
|
|
1072
|
+
if (stored === void 0) return void 0;
|
|
1073
|
+
const raw = stored[activeFieldName(capName)];
|
|
1074
|
+
return typeof raw === "boolean" ? raw : void 0;
|
|
1075
|
+
}
|
|
1076
|
+
function storedChangedAt(capName, stored) {
|
|
1077
|
+
if (stored === void 0) return void 0;
|
|
1078
|
+
if (capName === "motion") return priorLastDetectedAt(stored) ?? void 0;
|
|
1079
|
+
const raw = stored["lastChangedAt"];
|
|
1080
|
+
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : void 0;
|
|
1081
|
+
}
|
|
1054
1082
|
function buildSlice(capName, active, lastChangedAt, prior) {
|
|
1055
1083
|
switch (capName) {
|
|
1056
1084
|
case "contact": return {
|
|
@@ -7370,11 +7398,14 @@ function buildFreshStandaloneSpec(entity) {
|
|
|
7370
7398
|
/** Stable key over the class-affecting fields — drives the drift decision.
|
|
7371
7399
|
* Excludes `type` (compared directly) but folds it in so a pure type change
|
|
7372
7400
|
* (same caps, different DeviceType — shouldn't happen but defensively safe)
|
|
7373
|
-
* still counts.
|
|
7401
|
+
* still counts. **Role is deliberately omitted**: after adopt, Role is
|
|
7402
|
+
* operator-owned (`setRole` in the UI). Including it here made every mapping
|
|
7403
|
+
* / capability drift re-push the derived role via `applyDerivedSpec` and
|
|
7404
|
+
* revert the Role select by itself.
|
|
7405
|
+
*/
|
|
7374
7406
|
function standaloneDerivedKey(s) {
|
|
7375
7407
|
return JSON.stringify({
|
|
7376
7408
|
type: s.type,
|
|
7377
|
-
role: s.role ?? null,
|
|
7378
7409
|
capabilities: [...s.capabilities],
|
|
7379
7410
|
unitOfMeasurement: s.unitOfMeasurement ?? null,
|
|
7380
7411
|
deviceClass: s.deviceClass ?? null,
|
|
@@ -7384,7 +7415,8 @@ function standaloneDerivedKey(s) {
|
|
|
7384
7415
|
});
|
|
7385
7416
|
}
|
|
7386
7417
|
/** The config patch pushed via `applyDerivedSpec` on drift — the class-affecting
|
|
7387
|
-
* fields only (mirrors the Container reconcile's `childConfigPatch`)
|
|
7418
|
+
* fields only (mirrors the Container reconcile's `childConfigPatch`), minus
|
|
7419
|
+
* `role` which is operator-owned after adopt and must not be clobbered. */
|
|
7388
7420
|
function standaloneConfigPatch(s) {
|
|
7389
7421
|
return {
|
|
7390
7422
|
capabilities: [...s.capabilities],
|
|
@@ -7392,22 +7424,21 @@ function standaloneConfigPatch(s) {
|
|
|
7392
7424
|
...s.deviceClass !== void 0 ? { deviceClass: s.deviceClass } : {},
|
|
7393
7425
|
...s.options !== void 0 ? { options: [...s.options] } : {},
|
|
7394
7426
|
...s.features !== void 0 ? { features: [...s.features] } : {},
|
|
7395
|
-
...s.role !== void 0 ? { role: s.role } : {},
|
|
7396
7427
|
...s.dateTimeFormat !== void 0 ? { dateTimeFormat: s.dateTimeFormat } : {}
|
|
7397
7428
|
};
|
|
7398
7429
|
}
|
|
7399
7430
|
/**
|
|
7400
7431
|
* Diff a persisted standalone entity device against the fresh HA mapping. Pure —
|
|
7401
|
-
* no I/O. On drift the caller pushes `{ type,
|
|
7432
|
+
* no I/O. On drift the caller pushes `{ type, config }` through
|
|
7402
7433
|
* `kernel.devices.applyDerivedSpec(deviceId, …)`; the captured cap-re-derive
|
|
7403
7434
|
* factory rebuilds the concrete per-domain class from the new `capabilities`.
|
|
7435
|
+
* Role is never part of the patch — it is operator-owned after adopt.
|
|
7404
7436
|
*/
|
|
7405
7437
|
function diffStandaloneEntity(persisted, fresh) {
|
|
7406
7438
|
if (standaloneDerivedKey(persisted) === standaloneDerivedKey(fresh)) return { changed: false };
|
|
7407
7439
|
return {
|
|
7408
7440
|
changed: true,
|
|
7409
7441
|
type: fresh.type,
|
|
7410
|
-
...fresh.role !== void 0 ? { role: fresh.role } : {},
|
|
7411
7442
|
config: standaloneConfigPatch(fresh)
|
|
7412
7443
|
};
|
|
7413
7444
|
}
|
|
@@ -7437,7 +7468,7 @@ function standaloneEntityId(device) {
|
|
|
7437
7468
|
* Pure re-sync planner. Given the broker's live registry `devices` and the
|
|
7438
7469
|
* FRESH entity inventory (by entityId), enumerate the broker's STANDALONE entity
|
|
7439
7470
|
* devices and produce one `applyDerivedSpec` action per device whose
|
|
7440
|
-
* capability/class
|
|
7471
|
+
* capability/class drifted. Role is never re-derived (operator-owned). No I/O.
|
|
7441
7472
|
*
|
|
7442
7473
|
* - Non-standalone / other-broker / Container / accessory-child devices →
|
|
7443
7474
|
* skipped (via {@link isStandaloneEntityDevice}).
|
|
@@ -7459,7 +7490,6 @@ function planStandaloneReconcile(devices, freshById, brokerId) {
|
|
|
7459
7490
|
actions.push({
|
|
7460
7491
|
deviceId: device.id,
|
|
7461
7492
|
...diff.type !== void 0 ? { type: diff.type } : {},
|
|
7462
|
-
...diff.role !== void 0 ? { role: diff.role } : {},
|
|
7463
7493
|
...diff.config !== void 0 ? { config: diff.config } : {}
|
|
7464
7494
|
});
|
|
7465
7495
|
}
|