@camstack/addon-provider-homeassistant 1.2.639 → 1.2.640
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/addon.js +529 -460
- package/dist/addon.mjs +85 -16
- package/dist/{dist-C_XoeULr.js → ha-broker-source-0HGmZj7D.js} +2225 -853
- package/dist/{dist-Cvz76AD1.mjs → ha-broker-source-FHFpUlgq.mjs} +2208 -854
- package/dist/ha-export/ha-export.addon.js +209 -86
- package/dist/ha-export/ha-export.addon.mjs +164 -41
- package/i18n/en.json +2 -2
- package/i18n/it.json +2 -2
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
2
|
+
const require_ha_broker_source = require("./ha-broker-source-0HGmZj7D.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
|
|
@@ -72,21 +72,21 @@ function registerHaAdminLink(ctx, deviceId, brokerId, subject) {
|
|
|
72
72
|
});
|
|
73
73
|
return null;
|
|
74
74
|
};
|
|
75
|
-
ctx.registerNativeCap(
|
|
75
|
+
ctx.registerNativeCap(require_ha_broker_source.deviceAdminLinkCapability, { getAdminLink: async (input) => {
|
|
76
76
|
if (input.deviceId !== deviceId) throw new Error(`HaAdminLink: deviceId mismatch, expected ${deviceId}, got ${input.deviceId}`);
|
|
77
77
|
if (cachedBaseUrl === null) {
|
|
78
78
|
const raw = (await ctx.api.broker.getBrokerConfig.query({ id: brokerId }))?.["baseUrl"];
|
|
79
79
|
if (typeof raw !== "string" || raw.length === 0) return refuse("no-base-url");
|
|
80
80
|
cachedBaseUrl = raw;
|
|
81
81
|
}
|
|
82
|
-
const base =
|
|
82
|
+
const base = require_ha_broker_source.parseAdminBase(cachedBaseUrl);
|
|
83
83
|
if (!base.ok) {
|
|
84
84
|
cachedBaseUrl = null;
|
|
85
85
|
return refuse("base-unusable", { baseReason: base.reason });
|
|
86
86
|
}
|
|
87
87
|
const page = pageFor(subject, base.basePath);
|
|
88
88
|
if (page === null) return refuse("empty-subject");
|
|
89
|
-
const built =
|
|
89
|
+
const built = require_ha_broker_source.buildDeviceAdminUrl({
|
|
90
90
|
host: base.host,
|
|
91
91
|
port: base.port,
|
|
92
92
|
scheme: base.scheme,
|
|
@@ -114,25 +114,25 @@ function registerHaAdminLink(ctx, deviceId, brokerId, subject) {
|
|
|
114
114
|
* `readHaSource` (returns null) — do NOT use `z.object(haSourceSchemaFields).parse`.
|
|
115
115
|
*/
|
|
116
116
|
var haSourceSchemaFields = {
|
|
117
|
-
system:
|
|
118
|
-
brokerId:
|
|
119
|
-
haDeviceId:
|
|
120
|
-
entityId:
|
|
121
|
-
referenceEntityId:
|
|
122
|
-
capabilities:
|
|
123
|
-
role:
|
|
124
|
-
childDeviceIds:
|
|
125
|
-
unitOfMeasurement:
|
|
126
|
-
deviceClass:
|
|
127
|
-
integrationId:
|
|
128
|
-
options:
|
|
129
|
-
features:
|
|
117
|
+
system: require_ha_broker_source.literal("homeassistant").optional(),
|
|
118
|
+
brokerId: require_ha_broker_source.string(),
|
|
119
|
+
haDeviceId: require_ha_broker_source.string().optional(),
|
|
120
|
+
entityId: require_ha_broker_source.string().optional(),
|
|
121
|
+
referenceEntityId: require_ha_broker_source.string().nullable().optional(),
|
|
122
|
+
capabilities: require_ha_broker_source.array(require_ha_broker_source.string()).default([]),
|
|
123
|
+
role: require_ha_broker_source.string().optional(),
|
|
124
|
+
childDeviceIds: require_ha_broker_source.array(require_ha_broker_source.number()).default([]),
|
|
125
|
+
unitOfMeasurement: require_ha_broker_source.string().optional(),
|
|
126
|
+
deviceClass: require_ha_broker_source.string().optional(),
|
|
127
|
+
integrationId: require_ha_broker_source.string().optional(),
|
|
128
|
+
options: require_ha_broker_source.array(require_ha_broker_source.string()).optional(),
|
|
129
|
+
features: require_ha_broker_source.array(require_ha_broker_source.string()).optional(),
|
|
130
130
|
/** Sibling meter sensors whose readings this entity carries as `power-meter` (D951). */
|
|
131
|
-
meterEntities:
|
|
132
|
-
power:
|
|
133
|
-
energy:
|
|
134
|
-
voltage:
|
|
135
|
-
current:
|
|
131
|
+
meterEntities: require_ha_broker_source.object({
|
|
132
|
+
power: require_ha_broker_source.string().optional(),
|
|
133
|
+
energy: require_ha_broker_source.string().optional(),
|
|
134
|
+
voltage: require_ha_broker_source.string().optional(),
|
|
135
|
+
current: require_ha_broker_source.string().optional()
|
|
136
136
|
}).optional()
|
|
137
137
|
};
|
|
138
138
|
/** Project a persisted config blob into a typed source, or null when the
|
|
@@ -176,7 +176,7 @@ function readHaSource(config) {
|
|
|
176
176
|
function attachAccessoriesCap(ctx, deviceId, opts) {
|
|
177
177
|
let childIds = [];
|
|
178
178
|
const hidden = new Set(opts.initialHidden);
|
|
179
|
-
ctx.registerNativeCap(
|
|
179
|
+
ctx.registerNativeCap(require_ha_broker_source.accessoriesCapability, {
|
|
180
180
|
getStatus: async () => ({
|
|
181
181
|
childDeviceIds: childIds,
|
|
182
182
|
hiddenChildIds: [...hidden]
|
|
@@ -193,7 +193,7 @@ function attachAccessoriesCap(ctx, deviceId, opts) {
|
|
|
193
193
|
type: "device",
|
|
194
194
|
id: deviceId
|
|
195
195
|
},
|
|
196
|
-
category:
|
|
196
|
+
category: require_ha_broker_source.EventCategory.AccessoriesChildVisibilityChanged,
|
|
197
197
|
data: {
|
|
198
198
|
deviceId,
|
|
199
199
|
childDeviceId,
|
|
@@ -211,7 +211,7 @@ function attachAccessoriesCap(ctx, deviceId, opts) {
|
|
|
211
211
|
type: "device",
|
|
212
212
|
id: deviceId
|
|
213
213
|
},
|
|
214
|
-
category:
|
|
214
|
+
category: require_ha_broker_source.EventCategory.AccessoriesChanged,
|
|
215
215
|
data: {
|
|
216
216
|
deviceId,
|
|
217
217
|
childDeviceIds: childIds,
|
|
@@ -232,23 +232,23 @@ function attachAccessoriesCap(ctx, deviceId, opts) {
|
|
|
232
232
|
* in the materialisation factory (Phase E) where each domain becomes
|
|
233
233
|
* its own DeviceType + cap set.
|
|
234
234
|
*/
|
|
235
|
-
var HaEntityStateSchema =
|
|
236
|
-
entity_id:
|
|
235
|
+
var HaEntityStateSchema = require_ha_broker_source.object({
|
|
236
|
+
entity_id: require_ha_broker_source.string().min(1),
|
|
237
237
|
/** Domain-specific state value (`on`/`off`/`open`/temperature
|
|
238
238
|
* number-as-string/etc.). Always a string in HA. */
|
|
239
|
-
state:
|
|
239
|
+
state: require_ha_broker_source.string(),
|
|
240
240
|
/** Free-form attribute map. Domain-specific. */
|
|
241
|
-
attributes:
|
|
241
|
+
attributes: require_ha_broker_source.record(require_ha_broker_source.string(), require_ha_broker_source.unknown()),
|
|
242
242
|
/** Optional context envelope (user/parent id) the HA server attaches. */
|
|
243
|
-
context:
|
|
244
|
-
id:
|
|
245
|
-
parent_id:
|
|
246
|
-
user_id:
|
|
243
|
+
context: require_ha_broker_source.object({
|
|
244
|
+
id: require_ha_broker_source.string(),
|
|
245
|
+
parent_id: require_ha_broker_source.string().nullable(),
|
|
246
|
+
user_id: require_ha_broker_source.string().nullable()
|
|
247
247
|
}).optional(),
|
|
248
248
|
/** ISO 8601 timestamp of the last state change. */
|
|
249
|
-
last_changed:
|
|
249
|
+
last_changed: require_ha_broker_source.string(),
|
|
250
250
|
/** ISO 8601 timestamp of the last update (state OR attributes). */
|
|
251
|
-
last_updated:
|
|
251
|
+
last_updated: require_ha_broker_source.string()
|
|
252
252
|
});
|
|
253
253
|
/**
|
|
254
254
|
* Auth strategy. Two mutually-exclusive options:
|
|
@@ -259,16 +259,16 @@ var HaEntityStateSchema = require_dist.object({
|
|
|
259
259
|
* the addon config; the WS URL points at their HA instance
|
|
260
260
|
* (`ws://ha.example:8123/api/websocket` style).
|
|
261
261
|
*/
|
|
262
|
-
var HaAuthConfigSchema =
|
|
263
|
-
kind:
|
|
262
|
+
var HaAuthConfigSchema = require_ha_broker_source.discriminatedUnion("kind", [require_ha_broker_source.object({
|
|
263
|
+
kind: require_ha_broker_source.literal("supervisor"),
|
|
264
264
|
/** Token injected by the Supervisor at runtime via env. */
|
|
265
|
-
supervisorToken:
|
|
266
|
-
}),
|
|
267
|
-
kind:
|
|
265
|
+
supervisorToken: require_ha_broker_source.string().min(1).meta({ secret: true })
|
|
266
|
+
}), require_ha_broker_source.object({
|
|
267
|
+
kind: require_ha_broker_source.literal("long-lived"),
|
|
268
268
|
/** Origin URL of the HA instance (e.g. `https://ha.example:8123`). */
|
|
269
|
-
baseUrl:
|
|
269
|
+
baseUrl: require_ha_broker_source.url(),
|
|
270
270
|
/** Long-lived access token issued by the user in their HA profile. */
|
|
271
|
-
accessToken:
|
|
271
|
+
accessToken: require_ha_broker_source.string().min(1).meta({ secret: true })
|
|
272
272
|
})]);
|
|
273
273
|
/** HA's standard domain enum — supported subset; future domains added
|
|
274
274
|
* as integration coverage grows. */
|
|
@@ -306,7 +306,7 @@ var HaDomain = /* @__PURE__ */ function(HaDomain) {
|
|
|
306
306
|
* an unknown unit is never guessed (D393, D944).
|
|
307
307
|
*/
|
|
308
308
|
function takeReading(logger, deviceId, value, rawUnit, quantity) {
|
|
309
|
-
const result =
|
|
309
|
+
const result = require_ha_broker_source.ingestReading({
|
|
310
310
|
value,
|
|
311
311
|
rawUnit,
|
|
312
312
|
quantity
|
|
@@ -367,7 +367,7 @@ function applyMeterReading(prev, field, value, lastFetchedAt) {
|
|
|
367
367
|
lastFetchedAt
|
|
368
368
|
};
|
|
369
369
|
}
|
|
370
|
-
var LOAD_TYPES = new Set(
|
|
370
|
+
var LOAD_TYPES = new Set(require_ha_broker_source.powerMeterCapability.deviceTypes.filter((type) => type !== require_ha_broker_source.DeviceType.Sensor));
|
|
371
371
|
function isLoad(entity) {
|
|
372
372
|
return LOAD_TYPES.has(entity.deviceType) && entity.entityCategory === void 0 && !entity.capabilities.includes("power-meter");
|
|
373
373
|
}
|
|
@@ -428,7 +428,7 @@ var HaMeterCarrier = class {
|
|
|
428
428
|
const entityId = meters[field];
|
|
429
429
|
return entityId === void 0 ? [] : [[entityId, field]];
|
|
430
430
|
}));
|
|
431
|
-
this.ctx.registerNativeCap(
|
|
431
|
+
this.ctx.registerNativeCap(require_ha_broker_source.powerMeterCapability, { getStatus: async () => this.runtimeState.getCapState("power-meter") ?? COLD_START$20 });
|
|
432
432
|
this.runtimeState.setCapState("power-meter", {
|
|
433
433
|
...COLD_START$20,
|
|
434
434
|
...this.runtimeState.getCapState("power-meter")
|
|
@@ -469,7 +469,7 @@ var HaMeterCarrier = class {
|
|
|
469
469
|
* and carries `childDeviceIds` so parent-mode devices can host the
|
|
470
470
|
* accessories cap for their entity-children.
|
|
471
471
|
*/
|
|
472
|
-
var haChildDeviceSchema =
|
|
472
|
+
var haChildDeviceSchema = require_ha_broker_source.object({ ...haSourceSchemaFields });
|
|
473
473
|
/**
|
|
474
474
|
* Abstract base for every HA-entity-backed CamStack accessory device.
|
|
475
475
|
*
|
|
@@ -490,14 +490,14 @@ var haChildDeviceSchema = require_dist.object({ ...haSourceSchemaFields });
|
|
|
490
490
|
* own (beyond BaseDevice's auto-registered `device-status` /
|
|
491
491
|
* `feature-probe`).
|
|
492
492
|
*/
|
|
493
|
-
var DEVICE_FEATURE_VALUES = new Set(Object.values(
|
|
493
|
+
var DEVICE_FEATURE_VALUES = new Set(Object.values(require_ha_broker_source.DeviceFeature));
|
|
494
494
|
/** Keep only strings that are valid DeviceFeature enum values (the persisted
|
|
495
495
|
* config stores them as plain strings). */
|
|
496
496
|
function parseDeviceFeatures(raw) {
|
|
497
497
|
if (!Array.isArray(raw)) return [];
|
|
498
498
|
return raw.filter((f) => typeof f === "string" && DEVICE_FEATURE_VALUES.has(f));
|
|
499
499
|
}
|
|
500
|
-
var HaBaseChildDevice = class HaBaseChildDevice extends
|
|
500
|
+
var HaBaseChildDevice = class HaBaseChildDevice extends require_ha_broker_source.BaseDevice {
|
|
501
501
|
/** Mapping-derived feature flags (e.g. `lock-open`), read from the persisted
|
|
502
502
|
* config at construction. Surfaced on `device.features` (and re-published to
|
|
503
503
|
* the device meta in `onActivate` via `refreshFeatures`) so the UI gates
|
|
@@ -639,7 +639,7 @@ var HaBaseChildDevice = class HaBaseChildDevice extends require_dist.BaseDevice
|
|
|
639
639
|
this.deviceLogger.warn("ha-child getRawState failed to read cached state", { meta: {
|
|
640
640
|
brokerId: this.brokerId,
|
|
641
641
|
entityId: this.entityId,
|
|
642
|
-
error:
|
|
642
|
+
error: require_ha_broker_source.errMsg(err)
|
|
643
643
|
} });
|
|
644
644
|
return null;
|
|
645
645
|
}
|
|
@@ -689,7 +689,7 @@ var HaBaseChildDevice = class HaBaseChildDevice extends require_dist.BaseDevice
|
|
|
689
689
|
entityId: this.entityId,
|
|
690
690
|
domain,
|
|
691
691
|
service,
|
|
692
|
-
error:
|
|
692
|
+
error: require_ha_broker_source.errMsg(err)
|
|
693
693
|
} });
|
|
694
694
|
throw err;
|
|
695
695
|
}
|
|
@@ -716,7 +716,7 @@ var HaBaseChildDevice = class HaBaseChildDevice extends require_dist.BaseDevice
|
|
|
716
716
|
this.deviceLogger.warn("ha-child failed to register broker subscription", { meta: {
|
|
717
717
|
entityId: this.entityId,
|
|
718
718
|
brokerId: this.brokerId,
|
|
719
|
-
error:
|
|
719
|
+
error: require_ha_broker_source.errMsg(err)
|
|
720
720
|
} });
|
|
721
721
|
return false;
|
|
722
722
|
}
|
|
@@ -757,7 +757,7 @@ var HaBaseChildDevice = class HaBaseChildDevice extends require_dist.BaseDevice
|
|
|
757
757
|
} catch (err) {
|
|
758
758
|
this.deviceLogger.warn("ha-child state-push handler error", { meta: {
|
|
759
759
|
entityId: this.entityId,
|
|
760
|
-
error:
|
|
760
|
+
error: require_ha_broker_source.errMsg(err)
|
|
761
761
|
} });
|
|
762
762
|
}
|
|
763
763
|
};
|
|
@@ -786,7 +786,7 @@ var HaButtonDevice = class extends HaBaseChildDevice {
|
|
|
786
786
|
this.registerButtonCap();
|
|
787
787
|
}
|
|
788
788
|
registerButtonCap() {
|
|
789
|
-
this.ctx.registerNativeCap(
|
|
789
|
+
this.ctx.registerNativeCap(require_ha_broker_source.buttonCapability, { press: async () => {
|
|
790
790
|
const domain = this.entityId.split(".")[0] ?? "button";
|
|
791
791
|
if (domain === "scene") {
|
|
792
792
|
await this.callHaService("scene", "turn_on");
|
|
@@ -844,7 +844,7 @@ var HaUpdateDevice = class extends HaBaseChildDevice {
|
|
|
844
844
|
});
|
|
845
845
|
}
|
|
846
846
|
registerUpdateCap() {
|
|
847
|
-
this.ctx.registerNativeCap(
|
|
847
|
+
this.ctx.registerNativeCap(require_ha_broker_source.updateCapability, {
|
|
848
848
|
getStatus: async () => {
|
|
849
849
|
return this.runtimeState.getCapState(UPDATE_CAP) ?? COLD_START$19;
|
|
850
850
|
},
|
|
@@ -928,7 +928,7 @@ var HaSwitchDevice = class extends HaBaseChildDevice {
|
|
|
928
928
|
});
|
|
929
929
|
}
|
|
930
930
|
registerSwitchCap() {
|
|
931
|
-
this.ctx.registerNativeCap(
|
|
931
|
+
this.ctx.registerNativeCap(require_ha_broker_source.switchCapability, {
|
|
932
932
|
getStatus: async () => {
|
|
933
933
|
return this.runtimeState.getCapState("switch") ?? {
|
|
934
934
|
on: false,
|
|
@@ -1045,7 +1045,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
|
|
|
1045
1045
|
const stored = this.sourceInfo.quantity;
|
|
1046
1046
|
if (stored !== void 0 && stored !== "device") return stored;
|
|
1047
1047
|
if (unitRaw === void 0) return "none";
|
|
1048
|
-
const learned =
|
|
1048
|
+
const learned = require_ha_broker_source.quantityFromUnit(unitRaw);
|
|
1049
1049
|
if (learned === void 0 || learned === "device") {
|
|
1050
1050
|
this.deviceLogger.warn("numeric reading refused", {
|
|
1051
1051
|
tags: { deviceId: this.id },
|
|
@@ -1071,7 +1071,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
|
|
|
1071
1071
|
value: "",
|
|
1072
1072
|
lastFetchedAt: 0
|
|
1073
1073
|
};
|
|
1074
|
-
this.ctx.registerNativeCap(
|
|
1074
|
+
this.ctx.registerNativeCap(require_ha_broker_source.enumSensorCapability, { getStatus: async () => {
|
|
1075
1075
|
return this.runtimeState.getCapState("enum-sensor") ?? COLD_START;
|
|
1076
1076
|
} });
|
|
1077
1077
|
this.runtimeState.setCapState("enum-sensor", COLD_START);
|
|
@@ -1083,7 +1083,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
|
|
|
1083
1083
|
temperature: 0,
|
|
1084
1084
|
lastFetchedAt: 0
|
|
1085
1085
|
};
|
|
1086
|
-
this.ctx.registerNativeCap(
|
|
1086
|
+
this.ctx.registerNativeCap(require_ha_broker_source.temperatureSensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
|
|
1087
1087
|
return;
|
|
1088
1088
|
}
|
|
1089
1089
|
case "humidity-sensor": {
|
|
@@ -1091,7 +1091,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
|
|
|
1091
1091
|
humidity: 0,
|
|
1092
1092
|
lastFetchedAt: 0
|
|
1093
1093
|
};
|
|
1094
|
-
this.ctx.registerNativeCap(
|
|
1094
|
+
this.ctx.registerNativeCap(require_ha_broker_source.humiditySensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
|
|
1095
1095
|
return;
|
|
1096
1096
|
}
|
|
1097
1097
|
case "ambient-light-sensor": {
|
|
@@ -1099,7 +1099,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
|
|
|
1099
1099
|
illuminance: 0,
|
|
1100
1100
|
lastFetchedAt: 0
|
|
1101
1101
|
};
|
|
1102
|
-
this.ctx.registerNativeCap(
|
|
1102
|
+
this.ctx.registerNativeCap(require_ha_broker_source.ambientLightSensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
|
|
1103
1103
|
return;
|
|
1104
1104
|
}
|
|
1105
1105
|
case "pressure-sensor": {
|
|
@@ -1107,7 +1107,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
|
|
|
1107
1107
|
pressure: 0,
|
|
1108
1108
|
lastFetchedAt: 0
|
|
1109
1109
|
};
|
|
1110
|
-
this.ctx.registerNativeCap(
|
|
1110
|
+
this.ctx.registerNativeCap(require_ha_broker_source.pressureSensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
|
|
1111
1111
|
return;
|
|
1112
1112
|
}
|
|
1113
1113
|
case "numeric-sensor": {
|
|
@@ -1115,7 +1115,7 @@ var HaNumericSensorDevice = class extends HaBaseChildDevice {
|
|
|
1115
1115
|
value: 0,
|
|
1116
1116
|
lastFetchedAt: 0
|
|
1117
1117
|
};
|
|
1118
|
-
this.ctx.registerNativeCap(
|
|
1118
|
+
this.ctx.registerNativeCap(require_ha_broker_source.numericSensorCapability, { getStatus: async () => this.readSlice(COLD_START) });
|
|
1119
1119
|
return;
|
|
1120
1120
|
}
|
|
1121
1121
|
}
|
|
@@ -1207,61 +1207,61 @@ var HaBinarySensorDevice = class extends HaBaseChildDevice {
|
|
|
1207
1207
|
registerCap(name) {
|
|
1208
1208
|
switch (name) {
|
|
1209
1209
|
case "contact":
|
|
1210
|
-
this.ctx.registerNativeCap(
|
|
1210
|
+
this.ctx.registerNativeCap(require_ha_broker_source.contactCapability, { getStatus: async () => this.readSlice({
|
|
1211
1211
|
entryOpen: false,
|
|
1212
1212
|
lastChangedAt: 0
|
|
1213
1213
|
}) });
|
|
1214
1214
|
return;
|
|
1215
1215
|
case "flood":
|
|
1216
|
-
this.ctx.registerNativeCap(
|
|
1216
|
+
this.ctx.registerNativeCap(require_ha_broker_source.floodCapability, { getStatus: async () => this.readSlice({
|
|
1217
1217
|
flooded: false,
|
|
1218
1218
|
lastChangedAt: 0
|
|
1219
1219
|
}) });
|
|
1220
1220
|
return;
|
|
1221
1221
|
case "smoke":
|
|
1222
|
-
this.ctx.registerNativeCap(
|
|
1222
|
+
this.ctx.registerNativeCap(require_ha_broker_source.smokeCapability, { getStatus: async () => this.readSlice({
|
|
1223
1223
|
detected: false,
|
|
1224
1224
|
lastChangedAt: 0
|
|
1225
1225
|
}) });
|
|
1226
1226
|
return;
|
|
1227
1227
|
case "carbon-monoxide":
|
|
1228
|
-
this.ctx.registerNativeCap(
|
|
1228
|
+
this.ctx.registerNativeCap(require_ha_broker_source.carbonMonoxideCapability, { getStatus: async () => this.readSlice({
|
|
1229
1229
|
detected: false,
|
|
1230
1230
|
lastChangedAt: 0
|
|
1231
1231
|
}) });
|
|
1232
1232
|
return;
|
|
1233
1233
|
case "gas":
|
|
1234
|
-
this.ctx.registerNativeCap(
|
|
1234
|
+
this.ctx.registerNativeCap(require_ha_broker_source.gasCapability, { getStatus: async () => this.readSlice({
|
|
1235
1235
|
detected: false,
|
|
1236
1236
|
lastChangedAt: 0
|
|
1237
1237
|
}) });
|
|
1238
1238
|
return;
|
|
1239
1239
|
case "tamper":
|
|
1240
|
-
this.ctx.registerNativeCap(
|
|
1240
|
+
this.ctx.registerNativeCap(require_ha_broker_source.tamperCapability, { getStatus: async () => this.readSlice({
|
|
1241
1241
|
tampered: false,
|
|
1242
1242
|
lastChangedAt: 0
|
|
1243
1243
|
}) });
|
|
1244
1244
|
return;
|
|
1245
1245
|
case "vibration":
|
|
1246
|
-
this.ctx.registerNativeCap(
|
|
1246
|
+
this.ctx.registerNativeCap(require_ha_broker_source.vibrationCapability, { getStatus: async () => this.readSlice({
|
|
1247
1247
|
detected: false,
|
|
1248
1248
|
lastChangedAt: 0
|
|
1249
1249
|
}) });
|
|
1250
1250
|
return;
|
|
1251
1251
|
case "connectivity":
|
|
1252
|
-
this.ctx.registerNativeCap(
|
|
1252
|
+
this.ctx.registerNativeCap(require_ha_broker_source.connectivityCapability, { getStatus: async () => this.readSlice({
|
|
1253
1253
|
connected: false,
|
|
1254
1254
|
lastChangedAt: 0
|
|
1255
1255
|
}) });
|
|
1256
1256
|
return;
|
|
1257
1257
|
case "binary":
|
|
1258
|
-
this.ctx.registerNativeCap(
|
|
1258
|
+
this.ctx.registerNativeCap(require_ha_broker_source.binaryCapability, { getStatus: async () => this.readSlice({
|
|
1259
1259
|
on: false,
|
|
1260
1260
|
lastChangedAt: 0
|
|
1261
1261
|
}) });
|
|
1262
1262
|
return;
|
|
1263
1263
|
case "motion":
|
|
1264
|
-
this.ctx.registerNativeCap(
|
|
1264
|
+
this.ctx.registerNativeCap(require_ha_broker_source.motionCapability, {
|
|
1265
1265
|
getStatus: async () => this.readSlice({
|
|
1266
1266
|
detected: false,
|
|
1267
1267
|
lastDetectedAt: null,
|
|
@@ -1434,7 +1434,7 @@ var HaLightDevice = class extends HaBaseChildDevice {
|
|
|
1434
1434
|
}
|
|
1435
1435
|
}
|
|
1436
1436
|
registerSwitchCap() {
|
|
1437
|
-
this.ctx.registerNativeCap(
|
|
1437
|
+
this.ctx.registerNativeCap(require_ha_broker_source.switchCapability, {
|
|
1438
1438
|
getStatus: async () => {
|
|
1439
1439
|
return this.runtimeState.getCapState("switch") ?? {
|
|
1440
1440
|
on: false,
|
|
@@ -1447,7 +1447,7 @@ var HaLightDevice = class extends HaBaseChildDevice {
|
|
|
1447
1447
|
});
|
|
1448
1448
|
}
|
|
1449
1449
|
registerBrightnessCap() {
|
|
1450
|
-
this.ctx.registerNativeCap(
|
|
1450
|
+
this.ctx.registerNativeCap(require_ha_broker_source.brightnessCapability, {
|
|
1451
1451
|
getStatus: async () => {
|
|
1452
1452
|
return this.runtimeState.getCapState("brightness") ?? {
|
|
1453
1453
|
level: 0,
|
|
@@ -1460,7 +1460,7 @@ var HaLightDevice = class extends HaBaseChildDevice {
|
|
|
1460
1460
|
});
|
|
1461
1461
|
}
|
|
1462
1462
|
registerColorCap() {
|
|
1463
|
-
this.ctx.registerNativeCap(
|
|
1463
|
+
this.ctx.registerNativeCap(require_ha_broker_source.colorCapability, {
|
|
1464
1464
|
getStatus: async () => {
|
|
1465
1465
|
return this.runtimeState.getCapState("color") ?? {
|
|
1466
1466
|
mode: "rgb",
|
|
@@ -1590,7 +1590,7 @@ var HaCoverDevice = class extends HaBaseChildDevice {
|
|
|
1590
1590
|
});
|
|
1591
1591
|
}
|
|
1592
1592
|
registerCoverCap() {
|
|
1593
|
-
this.ctx.registerNativeCap(
|
|
1593
|
+
this.ctx.registerNativeCap(require_ha_broker_source.coverCapability, {
|
|
1594
1594
|
getStatus: async () => {
|
|
1595
1595
|
return this.runtimeState.getCapState("cover") ?? COLD_START$18;
|
|
1596
1596
|
},
|
|
@@ -1661,7 +1661,7 @@ var HaValveDevice = class extends HaBaseChildDevice {
|
|
|
1661
1661
|
});
|
|
1662
1662
|
}
|
|
1663
1663
|
registerValveCap() {
|
|
1664
|
-
this.ctx.registerNativeCap(
|
|
1664
|
+
this.ctx.registerNativeCap(require_ha_broker_source.valveCapability, {
|
|
1665
1665
|
getStatus: async () => {
|
|
1666
1666
|
return this.runtimeState.getCapState("valve") ?? COLD_START$17;
|
|
1667
1667
|
},
|
|
@@ -1735,7 +1735,7 @@ var HaLockDevice = class extends HaBaseChildDevice {
|
|
|
1735
1735
|
});
|
|
1736
1736
|
}
|
|
1737
1737
|
registerLockCap() {
|
|
1738
|
-
this.ctx.registerNativeCap(
|
|
1738
|
+
this.ctx.registerNativeCap(require_ha_broker_source.lockControlCapability, {
|
|
1739
1739
|
getStatus: async () => {
|
|
1740
1740
|
return this.runtimeState.getCapState("lock-control") ?? COLD_START$16;
|
|
1741
1741
|
},
|
|
@@ -1819,7 +1819,7 @@ var HaClimateDevice = class extends HaBaseChildDevice {
|
|
|
1819
1819
|
this.swingHorizontalModes = readStringArray$4(state.attributes, "swing_horizontal_modes");
|
|
1820
1820
|
const unit = readStringAttr$6(state.attributes, "temperature_unit");
|
|
1821
1821
|
if (unit !== null) {
|
|
1822
|
-
const probe =
|
|
1822
|
+
const probe = require_ha_broker_source.ingestReading({
|
|
1823
1823
|
value: 0,
|
|
1824
1824
|
rawUnit: unit,
|
|
1825
1825
|
quantity: "temperature"
|
|
@@ -1836,7 +1836,7 @@ var HaClimateDevice = class extends HaBaseChildDevice {
|
|
|
1836
1836
|
this.runtimeState.setCapState("climate-control", climateSliceFromState(state));
|
|
1837
1837
|
}
|
|
1838
1838
|
registerClimateCap() {
|
|
1839
|
-
this.ctx.registerNativeCap(
|
|
1839
|
+
this.ctx.registerNativeCap(require_ha_broker_source.climateControlCapability, {
|
|
1840
1840
|
getStatus: async () => {
|
|
1841
1841
|
return this.runtimeState.getCapState("climate-control") ?? COLD_START$15;
|
|
1842
1842
|
},
|
|
@@ -1894,7 +1894,7 @@ function climateSliceFromState(state) {
|
|
|
1894
1894
|
const tempUnit = readStringAttr$6(attrs, "temperature_unit") ?? void 0;
|
|
1895
1895
|
const celsius = (raw) => {
|
|
1896
1896
|
if (raw === null) return null;
|
|
1897
|
-
const result =
|
|
1897
|
+
const result = require_ha_broker_source.ingestReading({
|
|
1898
1898
|
value: raw,
|
|
1899
1899
|
rawUnit: tempUnit,
|
|
1900
1900
|
quantity: "temperature"
|
|
@@ -2043,7 +2043,7 @@ var HaHumidifierDevice = class extends HaBaseChildDevice {
|
|
|
2043
2043
|
});
|
|
2044
2044
|
}
|
|
2045
2045
|
registerHumidifierCap() {
|
|
2046
|
-
this.ctx.registerNativeCap(
|
|
2046
|
+
this.ctx.registerNativeCap(require_ha_broker_source.humidifierCapability, {
|
|
2047
2047
|
getStatus: async () => {
|
|
2048
2048
|
return this.runtimeState.getCapState("humidifier") ?? COLD_START$14;
|
|
2049
2049
|
},
|
|
@@ -2123,7 +2123,7 @@ var HaWaterHeaterDevice = class extends HaBaseChildDevice {
|
|
|
2123
2123
|
});
|
|
2124
2124
|
}
|
|
2125
2125
|
registerWaterHeaterCap() {
|
|
2126
|
-
this.ctx.registerNativeCap(
|
|
2126
|
+
this.ctx.registerNativeCap(require_ha_broker_source.waterHeaterCapability, {
|
|
2127
2127
|
getStatus: async () => {
|
|
2128
2128
|
return this.runtimeState.getCapState("water-heater") ?? COLD_START$13;
|
|
2129
2129
|
},
|
|
@@ -2206,7 +2206,7 @@ var HaFanDevice = class extends HaBaseChildDevice {
|
|
|
2206
2206
|
this.runtimeState.setCapState("fan-control", slice);
|
|
2207
2207
|
}
|
|
2208
2208
|
registerSwitchCap() {
|
|
2209
|
-
this.ctx.registerNativeCap(
|
|
2209
|
+
this.ctx.registerNativeCap(require_ha_broker_source.switchCapability, {
|
|
2210
2210
|
getStatus: async () => {
|
|
2211
2211
|
return this.runtimeState.getCapState("switch") ?? {
|
|
2212
2212
|
on: false,
|
|
@@ -2219,7 +2219,7 @@ var HaFanDevice = class extends HaBaseChildDevice {
|
|
|
2219
2219
|
});
|
|
2220
2220
|
}
|
|
2221
2221
|
registerFanCap() {
|
|
2222
|
-
this.ctx.registerNativeCap(
|
|
2222
|
+
this.ctx.registerNativeCap(require_ha_broker_source.fanControlCapability, {
|
|
2223
2223
|
getStatus: async () => {
|
|
2224
2224
|
return this.runtimeState.getCapState("fan-control") ?? FAN_COLD_START;
|
|
2225
2225
|
},
|
|
@@ -2287,7 +2287,7 @@ var HaVacuumDevice = class extends HaBaseChildDevice {
|
|
|
2287
2287
|
this.registerVacuumCap();
|
|
2288
2288
|
this.registerRunningCap();
|
|
2289
2289
|
this.runtimeState.setCapState("vacuum-control", COLD_START$12);
|
|
2290
|
-
this.runtimeState.setCapState("running-state",
|
|
2290
|
+
this.runtimeState.setCapState("running-state", require_ha_broker_source.RUNNING_STATE_COLD);
|
|
2291
2291
|
}
|
|
2292
2292
|
handleStatePush(state) {
|
|
2293
2293
|
if (state.state === "unavailable" || state.state === "unknown") return;
|
|
@@ -2309,13 +2309,13 @@ var HaVacuumDevice = class extends HaBaseChildDevice {
|
|
|
2309
2309
|
});
|
|
2310
2310
|
const fetchedAt = Date.now();
|
|
2311
2311
|
const previous = this.runtimeState.getCapState("running-state");
|
|
2312
|
-
this.runtimeState.setCapState("running-state",
|
|
2312
|
+
this.runtimeState.setCapState("running-state", require_ha_broker_source.runningFromVacuumState(lifecycleState, previous, fetchedAt, lastChangedAt));
|
|
2313
2313
|
}
|
|
2314
2314
|
registerRunningCap() {
|
|
2315
|
-
this.ctx.registerNativeCap(
|
|
2315
|
+
this.ctx.registerNativeCap(require_ha_broker_source.runningStateCapability, { getStatus: async () => this.runtimeState.getCapState("running-state") ?? require_ha_broker_source.RUNNING_STATE_COLD });
|
|
2316
2316
|
}
|
|
2317
2317
|
registerVacuumCap() {
|
|
2318
|
-
this.ctx.registerNativeCap(
|
|
2318
|
+
this.ctx.registerNativeCap(require_ha_broker_source.vacuumControlCapability, {
|
|
2319
2319
|
getStatus: async () => {
|
|
2320
2320
|
return this.runtimeState.getCapState("vacuum-control") ?? COLD_START$12;
|
|
2321
2321
|
},
|
|
@@ -2387,7 +2387,7 @@ var HaLawnMowerDevice = class extends HaBaseChildDevice {
|
|
|
2387
2387
|
this.registerLawnMowerCap();
|
|
2388
2388
|
this.registerRunningCap();
|
|
2389
2389
|
this.runtimeState.setCapState("lawn-mower-control", COLD_START$11);
|
|
2390
|
-
this.runtimeState.setCapState("running-state",
|
|
2390
|
+
this.runtimeState.setCapState("running-state", require_ha_broker_source.RUNNING_STATE_COLD);
|
|
2391
2391
|
}
|
|
2392
2392
|
handleStatePush(state) {
|
|
2393
2393
|
if (state.state === "unavailable" || state.state === "unknown") return;
|
|
@@ -2405,13 +2405,13 @@ var HaLawnMowerDevice = class extends HaBaseChildDevice {
|
|
|
2405
2405
|
});
|
|
2406
2406
|
const fetchedAt = Date.now();
|
|
2407
2407
|
const previous = this.runtimeState.getCapState("running-state");
|
|
2408
|
-
this.runtimeState.setCapState("running-state",
|
|
2408
|
+
this.runtimeState.setCapState("running-state", require_ha_broker_source.runningFromLawnMower(activity, previous, fetchedAt, lastChangedAt));
|
|
2409
2409
|
}
|
|
2410
2410
|
registerRunningCap() {
|
|
2411
|
-
this.ctx.registerNativeCap(
|
|
2411
|
+
this.ctx.registerNativeCap(require_ha_broker_source.runningStateCapability, { getStatus: async () => this.runtimeState.getCapState("running-state") ?? require_ha_broker_source.RUNNING_STATE_COLD });
|
|
2412
2412
|
}
|
|
2413
2413
|
registerLawnMowerCap() {
|
|
2414
|
-
this.ctx.registerNativeCap(
|
|
2414
|
+
this.ctx.registerNativeCap(require_ha_broker_source.lawnMowerControlCapability, {
|
|
2415
2415
|
getStatus: async () => {
|
|
2416
2416
|
return this.runtimeState.getCapState("lawn-mower-control") ?? COLD_START$11;
|
|
2417
2417
|
},
|
|
@@ -2467,7 +2467,7 @@ var HaMediaPlayerDevice = class extends HaBaseChildDevice {
|
|
|
2467
2467
|
this.registerMediaPlayerCap();
|
|
2468
2468
|
this.registerRunningCap();
|
|
2469
2469
|
this.runtimeState.setCapState("media-player", COLD_START$10);
|
|
2470
|
-
this.runtimeState.setCapState("running-state",
|
|
2470
|
+
this.runtimeState.setCapState("running-state", require_ha_broker_source.RUNNING_STATE_COLD);
|
|
2471
2471
|
}
|
|
2472
2472
|
handleStatePush(state) {
|
|
2473
2473
|
if (state.state === "unavailable" || state.state === "unknown") return;
|
|
@@ -2492,13 +2492,13 @@ var HaMediaPlayerDevice = class extends HaBaseChildDevice {
|
|
|
2492
2492
|
this.runtimeState.setCapState("media-player", slice);
|
|
2493
2493
|
const fetchedAt = Date.now();
|
|
2494
2494
|
const previous = this.runtimeState.getCapState("running-state");
|
|
2495
|
-
this.runtimeState.setCapState("running-state",
|
|
2495
|
+
this.runtimeState.setCapState("running-state", require_ha_broker_source.runningFromMediaPlayer(playerState, previous, fetchedAt, lastChangedAt));
|
|
2496
2496
|
}
|
|
2497
2497
|
registerRunningCap() {
|
|
2498
|
-
this.ctx.registerNativeCap(
|
|
2498
|
+
this.ctx.registerNativeCap(require_ha_broker_source.runningStateCapability, { getStatus: async () => this.runtimeState.getCapState("running-state") ?? require_ha_broker_source.RUNNING_STATE_COLD });
|
|
2499
2499
|
}
|
|
2500
2500
|
registerMediaPlayerCap() {
|
|
2501
|
-
this.ctx.registerNativeCap(
|
|
2501
|
+
this.ctx.registerNativeCap(require_ha_broker_source.mediaPlayerCapability, {
|
|
2502
2502
|
getStatus: async () => {
|
|
2503
2503
|
return this.runtimeState.getCapState("media-player") ?? COLD_START$10;
|
|
2504
2504
|
},
|
|
@@ -2630,7 +2630,7 @@ var HaAlarmPanelDevice = class extends HaBaseChildDevice {
|
|
|
2630
2630
|
});
|
|
2631
2631
|
}
|
|
2632
2632
|
registerAlarmCap() {
|
|
2633
|
-
this.ctx.registerNativeCap(
|
|
2633
|
+
this.ctx.registerNativeCap(require_ha_broker_source.alarmPanelCapability, {
|
|
2634
2634
|
getStatus: async () => {
|
|
2635
2635
|
return this.runtimeState.getCapState("alarm-panel") ?? COLD_START$9;
|
|
2636
2636
|
},
|
|
@@ -2745,7 +2745,7 @@ var HaPresenceDevice = class extends HaBaseChildDevice {
|
|
|
2745
2745
|
});
|
|
2746
2746
|
}
|
|
2747
2747
|
registerBatteryCap() {
|
|
2748
|
-
this.ctx.registerNativeCap(
|
|
2748
|
+
this.ctx.registerNativeCap(require_ha_broker_source.batteryCapability, {
|
|
2749
2749
|
getStatus: async () => this.runtimeState.getCapState("battery") ?? COLD_BATTERY,
|
|
2750
2750
|
wakeForStream: async () => ({
|
|
2751
2751
|
awoke: true,
|
|
@@ -2754,7 +2754,7 @@ var HaPresenceDevice = class extends HaBaseChildDevice {
|
|
|
2754
2754
|
});
|
|
2755
2755
|
}
|
|
2756
2756
|
registerPresenceCap() {
|
|
2757
|
-
this.ctx.registerNativeCap(
|
|
2757
|
+
this.ctx.registerNativeCap(require_ha_broker_source.presenceCapability, { getStatus: async () => {
|
|
2758
2758
|
return this.runtimeState.getCapState("presence") ?? COLD_START$8;
|
|
2759
2759
|
} });
|
|
2760
2760
|
}
|
|
@@ -2822,7 +2822,7 @@ var HaControlDevice = class extends HaBaseChildDevice {
|
|
|
2822
2822
|
if (slice !== null) this.runtimeState.setCapState("control", slice);
|
|
2823
2823
|
}
|
|
2824
2824
|
registerControlCap() {
|
|
2825
|
-
this.ctx.registerNativeCap(
|
|
2825
|
+
this.ctx.registerNativeCap(require_ha_broker_source.controlCapability, {
|
|
2826
2826
|
getStatus: async () => {
|
|
2827
2827
|
return this.runtimeState.getCapState("control") ?? {
|
|
2828
2828
|
kind: this.kind,
|
|
@@ -2861,10 +2861,10 @@ var HaControlDevice = class extends HaBaseChildDevice {
|
|
|
2861
2861
|
/** Base-unit value → the unit the upstream entity still speaks. */
|
|
2862
2862
|
toUpstream(value) {
|
|
2863
2863
|
const quantity = this.sourceInfo.quantity;
|
|
2864
|
-
const base = quantity === void 0 ? void 0 :
|
|
2864
|
+
const base = quantity === void 0 ? void 0 : require_ha_broker_source.baseUnitOf(quantity);
|
|
2865
2865
|
const upstream = this.upstreamUnit;
|
|
2866
2866
|
if (base === void 0 || upstream === void 0 || upstream === base) return value;
|
|
2867
|
-
const converted =
|
|
2867
|
+
const converted = require_ha_broker_source.tryConvertUnit(value, base, upstream);
|
|
2868
2868
|
if (converted !== void 0) return converted;
|
|
2869
2869
|
this.deviceLogger.warn("numeric reading refused", {
|
|
2870
2870
|
tags: { deviceId: this.id },
|
|
@@ -2965,7 +2965,7 @@ function decodeNumeric(state, lastChangedAt, decode) {
|
|
|
2965
2965
|
if (!Number.isFinite(v)) return null;
|
|
2966
2966
|
const rawUnit = state.attributes["unit_of_measurement"];
|
|
2967
2967
|
const unit = typeof rawUnit === "string" && rawUnit.length > 0 ? rawUnit : void 0;
|
|
2968
|
-
const incoming = unit === void 0 ? void 0 :
|
|
2968
|
+
const incoming = unit === void 0 ? void 0 : require_ha_broker_source.quantityFromUnit(unit);
|
|
2969
2969
|
if (unit !== void 0 && (incoming === void 0 || incoming === "device")) {
|
|
2970
2970
|
decode.logger.warn("numeric reading refused", {
|
|
2971
2971
|
tags: { deviceId: decode.deviceId },
|
|
@@ -2992,7 +2992,7 @@ function decodeNumeric(state, lastChangedAt, decode) {
|
|
|
2992
2992
|
}
|
|
2993
2993
|
const value = takeReading(decode.logger, decode.deviceId, v, unit, quantity);
|
|
2994
2994
|
if (value === null) return null;
|
|
2995
|
-
decode.note(quantity, unit === void 0 ? void 0 :
|
|
2995
|
+
decode.note(quantity, unit === void 0 ? void 0 : require_ha_broker_source.normalizeUnit(unit));
|
|
2996
2996
|
const rawMin = state.attributes["min"];
|
|
2997
2997
|
const rawMax = state.attributes["max"];
|
|
2998
2998
|
const rawStep = state.attributes["step"];
|
|
@@ -3012,10 +3012,10 @@ function decodeNumeric(state, lastChangedAt, decode) {
|
|
|
3012
3012
|
/** A step is a difference: °F's offset must not move it. */
|
|
3013
3013
|
function convertStep(step, unit, quantity) {
|
|
3014
3014
|
if (step === void 0) return void 0;
|
|
3015
|
-
const base =
|
|
3016
|
-
const from = unit === void 0 ? void 0 :
|
|
3015
|
+
const base = require_ha_broker_source.baseUnitOf(quantity);
|
|
3016
|
+
const from = unit === void 0 ? void 0 : require_ha_broker_source.normalizeUnit(unit);
|
|
3017
3017
|
if (base === void 0 || from === void 0 || from === base) return step;
|
|
3018
|
-
return
|
|
3018
|
+
return require_ha_broker_source.tryConvertDelta(step, from, base);
|
|
3019
3019
|
}
|
|
3020
3020
|
//#endregion
|
|
3021
3021
|
//#region src/devices/ha-script-device.ts
|
|
@@ -3058,7 +3058,7 @@ var HaScriptDevice = class extends HaBaseChildDevice {
|
|
|
3058
3058
|
});
|
|
3059
3059
|
}
|
|
3060
3060
|
registerScriptCap() {
|
|
3061
|
-
this.ctx.registerNativeCap(
|
|
3061
|
+
this.ctx.registerNativeCap(require_ha_broker_source.scriptRunnerCapability, {
|
|
3062
3062
|
getStatus: async () => {
|
|
3063
3063
|
return this.runtimeState.getCapState("script-runner") ?? COLD_START$7;
|
|
3064
3064
|
},
|
|
@@ -3117,7 +3117,7 @@ var HaAutomationDevice = class extends HaBaseChildDevice {
|
|
|
3117
3117
|
});
|
|
3118
3118
|
}
|
|
3119
3119
|
registerAutomationCap() {
|
|
3120
|
-
this.ctx.registerNativeCap(
|
|
3120
|
+
this.ctx.registerNativeCap(require_ha_broker_source.automationControlCapability, {
|
|
3121
3121
|
getStatus: async () => {
|
|
3122
3122
|
return this.runtimeState.getCapState("automation-control") ?? COLD_START$6;
|
|
3123
3123
|
},
|
|
@@ -3176,7 +3176,7 @@ var HaNotifierDevice = class extends HaBaseChildDevice {
|
|
|
3176
3176
|
handleStatePush(_state) {}
|
|
3177
3177
|
registerNotifierCap() {
|
|
3178
3178
|
const serviceName = this.entityId.split(".")[1] ?? "";
|
|
3179
|
-
this.ctx.registerNativeCap(
|
|
3179
|
+
this.ctx.registerNativeCap(require_ha_broker_source.notifierCapability, {
|
|
3180
3180
|
getStatus: async () => {
|
|
3181
3181
|
return this.runtimeState.getCapState("notifier") ?? COLD_START$5;
|
|
3182
3182
|
},
|
|
@@ -3272,7 +3272,7 @@ var HaPowerMeterDevice = class extends HaBaseChildDevice {
|
|
|
3272
3272
|
if (update !== null) this.runtimeState.setCapState("power-meter", update);
|
|
3273
3273
|
}
|
|
3274
3274
|
registerPowerMeterCap() {
|
|
3275
|
-
this.ctx.registerNativeCap(
|
|
3275
|
+
this.ctx.registerNativeCap(require_ha_broker_source.powerMeterCapability, { getStatus: async () => {
|
|
3276
3276
|
return this.runtimeState.getCapState("power-meter") ?? COLD_START$4;
|
|
3277
3277
|
} });
|
|
3278
3278
|
}
|
|
@@ -3351,7 +3351,7 @@ var HaAirQualityDevice = class extends HaBaseChildDevice {
|
|
|
3351
3351
|
if (update !== null) this.runtimeState.setCapState("air-quality-sensor", update);
|
|
3352
3352
|
}
|
|
3353
3353
|
registerCap() {
|
|
3354
|
-
this.ctx.registerNativeCap(
|
|
3354
|
+
this.ctx.registerNativeCap(require_ha_broker_source.airQualitySensorCapability, { getStatus: async () => {
|
|
3355
3355
|
return this.runtimeState.getCapState("air-quality-sensor") ?? COLD_START$3;
|
|
3356
3356
|
} });
|
|
3357
3357
|
}
|
|
@@ -3426,7 +3426,7 @@ var HaEnumSensorDevice = class extends HaBaseChildDevice {
|
|
|
3426
3426
|
constructor(ctx) {
|
|
3427
3427
|
const persisted = ctx.persistedConfig ?? {};
|
|
3428
3428
|
super(ctx, persisted.role !== void 0 ? { role: persisted.role } : {});
|
|
3429
|
-
const parsedFormat =
|
|
3429
|
+
const parsedFormat = require_ha_broker_source.EnumSensorDateTimeFormatSchema.safeParse(persisted.dateTimeFormat);
|
|
3430
3430
|
this.dateTimeFormat = parsedFormat.success ? parsedFormat.data : void 0;
|
|
3431
3431
|
if (this.dateTimeFormat !== void 0) this.updateSourceInfo({ dateTimeShape: this.dateTimeFormat });
|
|
3432
3432
|
this.registerCap();
|
|
@@ -3448,7 +3448,7 @@ var HaEnumSensorDevice = class extends HaBaseChildDevice {
|
|
|
3448
3448
|
});
|
|
3449
3449
|
}
|
|
3450
3450
|
registerCap() {
|
|
3451
|
-
this.ctx.registerNativeCap(
|
|
3451
|
+
this.ctx.registerNativeCap(require_ha_broker_source.enumSensorCapability, { getStatus: async () => {
|
|
3452
3452
|
return this.runtimeState.getCapState("enum-sensor") ?? this.coldStart();
|
|
3453
3453
|
} });
|
|
3454
3454
|
}
|
|
@@ -3547,7 +3547,7 @@ var HaEventEmitterDevice = class extends HaBaseChildDevice {
|
|
|
3547
3547
|
timestamp: Date.now(),
|
|
3548
3548
|
seq: ++this.#seq
|
|
3549
3549
|
};
|
|
3550
|
-
this.ctx.eventBus.emit(
|
|
3550
|
+
this.ctx.eventBus.emit(require_ha_broker_source.createEvent(require_ha_broker_source.EventCategory.EventEmitted, {
|
|
3551
3551
|
type: "device",
|
|
3552
3552
|
id: this.stableId,
|
|
3553
3553
|
deviceId: this.id,
|
|
@@ -3561,7 +3561,7 @@ var HaEventEmitterDevice = class extends HaBaseChildDevice {
|
|
|
3561
3561
|
this.runtimeState.setCapState("event-emitter", slice);
|
|
3562
3562
|
}
|
|
3563
3563
|
registerEventEmitterCap() {
|
|
3564
|
-
this.ctx.registerNativeCap(
|
|
3564
|
+
this.ctx.registerNativeCap(require_ha_broker_source.eventEmitterCapability, { getStatus: async () => this.readSlice() });
|
|
3565
3565
|
}
|
|
3566
3566
|
readSlice() {
|
|
3567
3567
|
return this.runtimeState.getCapState("event-emitter") ?? {
|
|
@@ -3644,7 +3644,7 @@ var HaWeatherDevice = class extends HaBaseChildDevice {
|
|
|
3644
3644
|
this.runtimeState.setCapState("weather", slice);
|
|
3645
3645
|
}
|
|
3646
3646
|
registerWeatherCap() {
|
|
3647
|
-
this.ctx.registerNativeCap(
|
|
3647
|
+
this.ctx.registerNativeCap(require_ha_broker_source.weatherCapability, { getStatus: async () => {
|
|
3648
3648
|
return this.runtimeState.getCapState("weather") ?? COLD_START$1;
|
|
3649
3649
|
} });
|
|
3650
3650
|
}
|
|
@@ -3742,7 +3742,7 @@ var HaImageDevice = class extends HaBaseChildDevice {
|
|
|
3742
3742
|
this.deviceLogger.warn("ha-image: failed to build absolute image url", { meta: {
|
|
3743
3743
|
entityId: this.entityId,
|
|
3744
3744
|
brokerId: this.brokerId,
|
|
3745
|
-
error:
|
|
3745
|
+
error: require_ha_broker_source.errMsg(err)
|
|
3746
3746
|
} });
|
|
3747
3747
|
url = null;
|
|
3748
3748
|
}
|
|
@@ -3774,7 +3774,7 @@ var HaImageDevice = class extends HaBaseChildDevice {
|
|
|
3774
3774
|
return typeof raw === "string" && raw.length > 0 ? raw : null;
|
|
3775
3775
|
}
|
|
3776
3776
|
registerImageCap() {
|
|
3777
|
-
this.ctx.registerNativeCap(
|
|
3777
|
+
this.ctx.registerNativeCap(require_ha_broker_source.imageCapability, { getStatus: async () => {
|
|
3778
3778
|
return this.runtimeState.getCapState("image") ?? COLD_START;
|
|
3779
3779
|
} });
|
|
3780
3780
|
}
|
|
@@ -3868,28 +3868,28 @@ function pickHaChildClass(capabilities) {
|
|
|
3868
3868
|
//#region src/ha-container-reconcile.ts
|
|
3869
3869
|
/** Validates a persisted Container `entities[]` blob (mirrors `haEntitySchema`
|
|
3870
3870
|
* in ha-container-device.ts). Returns `[]` on absent/invalid input. */
|
|
3871
|
-
var containerEntitySchema =
|
|
3872
|
-
entityId:
|
|
3873
|
-
deviceType:
|
|
3874
|
-
capabilities:
|
|
3875
|
-
role:
|
|
3876
|
-
unitOfMeasurement:
|
|
3877
|
-
deviceClass:
|
|
3878
|
-
options:
|
|
3879
|
-
features:
|
|
3880
|
-
name:
|
|
3881
|
-
dateTimeFormat:
|
|
3882
|
-
entityCategory:
|
|
3883
|
-
meterEntities:
|
|
3884
|
-
power:
|
|
3885
|
-
energy:
|
|
3886
|
-
voltage:
|
|
3887
|
-
current:
|
|
3871
|
+
var containerEntitySchema = require_ha_broker_source.object({
|
|
3872
|
+
entityId: require_ha_broker_source.string(),
|
|
3873
|
+
deviceType: require_ha_broker_source._enum(require_ha_broker_source.DeviceType),
|
|
3874
|
+
capabilities: require_ha_broker_source.array(require_ha_broker_source.string()),
|
|
3875
|
+
role: require_ha_broker_source.string().optional(),
|
|
3876
|
+
unitOfMeasurement: require_ha_broker_source.string().optional(),
|
|
3877
|
+
deviceClass: require_ha_broker_source.string().optional(),
|
|
3878
|
+
options: require_ha_broker_source.array(require_ha_broker_source.string()).optional(),
|
|
3879
|
+
features: require_ha_broker_source.array(require_ha_broker_source.string()).optional(),
|
|
3880
|
+
name: require_ha_broker_source.string().optional(),
|
|
3881
|
+
dateTimeFormat: require_ha_broker_source.EnumSensorDateTimeFormatSchema.optional(),
|
|
3882
|
+
entityCategory: require_ha_broker_source._enum(["config", "diagnostic"]).optional(),
|
|
3883
|
+
meterEntities: require_ha_broker_source.object({
|
|
3884
|
+
power: require_ha_broker_source.string().optional(),
|
|
3885
|
+
energy: require_ha_broker_source.string().optional(),
|
|
3886
|
+
voltage: require_ha_broker_source.string().optional(),
|
|
3887
|
+
current: require_ha_broker_source.string().optional()
|
|
3888
3888
|
}).optional(),
|
|
3889
|
-
foldedInto:
|
|
3889
|
+
foldedInto: require_ha_broker_source.string().optional()
|
|
3890
3890
|
});
|
|
3891
3891
|
function parseContainerEntities(raw) {
|
|
3892
|
-
const result =
|
|
3892
|
+
const result = require_ha_broker_source.array(containerEntitySchema).safeParse(raw);
|
|
3893
3893
|
return result.success ? result.data : [];
|
|
3894
3894
|
}
|
|
3895
3895
|
/**
|
|
@@ -4043,45 +4043,45 @@ function deriveChildLayout(entities) {
|
|
|
4043
4043
|
}
|
|
4044
4044
|
//#endregion
|
|
4045
4045
|
//#region src/devices/ha-container-device.ts
|
|
4046
|
-
var haEntitySchema =
|
|
4047
|
-
entityId:
|
|
4048
|
-
deviceType:
|
|
4049
|
-
capabilities:
|
|
4050
|
-
role:
|
|
4051
|
-
unitOfMeasurement:
|
|
4052
|
-
deviceClass:
|
|
4046
|
+
var haEntitySchema = require_ha_broker_source.object({
|
|
4047
|
+
entityId: require_ha_broker_source.string(),
|
|
4048
|
+
deviceType: require_ha_broker_source._enum(require_ha_broker_source.DeviceType),
|
|
4049
|
+
capabilities: require_ha_broker_source.array(require_ha_broker_source.string()),
|
|
4050
|
+
role: require_ha_broker_source.string().optional(),
|
|
4051
|
+
unitOfMeasurement: require_ha_broker_source.string().optional(),
|
|
4052
|
+
deviceClass: require_ha_broker_source.string().optional(),
|
|
4053
4053
|
/** HA `options` attribute — present on select / input_select entities.
|
|
4054
4054
|
* Persisted at adoption so the control slice is seeded immediately. */
|
|
4055
|
-
options:
|
|
4055
|
+
options: require_ha_broker_source.array(require_ha_broker_source.string()).optional(),
|
|
4056
4056
|
/** Mapping-derived DeviceFeature flags (e.g. `lock-open`) — surfaced on the
|
|
4057
4057
|
* child's `device.features` so the UI gates feature affordances. */
|
|
4058
|
-
features:
|
|
4058
|
+
features: require_ha_broker_source.array(require_ha_broker_source.string()).optional(),
|
|
4059
4059
|
/** HA friendly_name — persisted so the child device name survives
|
|
4060
4060
|
* a reboot without a discovery round-trip. Falls back to entityId. */
|
|
4061
|
-
name:
|
|
4061
|
+
name: require_ha_broker_source.string().optional(),
|
|
4062
4062
|
/** Locale-render shape for a `DateTimeSensor`-role enum sensor
|
|
4063
4063
|
* (`device_class=timestamp` → `'datetime'`, `date` → `'date'`). Seeded into
|
|
4064
4064
|
* the enum-sensor cap slice by the child so the UI renders the ISO `value`. */
|
|
4065
|
-
dateTimeFormat:
|
|
4065
|
+
dateTimeFormat: require_ha_broker_source.EnumSensorDateTimeFormatSchema.optional(),
|
|
4066
4066
|
/** HA `entity_category` — `config` / `diagnostic` / absent (a normal
|
|
4067
4067
|
* control). Drives the accordion section the child renders in. */
|
|
4068
|
-
entityCategory:
|
|
4068
|
+
entityCategory: require_ha_broker_source._enum(["config", "diagnostic"]).optional(),
|
|
4069
4069
|
/** Sibling meter sensors this entity reads as its own power-meter (D951). */
|
|
4070
|
-
meterEntities:
|
|
4071
|
-
power:
|
|
4072
|
-
energy:
|
|
4073
|
-
voltage:
|
|
4074
|
-
current:
|
|
4070
|
+
meterEntities: require_ha_broker_source.object({
|
|
4071
|
+
power: require_ha_broker_source.string().optional(),
|
|
4072
|
+
energy: require_ha_broker_source.string().optional(),
|
|
4073
|
+
voltage: require_ha_broker_source.string().optional(),
|
|
4074
|
+
current: require_ha_broker_source.string().optional()
|
|
4075
4075
|
}).optional(),
|
|
4076
4076
|
/** Set on a meter sensor folded into another entity: sectioned as Diagnostic. */
|
|
4077
|
-
foldedInto:
|
|
4077
|
+
foldedInto: require_ha_broker_source.string().optional()
|
|
4078
4078
|
});
|
|
4079
|
-
var haContainerSchema =
|
|
4080
|
-
system:
|
|
4081
|
-
brokerId:
|
|
4082
|
-
haDeviceId:
|
|
4083
|
-
integrationId:
|
|
4084
|
-
entities:
|
|
4079
|
+
var haContainerSchema = require_ha_broker_source.object({
|
|
4080
|
+
system: require_ha_broker_source.literal("homeassistant"),
|
|
4081
|
+
brokerId: require_ha_broker_source.string(),
|
|
4082
|
+
haDeviceId: require_ha_broker_source.string(),
|
|
4083
|
+
integrationId: require_ha_broker_source.string().optional(),
|
|
4084
|
+
entities: require_ha_broker_source.array(haEntitySchema).default([])
|
|
4085
4085
|
});
|
|
4086
4086
|
/**
|
|
4087
4087
|
* A container entity is a battery source when the HA domain mapping
|
|
@@ -4091,7 +4091,7 @@ var haContainerSchema = require_dist.object({
|
|
|
4091
4091
|
* device_class is the original HA attribute that drove it.
|
|
4092
4092
|
*/
|
|
4093
4093
|
function isBatteryEntity(entity) {
|
|
4094
|
-
return entity.role ===
|
|
4094
|
+
return entity.role === require_ha_broker_source.DeviceRole.BatterySensor || entity.deviceClass === "battery";
|
|
4095
4095
|
}
|
|
4096
4096
|
/**
|
|
4097
4097
|
* A battery entity is BINARY when HA exposes it as a `binary_sensor`
|
|
@@ -4183,7 +4183,7 @@ function batteryEntityId(entities) {
|
|
|
4183
4183
|
* persist initial config, build context, construct via factory, then
|
|
4184
4184
|
* run the child's own probe + accessory + activate phases.
|
|
4185
4185
|
*/
|
|
4186
|
-
var HaContainerDevice = class HaContainerDevice extends
|
|
4186
|
+
var HaContainerDevice = class HaContainerDevice extends require_ha_broker_source.BaseDevice {
|
|
4187
4187
|
features;
|
|
4188
4188
|
brokerId;
|
|
4189
4189
|
integrationId;
|
|
@@ -4204,10 +4204,10 @@ var HaContainerDevice = class HaContainerDevice extends require_dist.BaseDevice
|
|
|
4204
4204
|
constructor(ctx) {
|
|
4205
4205
|
const cfg = haContainerSchema.parse(ctx.persistedConfig ?? {});
|
|
4206
4206
|
const batteryEntity = selectBatteryEntity(cfg.entities);
|
|
4207
|
-
super(ctx, haContainerSchema, { type:
|
|
4207
|
+
super(ctx, haContainerSchema, { type: require_ha_broker_source.DeviceType.Container });
|
|
4208
4208
|
this.brokerId = cfg.brokerId;
|
|
4209
4209
|
this.integrationId = cfg.integrationId;
|
|
4210
|
-
this.features = batteryEntity !== null ? [
|
|
4210
|
+
this.features = batteryEntity !== null ? [require_ha_broker_source.DeviceFeature.Resyncable, require_ha_broker_source.DeviceFeature.BatteryOperated] : [require_ha_broker_source.DeviceFeature.Resyncable];
|
|
4211
4211
|
this.entityIds = new Set(cfg.entities.map((e) => e.entityId));
|
|
4212
4212
|
this.online = false;
|
|
4213
4213
|
this.batteryEntityId = batteryEntityId(cfg.entities);
|
|
@@ -4218,7 +4218,7 @@ var HaContainerDevice = class HaContainerDevice extends require_dist.BaseDevice
|
|
|
4218
4218
|
sleeping: false,
|
|
4219
4219
|
lastUpdated: 0
|
|
4220
4220
|
};
|
|
4221
|
-
this.ctx.registerNativeCap(
|
|
4221
|
+
this.ctx.registerNativeCap(require_ha_broker_source.batteryCapability, {
|
|
4222
4222
|
getStatus: async () => this.runtimeState.getCapState("battery") ?? COLD,
|
|
4223
4223
|
wakeForStream: async () => ({
|
|
4224
4224
|
awoke: true,
|
|
@@ -4293,7 +4293,7 @@ var HaContainerDevice = class HaContainerDevice extends require_dist.BaseDevice
|
|
|
4293
4293
|
} catch (err) {
|
|
4294
4294
|
this.ctx.logger.warn("ha-container failed to subscribe entities for availability", { meta: {
|
|
4295
4295
|
brokerId: this.brokerId,
|
|
4296
|
-
error:
|
|
4296
|
+
error: require_ha_broker_source.errMsg(err)
|
|
4297
4297
|
} });
|
|
4298
4298
|
}
|
|
4299
4299
|
}
|
|
@@ -4334,7 +4334,7 @@ var HaContainerDevice = class HaContainerDevice extends require_dist.BaseDevice
|
|
|
4334
4334
|
} catch (err) {
|
|
4335
4335
|
this.ctx.logger.warn("ha-container failed to persist childLayout", { meta: {
|
|
4336
4336
|
haDeviceId: this.config.values.haDeviceId,
|
|
4337
|
-
error:
|
|
4337
|
+
error: require_ha_broker_source.errMsg(err)
|
|
4338
4338
|
} });
|
|
4339
4339
|
}
|
|
4340
4340
|
}
|
|
@@ -4413,10 +4413,10 @@ var HaContainerDevice = class HaContainerDevice extends require_dist.BaseDevice
|
|
|
4413
4413
|
* entity-backed (no `entityId`), so it does NOT extend the HA child base
|
|
4414
4414
|
* device — it is a thin standalone `BaseDevice` subclass.
|
|
4415
4415
|
*/
|
|
4416
|
-
var haEventBusDeviceSchema =
|
|
4417
|
-
system:
|
|
4418
|
-
brokerId:
|
|
4419
|
-
kind:
|
|
4416
|
+
var haEventBusDeviceSchema = require_ha_broker_source.object({
|
|
4417
|
+
system: require_ha_broker_source.literal("homeassistant"),
|
|
4418
|
+
brokerId: require_ha_broker_source.string(),
|
|
4419
|
+
kind: require_ha_broker_source.literal("event-bus")
|
|
4420
4420
|
});
|
|
4421
4421
|
/**
|
|
4422
4422
|
* Case 2 — generic per-broker HA bus-event aggregator.
|
|
@@ -4437,7 +4437,7 @@ var haEventBusDeviceSchema = require_dist.object({
|
|
|
4437
4437
|
* directly via {@link handleBusEvent} (the integration manager subscribes
|
|
4438
4438
|
* to the curated bus event types and threads each fire through the addon).
|
|
4439
4439
|
*/
|
|
4440
|
-
var HaEventBusDevice = class extends
|
|
4440
|
+
var HaEventBusDevice = class extends require_ha_broker_source.BaseDevice {
|
|
4441
4441
|
features = [];
|
|
4442
4442
|
/** Monotonic sequence — two identical events still produce distinct slice
|
|
4443
4443
|
* writes / bus emissions. */
|
|
@@ -4476,7 +4476,7 @@ var HaEventBusDevice = class extends require_dist.BaseDevice {
|
|
|
4476
4476
|
timestamp: Date.now(),
|
|
4477
4477
|
seq: ++this.#seq
|
|
4478
4478
|
};
|
|
4479
|
-
this.ctx.eventBus.emit(
|
|
4479
|
+
this.ctx.eventBus.emit(require_ha_broker_source.createEvent(require_ha_broker_source.EventCategory.EventEmitted, {
|
|
4480
4480
|
type: "device",
|
|
4481
4481
|
id: this.stableId,
|
|
4482
4482
|
deviceId: this.id,
|
|
@@ -4490,7 +4490,7 @@ var HaEventBusDevice = class extends require_dist.BaseDevice {
|
|
|
4490
4490
|
this.runtimeState.setCapState("event-emitter", slice);
|
|
4491
4491
|
}
|
|
4492
4492
|
registerEventEmitterCap() {
|
|
4493
|
-
this.ctx.registerNativeCap(
|
|
4493
|
+
this.ctx.registerNativeCap(require_ha_broker_source.eventEmitterCapability, { getStatus: async () => this.readSlice() });
|
|
4494
4494
|
}
|
|
4495
4495
|
readSlice() {
|
|
4496
4496
|
return this.runtimeState.getCapState("event-emitter") ?? {
|
|
@@ -4525,7 +4525,7 @@ async function cascadeRemoveDevicesForBroker(input) {
|
|
|
4525
4525
|
tags: { deviceId: d.id },
|
|
4526
4526
|
meta: {
|
|
4527
4527
|
brokerId,
|
|
4528
|
-
error:
|
|
4528
|
+
error: require_ha_broker_source.errMsg(err)
|
|
4529
4529
|
}
|
|
4530
4530
|
});
|
|
4531
4531
|
}
|
|
@@ -5431,7 +5431,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5431
5431
|
} catch (err) {
|
|
5432
5432
|
this.opts.logger.warn("ha-broker onConnected handler threw", { meta: {
|
|
5433
5433
|
brokerId: this.opts.id,
|
|
5434
|
-
error:
|
|
5434
|
+
error: require_ha_broker_source.errMsg(err)
|
|
5435
5435
|
} });
|
|
5436
5436
|
}
|
|
5437
5437
|
},
|
|
@@ -5446,12 +5446,12 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5446
5446
|
} catch (err) {
|
|
5447
5447
|
this.opts.logger.warn("ha-broker onDisconnected handler threw", { meta: {
|
|
5448
5448
|
brokerId: this.opts.id,
|
|
5449
|
-
error:
|
|
5449
|
+
error: require_ha_broker_source.errMsg(err)
|
|
5450
5450
|
} });
|
|
5451
5451
|
}
|
|
5452
5452
|
},
|
|
5453
5453
|
onReconnectError: (err, nextDelayMs) => {
|
|
5454
|
-
this.lastError =
|
|
5454
|
+
this.lastError = require_ha_broker_source.errMsg(err);
|
|
5455
5455
|
this.opts.logger.warn("ha-broker reconnect attempt failed", { meta: {
|
|
5456
5456
|
brokerId: this.opts.id,
|
|
5457
5457
|
error: this.lastError,
|
|
@@ -5628,7 +5628,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5628
5628
|
this.opts.logger.warn("ha-broker bus-event subscribe failed", { meta: {
|
|
5629
5629
|
brokerId: this.opts.id,
|
|
5630
5630
|
eventType,
|
|
5631
|
-
error:
|
|
5631
|
+
error: require_ha_broker_source.errMsg(err)
|
|
5632
5632
|
} });
|
|
5633
5633
|
}
|
|
5634
5634
|
}
|
|
@@ -5664,7 +5664,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5664
5664
|
return false;
|
|
5665
5665
|
}
|
|
5666
5666
|
emitBrokerMessage(subscriptionId, entityId, state) {
|
|
5667
|
-
this.opts.eventBus.emit(
|
|
5667
|
+
this.opts.eventBus.emit(require_ha_broker_source.createEvent("broker.message", {
|
|
5668
5668
|
type: "addon",
|
|
5669
5669
|
id: this.opts.id
|
|
5670
5670
|
}, {
|
|
@@ -5686,7 +5686,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5686
5686
|
} catch (err) {
|
|
5687
5687
|
this.opts.logger.debug("ha get_config probe failed", { meta: {
|
|
5688
5688
|
brokerId: this.opts.id,
|
|
5689
|
-
error:
|
|
5689
|
+
error: require_ha_broker_source.errMsg(err)
|
|
5690
5690
|
} });
|
|
5691
5691
|
}
|
|
5692
5692
|
}
|
|
@@ -5694,7 +5694,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5694
5694
|
if (this.status === next) return;
|
|
5695
5695
|
this.status = next;
|
|
5696
5696
|
this.lastCheckedAt = Date.now();
|
|
5697
|
-
this.opts.eventBus.emit(
|
|
5697
|
+
this.opts.eventBus.emit(require_ha_broker_source.createEvent("broker.status-changed", {
|
|
5698
5698
|
type: "addon",
|
|
5699
5699
|
id: this.opts.id
|
|
5700
5700
|
}, {
|
|
@@ -5715,7 +5715,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5715
5715
|
this.lastError = "Home Assistant host / URL is required";
|
|
5716
5716
|
this.setStatus("unreachable");
|
|
5717
5717
|
} else {
|
|
5718
|
-
this.lastError =
|
|
5718
|
+
this.lastError = require_ha_broker_source.errMsg(err);
|
|
5719
5719
|
this.setStatus("error");
|
|
5720
5720
|
}
|
|
5721
5721
|
}
|
|
@@ -5736,17 +5736,17 @@ var TEST_HANDSHAKE_TIMEOUT_MS = 8e3;
|
|
|
5736
5736
|
* `dataDir` being protected by filesystem permissions. (MQTT broker
|
|
5737
5737
|
* encrypts at rest; HA broker does not yet — TODO for hardening.)
|
|
5738
5738
|
*/
|
|
5739
|
-
var HaBrokerEntrySchema =
|
|
5740
|
-
id:
|
|
5741
|
-
name:
|
|
5739
|
+
var HaBrokerEntrySchema = require_ha_broker_source.object({
|
|
5740
|
+
id: require_ha_broker_source.string(),
|
|
5741
|
+
name: require_ha_broker_source.string(),
|
|
5742
5742
|
/** Either Supervisor (token from env) or long-lived (persisted). */
|
|
5743
|
-
auth:
|
|
5744
|
-
kind:
|
|
5745
|
-
supervisorToken:
|
|
5746
|
-
}),
|
|
5747
|
-
kind:
|
|
5748
|
-
baseUrl:
|
|
5749
|
-
accessToken:
|
|
5743
|
+
auth: require_ha_broker_source.discriminatedUnion("kind", [require_ha_broker_source.object({
|
|
5744
|
+
kind: require_ha_broker_source.literal("supervisor"),
|
|
5745
|
+
supervisorToken: require_ha_broker_source.string().meta({ secret: true })
|
|
5746
|
+
}), require_ha_broker_source.object({
|
|
5747
|
+
kind: require_ha_broker_source.literal("long-lived"),
|
|
5748
|
+
baseUrl: require_ha_broker_source.string(),
|
|
5749
|
+
accessToken: require_ha_broker_source.string().meta({ secret: true })
|
|
5750
5750
|
})]),
|
|
5751
5751
|
/** Optional FK to the integration record that spawned this broker.
|
|
5752
5752
|
* Populated when the wizard's "+ New Integration" flow created the
|
|
@@ -5754,7 +5754,7 @@ var HaBrokerEntrySchema = require_dist.object({
|
|
|
5754
5754
|
* directly. Used by the integration listener to keep the broker
|
|
5755
5755
|
* list in sync with the integrations table (cascade-delete on
|
|
5756
5756
|
* integration removal). */
|
|
5757
|
-
integrationId:
|
|
5757
|
+
integrationId: require_ha_broker_source.string().optional()
|
|
5758
5758
|
});
|
|
5759
5759
|
/**
|
|
5760
5760
|
* Validates a `broker.add` `settings` payload for the HA kind. Accepts:
|
|
@@ -5763,10 +5763,10 @@ var HaBrokerEntrySchema = require_dist.object({
|
|
|
5763
5763
|
* persisting allows the addon to keep working after the env var
|
|
5764
5764
|
* rotates out of scope)
|
|
5765
5765
|
*/
|
|
5766
|
-
var HaAddSettingsSchema =
|
|
5767
|
-
baseUrl:
|
|
5768
|
-
accessToken:
|
|
5769
|
-
}),
|
|
5766
|
+
var HaAddSettingsSchema = require_ha_broker_source.union([require_ha_broker_source.object({
|
|
5767
|
+
baseUrl: require_ha_broker_source.url(),
|
|
5768
|
+
accessToken: require_ha_broker_source.string().min(1).meta({ secret: true })
|
|
5769
|
+
}), require_ha_broker_source.object({ supervisorToken: require_ha_broker_source.string().min(1).meta({ secret: true }) })]);
|
|
5770
5770
|
function settingsToAuth(settings) {
|
|
5771
5771
|
const parsed = HaAddSettingsSchema.parse(settings);
|
|
5772
5772
|
if ("supervisorToken" in parsed) return {
|
|
@@ -5847,7 +5847,7 @@ var HaBrokerRegistry = class {
|
|
|
5847
5847
|
} catch (err) {
|
|
5848
5848
|
this.logger.warn("ha-broker bootstrap failed", { meta: {
|
|
5849
5849
|
brokerId: entry.id,
|
|
5850
|
-
error:
|
|
5850
|
+
error: require_ha_broker_source.errMsg(err)
|
|
5851
5851
|
} });
|
|
5852
5852
|
}
|
|
5853
5853
|
}));
|
|
@@ -5941,7 +5941,7 @@ var HaBrokerRegistry = class {
|
|
|
5941
5941
|
} catch (err) {
|
|
5942
5942
|
return {
|
|
5943
5943
|
ok: false,
|
|
5944
|
-
error:
|
|
5944
|
+
error: require_ha_broker_source.errMsg(err)
|
|
5945
5945
|
};
|
|
5946
5946
|
}
|
|
5947
5947
|
const startedAt = Date.now();
|
|
@@ -5979,7 +5979,7 @@ var HaBrokerRegistry = class {
|
|
|
5979
5979
|
client?.stop();
|
|
5980
5980
|
resolve({
|
|
5981
5981
|
ok: false,
|
|
5982
|
-
error:
|
|
5982
|
+
error: require_ha_broker_source.errMsg(err)
|
|
5983
5983
|
});
|
|
5984
5984
|
}
|
|
5985
5985
|
}
|
|
@@ -5991,7 +5991,7 @@ var HaBrokerRegistry = class {
|
|
|
5991
5991
|
client?.stop();
|
|
5992
5992
|
resolve({
|
|
5993
5993
|
ok: false,
|
|
5994
|
-
error:
|
|
5994
|
+
error: require_ha_broker_source.errMsg(err)
|
|
5995
5995
|
});
|
|
5996
5996
|
});
|
|
5997
5997
|
});
|
|
@@ -6186,27 +6186,27 @@ function mapHaEntityToCamStack(input) {
|
|
|
6186
6186
|
const { domain, deviceClass, attributes } = input;
|
|
6187
6187
|
switch (domain) {
|
|
6188
6188
|
case "switch": return {
|
|
6189
|
-
deviceType:
|
|
6190
|
-
role: deviceClass === "outlet" ?
|
|
6189
|
+
deviceType: require_ha_broker_source.DeviceType.Switch,
|
|
6190
|
+
role: deviceClass === "outlet" ? require_ha_broker_source.DeviceRole.Outlet : null,
|
|
6191
6191
|
capabilities: ["switch"]
|
|
6192
6192
|
};
|
|
6193
6193
|
case "input_boolean": return {
|
|
6194
|
-
deviceType:
|
|
6195
|
-
role:
|
|
6194
|
+
deviceType: require_ha_broker_source.DeviceType.Switch,
|
|
6195
|
+
role: require_ha_broker_source.DeviceRole.BinaryHelper,
|
|
6196
6196
|
capabilities: ["switch"]
|
|
6197
6197
|
};
|
|
6198
6198
|
case "remote": return {
|
|
6199
|
-
deviceType:
|
|
6199
|
+
deviceType: require_ha_broker_source.DeviceType.Switch,
|
|
6200
6200
|
role: null,
|
|
6201
6201
|
capabilities: ["switch"]
|
|
6202
6202
|
};
|
|
6203
6203
|
case "siren": return {
|
|
6204
|
-
deviceType:
|
|
6204
|
+
deviceType: require_ha_broker_source.DeviceType.Siren,
|
|
6205
6205
|
role: null,
|
|
6206
6206
|
capabilities: ["switch"]
|
|
6207
6207
|
};
|
|
6208
6208
|
case "update": return {
|
|
6209
|
-
deviceType:
|
|
6209
|
+
deviceType: require_ha_broker_source.DeviceType.Update,
|
|
6210
6210
|
role: null,
|
|
6211
6211
|
capabilities: ["update"]
|
|
6212
6212
|
};
|
|
@@ -6224,7 +6224,7 @@ function mapHaEntityToCamStack(input) {
|
|
|
6224
6224
|
case "alarm_control_panel": return mapAlarmPanel(attributes);
|
|
6225
6225
|
case "person":
|
|
6226
6226
|
case "device_tracker": return {
|
|
6227
|
-
deviceType:
|
|
6227
|
+
deviceType: require_ha_broker_source.DeviceType.Presence,
|
|
6228
6228
|
role: null,
|
|
6229
6229
|
capabilities: ["presence"]
|
|
6230
6230
|
};
|
|
@@ -6233,49 +6233,49 @@ function mapHaEntityToCamStack(input) {
|
|
|
6233
6233
|
case "camera": return mapImage(attributes);
|
|
6234
6234
|
case "number":
|
|
6235
6235
|
case "input_number": return {
|
|
6236
|
-
deviceType:
|
|
6237
|
-
role:
|
|
6236
|
+
deviceType: require_ha_broker_source.DeviceType.Control,
|
|
6237
|
+
role: require_ha_broker_source.DeviceRole.NumericControl,
|
|
6238
6238
|
capabilities: ["control"]
|
|
6239
6239
|
};
|
|
6240
6240
|
case "select":
|
|
6241
6241
|
case "input_select": return {
|
|
6242
|
-
deviceType:
|
|
6243
|
-
role:
|
|
6242
|
+
deviceType: require_ha_broker_source.DeviceType.Control,
|
|
6243
|
+
role: require_ha_broker_source.DeviceRole.SelectControl,
|
|
6244
6244
|
capabilities: ["control"]
|
|
6245
6245
|
};
|
|
6246
6246
|
case "text":
|
|
6247
6247
|
case "input_text": return {
|
|
6248
|
-
deviceType:
|
|
6249
|
-
role:
|
|
6248
|
+
deviceType: require_ha_broker_source.DeviceType.Control,
|
|
6249
|
+
role: require_ha_broker_source.DeviceRole.TextControl,
|
|
6250
6250
|
capabilities: ["control"]
|
|
6251
6251
|
};
|
|
6252
6252
|
case "input_datetime":
|
|
6253
6253
|
case "date":
|
|
6254
6254
|
case "time":
|
|
6255
6255
|
case "datetime": return {
|
|
6256
|
-
deviceType:
|
|
6257
|
-
role:
|
|
6256
|
+
deviceType: require_ha_broker_source.DeviceType.Control,
|
|
6257
|
+
role: require_ha_broker_source.DeviceRole.DateTimeControl,
|
|
6258
6258
|
capabilities: ["control"]
|
|
6259
6259
|
};
|
|
6260
6260
|
case "button":
|
|
6261
6261
|
case "input_button":
|
|
6262
6262
|
case "scene": return {
|
|
6263
|
-
deviceType:
|
|
6263
|
+
deviceType: require_ha_broker_source.DeviceType.Button,
|
|
6264
6264
|
role: null,
|
|
6265
6265
|
capabilities: ["button"]
|
|
6266
6266
|
};
|
|
6267
6267
|
case "event": return {
|
|
6268
|
-
deviceType:
|
|
6268
|
+
deviceType: require_ha_broker_source.DeviceType.EventEmitter,
|
|
6269
6269
|
role: null,
|
|
6270
6270
|
capabilities: ["event-emitter"]
|
|
6271
6271
|
};
|
|
6272
6272
|
case "script": return {
|
|
6273
|
-
deviceType:
|
|
6273
|
+
deviceType: require_ha_broker_source.DeviceType.Script,
|
|
6274
6274
|
role: null,
|
|
6275
6275
|
capabilities: ["script-runner"]
|
|
6276
6276
|
};
|
|
6277
6277
|
case "automation": return {
|
|
6278
|
-
deviceType:
|
|
6278
|
+
deviceType: require_ha_broker_source.DeviceType.Automation,
|
|
6279
6279
|
role: null,
|
|
6280
6280
|
capabilities: ["automation-control"]
|
|
6281
6281
|
};
|
|
@@ -6301,12 +6301,12 @@ function mapLight(attributes) {
|
|
|
6301
6301
|
const hasMired = modes.some((m) => m === "color_temp");
|
|
6302
6302
|
if (hasRgb || hasMired) {
|
|
6303
6303
|
capabilities.push("color");
|
|
6304
|
-
if (modes.includes("rgb") || modes.includes("rgbw") || modes.includes("rgbww") || modes.includes("xy")) features.push(
|
|
6305
|
-
if (modes.includes("hs")) features.push(
|
|
6306
|
-
if (hasMired) features.push(
|
|
6304
|
+
if (modes.includes("rgb") || modes.includes("rgbw") || modes.includes("rgbww") || modes.includes("xy")) features.push(require_ha_broker_source.DeviceFeature.LightColorRgb);
|
|
6305
|
+
if (modes.includes("hs")) features.push(require_ha_broker_source.DeviceFeature.LightColorHsv);
|
|
6306
|
+
if (hasMired) features.push(require_ha_broker_source.DeviceFeature.LightColorMired);
|
|
6307
6307
|
}
|
|
6308
6308
|
return {
|
|
6309
|
-
deviceType:
|
|
6309
|
+
deviceType: require_ha_broker_source.DeviceType.Light,
|
|
6310
6310
|
role: null,
|
|
6311
6311
|
capabilities,
|
|
6312
6312
|
features
|
|
@@ -6314,11 +6314,11 @@ function mapLight(attributes) {
|
|
|
6314
6314
|
}
|
|
6315
6315
|
function mapLock(attributes) {
|
|
6316
6316
|
const features = [];
|
|
6317
|
-
if (attributes["code_format"] !== void 0 && attributes["code_format"] !== null) features.push(
|
|
6317
|
+
if (attributes["code_format"] !== void 0 && attributes["code_format"] !== null) features.push(require_ha_broker_source.DeviceFeature.LockPinRequired);
|
|
6318
6318
|
const sf = readNumericAttr(attributes, "supported_features");
|
|
6319
|
-
if (sf !== null && (sf & 1) !== 0) features.push(
|
|
6319
|
+
if (sf !== null && (sf & 1) !== 0) features.push(require_ha_broker_source.DeviceFeature.LockOpen);
|
|
6320
6320
|
return {
|
|
6321
|
-
deviceType:
|
|
6321
|
+
deviceType: require_ha_broker_source.DeviceType.Lock,
|
|
6322
6322
|
role: null,
|
|
6323
6323
|
capabilities: ["lock-control"],
|
|
6324
6324
|
features
|
|
@@ -6327,10 +6327,10 @@ function mapLock(attributes) {
|
|
|
6327
6327
|
function mapCover(attributes, deviceClass) {
|
|
6328
6328
|
const features = [];
|
|
6329
6329
|
const sf = readNumericAttr(attributes, "supported_features");
|
|
6330
|
-
if (sf !== null && (sf & 4) !== 0) features.push(
|
|
6331
|
-
if (sf !== null && (sf & 128) !== 0) features.push(
|
|
6330
|
+
if (sf !== null && (sf & 4) !== 0) features.push(require_ha_broker_source.DeviceFeature.CoverPositionable);
|
|
6331
|
+
if (sf !== null && (sf & 128) !== 0) features.push(require_ha_broker_source.DeviceFeature.CoverTilt);
|
|
6332
6332
|
return {
|
|
6333
|
-
deviceType:
|
|
6333
|
+
deviceType: require_ha_broker_source.DeviceType.Cover,
|
|
6334
6334
|
role: coverRoleFor(deviceClass),
|
|
6335
6335
|
capabilities: ["cover"],
|
|
6336
6336
|
features
|
|
@@ -6340,23 +6340,23 @@ function mapCover(attributes, deviceClass) {
|
|
|
6340
6340
|
function coverRoleFor(deviceClass) {
|
|
6341
6341
|
switch (deviceClass) {
|
|
6342
6342
|
case "blind":
|
|
6343
|
-
case "shade": return
|
|
6344
|
-
case "shutter": return
|
|
6345
|
-
case "awning": return
|
|
6346
|
-
case "curtain": return
|
|
6347
|
-
case "garage": return
|
|
6348
|
-
case "gate": return
|
|
6349
|
-
case "door": return
|
|
6350
|
-
case "window": return
|
|
6343
|
+
case "shade": return require_ha_broker_source.DeviceRole.CoverBlind;
|
|
6344
|
+
case "shutter": return require_ha_broker_source.DeviceRole.CoverShutter;
|
|
6345
|
+
case "awning": return require_ha_broker_source.DeviceRole.CoverAwning;
|
|
6346
|
+
case "curtain": return require_ha_broker_source.DeviceRole.CoverCurtain;
|
|
6347
|
+
case "garage": return require_ha_broker_source.DeviceRole.CoverGarage;
|
|
6348
|
+
case "gate": return require_ha_broker_source.DeviceRole.CoverGate;
|
|
6349
|
+
case "door": return require_ha_broker_source.DeviceRole.CoverDoor;
|
|
6350
|
+
case "window": return require_ha_broker_source.DeviceRole.CoverWindow;
|
|
6351
6351
|
default: return null;
|
|
6352
6352
|
}
|
|
6353
6353
|
}
|
|
6354
6354
|
function mapValve(attributes, _deviceClass) {
|
|
6355
6355
|
const features = [];
|
|
6356
6356
|
const sf = readNumericAttr(attributes, "supported_features");
|
|
6357
|
-
if (sf !== null && (sf & 4) !== 0) features.push(
|
|
6357
|
+
if (sf !== null && (sf & 4) !== 0) features.push(require_ha_broker_source.DeviceFeature.ValvePositionable);
|
|
6358
6358
|
return {
|
|
6359
|
-
deviceType:
|
|
6359
|
+
deviceType: require_ha_broker_source.DeviceType.Valve,
|
|
6360
6360
|
role: null,
|
|
6361
6361
|
capabilities: ["valve"],
|
|
6362
6362
|
features
|
|
@@ -6364,7 +6364,7 @@ function mapValve(attributes, _deviceClass) {
|
|
|
6364
6364
|
}
|
|
6365
6365
|
function mapHumidifier(_attributes, _deviceClass) {
|
|
6366
6366
|
return {
|
|
6367
|
-
deviceType:
|
|
6367
|
+
deviceType: require_ha_broker_source.DeviceType.Humidifier,
|
|
6368
6368
|
role: null,
|
|
6369
6369
|
capabilities: ["humidifier"],
|
|
6370
6370
|
features: []
|
|
@@ -6372,7 +6372,7 @@ function mapHumidifier(_attributes, _deviceClass) {
|
|
|
6372
6372
|
}
|
|
6373
6373
|
function mapWaterHeater(_attributes, _deviceClass) {
|
|
6374
6374
|
return {
|
|
6375
|
-
deviceType:
|
|
6375
|
+
deviceType: require_ha_broker_source.DeviceType.WaterHeater,
|
|
6376
6376
|
role: null,
|
|
6377
6377
|
capabilities: ["water-heater"],
|
|
6378
6378
|
features: []
|
|
@@ -6382,13 +6382,13 @@ function mapFan(attributes) {
|
|
|
6382
6382
|
const features = [];
|
|
6383
6383
|
const sf = readNumericAttr(attributes, "supported_features");
|
|
6384
6384
|
if (sf !== null) {
|
|
6385
|
-
if ((sf & 1) !== 0) features.push(
|
|
6386
|
-
if ((sf & 2) !== 0) features.push(
|
|
6387
|
-
if ((sf & 4) !== 0) features.push(
|
|
6388
|
-
if ((sf & 8) !== 0) features.push(
|
|
6385
|
+
if ((sf & 1) !== 0) features.push(require_ha_broker_source.DeviceFeature.FanSpeed);
|
|
6386
|
+
if ((sf & 2) !== 0) features.push(require_ha_broker_source.DeviceFeature.FanOscillating);
|
|
6387
|
+
if ((sf & 4) !== 0) features.push(require_ha_broker_source.DeviceFeature.FanDirection);
|
|
6388
|
+
if ((sf & 8) !== 0) features.push(require_ha_broker_source.DeviceFeature.FanPreset);
|
|
6389
6389
|
}
|
|
6390
6390
|
return {
|
|
6391
|
-
deviceType:
|
|
6391
|
+
deviceType: require_ha_broker_source.DeviceType.Fan,
|
|
6392
6392
|
role: null,
|
|
6393
6393
|
capabilities: ["switch", "fan-control"],
|
|
6394
6394
|
features
|
|
@@ -6396,7 +6396,7 @@ function mapFan(attributes) {
|
|
|
6396
6396
|
}
|
|
6397
6397
|
function mapVacuum(_attributes) {
|
|
6398
6398
|
return {
|
|
6399
|
-
deviceType:
|
|
6399
|
+
deviceType: require_ha_broker_source.DeviceType.Vacuum,
|
|
6400
6400
|
role: null,
|
|
6401
6401
|
capabilities: ["vacuum-control"],
|
|
6402
6402
|
features: []
|
|
@@ -6404,7 +6404,7 @@ function mapVacuum(_attributes) {
|
|
|
6404
6404
|
}
|
|
6405
6405
|
function mapLawnMower(_attributes) {
|
|
6406
6406
|
return {
|
|
6407
|
-
deviceType:
|
|
6407
|
+
deviceType: require_ha_broker_source.DeviceType.LawnMower,
|
|
6408
6408
|
role: null,
|
|
6409
6409
|
capabilities: ["lawn-mower-control"],
|
|
6410
6410
|
features: []
|
|
@@ -6414,13 +6414,13 @@ function mapClimate(attributes) {
|
|
|
6414
6414
|
const features = [];
|
|
6415
6415
|
const sf = readNumericAttr(attributes, "supported_features");
|
|
6416
6416
|
if (sf !== null) {
|
|
6417
|
-
if ((sf & 2) !== 0) features.push(
|
|
6418
|
-
if ((sf & 4) !== 0) features.push(
|
|
6419
|
-
if ((sf & 8) !== 0) features.push(
|
|
6420
|
-
if ((sf & 16) !== 0) features.push(
|
|
6417
|
+
if ((sf & 2) !== 0) features.push(require_ha_broker_source.DeviceFeature.ClimateDualSetpoint);
|
|
6418
|
+
if ((sf & 4) !== 0) features.push(require_ha_broker_source.DeviceFeature.ClimateHumidity);
|
|
6419
|
+
if ((sf & 8) !== 0) features.push(require_ha_broker_source.DeviceFeature.ClimateFanMode);
|
|
6420
|
+
if ((sf & 16) !== 0) features.push(require_ha_broker_source.DeviceFeature.ClimatePreset);
|
|
6421
6421
|
}
|
|
6422
6422
|
return {
|
|
6423
|
-
deviceType:
|
|
6423
|
+
deviceType: require_ha_broker_source.DeviceType.Thermostat,
|
|
6424
6424
|
role: null,
|
|
6425
6425
|
capabilities: ["climate-control"],
|
|
6426
6426
|
features
|
|
@@ -6430,19 +6430,19 @@ function mapMediaPlayer(attributes) {
|
|
|
6430
6430
|
const features = [];
|
|
6431
6431
|
const sf = readNumericAttr(attributes, "supported_features");
|
|
6432
6432
|
if (sf !== null) {
|
|
6433
|
-
if ((sf & 2) !== 0) features.push(
|
|
6434
|
-
if ((sf & 4) !== 0) features.push(
|
|
6435
|
-
if ((sf & 8) !== 0) features.push(
|
|
6436
|
-
if ((sf & 16) !== 0) features.push(
|
|
6437
|
-
if ((sf & 32) !== 0) features.push(
|
|
6438
|
-
if ((sf & 512) !== 0) features.push(
|
|
6439
|
-
if ((sf & 2048) !== 0) features.push(
|
|
6440
|
-
if ((sf & 4096) !== 0) features.push(
|
|
6441
|
-
if ((sf & 32768) !== 0) features.push(
|
|
6442
|
-
if ((sf & 262144) !== 0) features.push(
|
|
6433
|
+
if ((sf & 2) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerSeek);
|
|
6434
|
+
if ((sf & 4) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerVolume);
|
|
6435
|
+
if ((sf & 8) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerMute);
|
|
6436
|
+
if ((sf & 16) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerPrevious);
|
|
6437
|
+
if ((sf & 32) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerNext);
|
|
6438
|
+
if ((sf & 512) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerPlayMedia);
|
|
6439
|
+
if ((sf & 2048) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerSelectSource);
|
|
6440
|
+
if ((sf & 4096) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerStop);
|
|
6441
|
+
if ((sf & 32768) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerShuffle);
|
|
6442
|
+
if ((sf & 262144) !== 0) features.push(require_ha_broker_source.DeviceFeature.MediaPlayerRepeat);
|
|
6443
6443
|
}
|
|
6444
6444
|
return {
|
|
6445
|
-
deviceType:
|
|
6445
|
+
deviceType: require_ha_broker_source.DeviceType.MediaPlayer,
|
|
6446
6446
|
role: null,
|
|
6447
6447
|
capabilities: ["media-player"],
|
|
6448
6448
|
features
|
|
@@ -6450,9 +6450,9 @@ function mapMediaPlayer(attributes) {
|
|
|
6450
6450
|
}
|
|
6451
6451
|
function mapAlarmPanel(attributes) {
|
|
6452
6452
|
const features = [];
|
|
6453
|
-
if (attributes["code_format"] !== void 0 && attributes["code_format"] !== null) features.push(
|
|
6453
|
+
if (attributes["code_format"] !== void 0 && attributes["code_format"] !== null) features.push(require_ha_broker_source.DeviceFeature.AlarmPinRequired);
|
|
6454
6454
|
return {
|
|
6455
|
-
deviceType:
|
|
6455
|
+
deviceType: require_ha_broker_source.DeviceType.AlarmPanel,
|
|
6456
6456
|
role: null,
|
|
6457
6457
|
capabilities: ["alarm-panel"],
|
|
6458
6458
|
features
|
|
@@ -6460,21 +6460,21 @@ function mapAlarmPanel(attributes) {
|
|
|
6460
6460
|
}
|
|
6461
6461
|
function mapNotifier(_attributes) {
|
|
6462
6462
|
return {
|
|
6463
|
-
deviceType:
|
|
6464
|
-
role:
|
|
6463
|
+
deviceType: require_ha_broker_source.DeviceType.Notifier,
|
|
6464
|
+
role: require_ha_broker_source.DeviceRole.GenericNotifier,
|
|
6465
6465
|
capabilities: ["notifier"]
|
|
6466
6466
|
};
|
|
6467
6467
|
}
|
|
6468
6468
|
function mapWeather(_attributes) {
|
|
6469
6469
|
return {
|
|
6470
|
-
deviceType:
|
|
6470
|
+
deviceType: require_ha_broker_source.DeviceType.Weather,
|
|
6471
6471
|
role: null,
|
|
6472
6472
|
capabilities: ["weather"]
|
|
6473
6473
|
};
|
|
6474
6474
|
}
|
|
6475
6475
|
function mapImage(_attributes) {
|
|
6476
6476
|
return {
|
|
6477
|
-
deviceType:
|
|
6477
|
+
deviceType: require_ha_broker_source.DeviceType.Image,
|
|
6478
6478
|
role: null,
|
|
6479
6479
|
capabilities: ["image"]
|
|
6480
6480
|
};
|
|
@@ -6488,60 +6488,60 @@ function isTemperatureUnit(unit) {
|
|
|
6488
6488
|
function mapNumericSensor(deviceClass, _attributes) {
|
|
6489
6489
|
switch (deviceClass) {
|
|
6490
6490
|
case "temperature": return {
|
|
6491
|
-
deviceType:
|
|
6492
|
-
role:
|
|
6491
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6492
|
+
role: require_ha_broker_source.DeviceRole.TemperatureSensor,
|
|
6493
6493
|
capabilities: ["temperature-sensor"]
|
|
6494
6494
|
};
|
|
6495
6495
|
case "humidity": return {
|
|
6496
|
-
deviceType:
|
|
6497
|
-
role:
|
|
6496
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6497
|
+
role: require_ha_broker_source.DeviceRole.HumiditySensor,
|
|
6498
6498
|
capabilities: ["humidity-sensor"]
|
|
6499
6499
|
};
|
|
6500
6500
|
case "illuminance": return {
|
|
6501
|
-
deviceType:
|
|
6502
|
-
role:
|
|
6501
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6502
|
+
role: require_ha_broker_source.DeviceRole.AmbientLightSensor,
|
|
6503
6503
|
capabilities: ["ambient-light-sensor"]
|
|
6504
6504
|
};
|
|
6505
6505
|
case "pressure":
|
|
6506
6506
|
case "atmospheric_pressure": return {
|
|
6507
|
-
deviceType:
|
|
6508
|
-
role:
|
|
6507
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6508
|
+
role: require_ha_broker_source.DeviceRole.PressureSensor,
|
|
6509
6509
|
capabilities: ["pressure-sensor"]
|
|
6510
6510
|
};
|
|
6511
6511
|
case "wind_speed": return {
|
|
6512
|
-
deviceType:
|
|
6513
|
-
role:
|
|
6512
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6513
|
+
role: require_ha_broker_source.DeviceRole.WindSensor,
|
|
6514
6514
|
capabilities: ["numeric-sensor"]
|
|
6515
6515
|
};
|
|
6516
6516
|
case "precipitation":
|
|
6517
6517
|
case "precipitation_intensity": return {
|
|
6518
|
-
deviceType:
|
|
6519
|
-
role:
|
|
6518
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6519
|
+
role: require_ha_broker_source.DeviceRole.RainSensor,
|
|
6520
6520
|
capabilities: ["numeric-sensor"]
|
|
6521
6521
|
};
|
|
6522
6522
|
case "irradiance": return {
|
|
6523
|
-
deviceType:
|
|
6524
|
-
role:
|
|
6523
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6524
|
+
role: require_ha_broker_source.DeviceRole.SolarRadiationSensor,
|
|
6525
6525
|
capabilities: ["numeric-sensor"]
|
|
6526
6526
|
};
|
|
6527
6527
|
case "power": return {
|
|
6528
|
-
deviceType:
|
|
6529
|
-
role:
|
|
6528
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6529
|
+
role: require_ha_broker_source.DeviceRole.PowerSensor,
|
|
6530
6530
|
capabilities: ["power-meter"]
|
|
6531
6531
|
};
|
|
6532
6532
|
case "energy": return {
|
|
6533
|
-
deviceType:
|
|
6534
|
-
role:
|
|
6533
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6534
|
+
role: require_ha_broker_source.DeviceRole.EnergySensor,
|
|
6535
6535
|
capabilities: ["power-meter"]
|
|
6536
6536
|
};
|
|
6537
6537
|
case "voltage": return {
|
|
6538
|
-
deviceType:
|
|
6539
|
-
role:
|
|
6538
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6539
|
+
role: require_ha_broker_source.DeviceRole.VoltageSensor,
|
|
6540
6540
|
capabilities: ["power-meter"]
|
|
6541
6541
|
};
|
|
6542
6542
|
case "current": return {
|
|
6543
|
-
deviceType:
|
|
6544
|
-
role:
|
|
6543
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6544
|
+
role: require_ha_broker_source.DeviceRole.CurrentSensor,
|
|
6545
6545
|
capabilities: ["power-meter"]
|
|
6546
6546
|
};
|
|
6547
6547
|
case "pm1":
|
|
@@ -6554,46 +6554,46 @@ function mapNumericSensor(deviceClass, _attributes) {
|
|
|
6554
6554
|
case "sulphur_dioxide":
|
|
6555
6555
|
case "volatile_organic_compounds":
|
|
6556
6556
|
case "aqi": return {
|
|
6557
|
-
deviceType:
|
|
6558
|
-
role:
|
|
6557
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6558
|
+
role: require_ha_broker_source.DeviceRole.AirQualitySensor,
|
|
6559
6559
|
capabilities: ["air-quality-sensor"]
|
|
6560
6560
|
};
|
|
6561
6561
|
case "battery": return {
|
|
6562
|
-
deviceType:
|
|
6563
|
-
role:
|
|
6562
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6563
|
+
role: require_ha_broker_source.DeviceRole.BatterySensor,
|
|
6564
6564
|
capabilities: ["numeric-sensor"]
|
|
6565
6565
|
};
|
|
6566
6566
|
case "enum": return {
|
|
6567
|
-
deviceType:
|
|
6568
|
-
role:
|
|
6567
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6568
|
+
role: require_ha_broker_source.DeviceRole.EnumSensor,
|
|
6569
6569
|
capabilities: ["enum-sensor"]
|
|
6570
6570
|
};
|
|
6571
6571
|
case "timestamp": return {
|
|
6572
|
-
deviceType:
|
|
6573
|
-
role:
|
|
6572
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6573
|
+
role: require_ha_broker_source.DeviceRole.DateTimeSensor,
|
|
6574
6574
|
capabilities: ["enum-sensor"],
|
|
6575
6575
|
dateTimeFormat: "datetime"
|
|
6576
6576
|
};
|
|
6577
6577
|
case "date": return {
|
|
6578
|
-
deviceType:
|
|
6579
|
-
role:
|
|
6578
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6579
|
+
role: require_ha_broker_source.DeviceRole.DateTimeSensor,
|
|
6580
6580
|
capabilities: ["enum-sensor"],
|
|
6581
6581
|
dateTimeFormat: "date"
|
|
6582
6582
|
};
|
|
6583
6583
|
case null:
|
|
6584
6584
|
if (isTemperatureUnit(_attributes["unit_of_measurement"])) return {
|
|
6585
|
-
deviceType:
|
|
6586
|
-
role:
|
|
6585
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6586
|
+
role: require_ha_broker_source.DeviceRole.TemperatureSensor,
|
|
6587
6587
|
capabilities: ["temperature-sensor"]
|
|
6588
6588
|
};
|
|
6589
6589
|
return {
|
|
6590
|
-
deviceType:
|
|
6591
|
-
role:
|
|
6590
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6591
|
+
role: require_ha_broker_source.DeviceRole.EnumSensor,
|
|
6592
6592
|
capabilities: ["enum-sensor"]
|
|
6593
6593
|
};
|
|
6594
6594
|
default: return {
|
|
6595
|
-
deviceType:
|
|
6596
|
-
role:
|
|
6595
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6596
|
+
role: require_ha_broker_source.DeviceRole.NumericSensor,
|
|
6597
6597
|
capabilities: ["numeric-sensor"]
|
|
6598
6598
|
};
|
|
6599
6599
|
}
|
|
@@ -6604,67 +6604,67 @@ function mapBinarySensor(deviceClass) {
|
|
|
6604
6604
|
case "occupancy":
|
|
6605
6605
|
case "presence":
|
|
6606
6606
|
case "moving": return {
|
|
6607
|
-
deviceType:
|
|
6608
|
-
role:
|
|
6607
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6608
|
+
role: require_ha_broker_source.DeviceRole.MotionSensor,
|
|
6609
6609
|
capabilities: ["motion"]
|
|
6610
6610
|
};
|
|
6611
6611
|
case "door":
|
|
6612
6612
|
case "window":
|
|
6613
6613
|
case "garage_door":
|
|
6614
6614
|
case "opening": return {
|
|
6615
|
-
deviceType:
|
|
6616
|
-
role:
|
|
6615
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6616
|
+
role: require_ha_broker_source.DeviceRole.ContactSensor,
|
|
6617
6617
|
capabilities: ["contact"]
|
|
6618
6618
|
};
|
|
6619
6619
|
case "moisture": return {
|
|
6620
|
-
deviceType:
|
|
6621
|
-
role:
|
|
6620
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6621
|
+
role: require_ha_broker_source.DeviceRole.LeakSensor,
|
|
6622
6622
|
capabilities: ["flood"]
|
|
6623
6623
|
};
|
|
6624
6624
|
case "smoke": return {
|
|
6625
|
-
deviceType:
|
|
6626
|
-
role:
|
|
6625
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6626
|
+
role: require_ha_broker_source.DeviceRole.SmokeSensor,
|
|
6627
6627
|
capabilities: ["smoke"]
|
|
6628
6628
|
};
|
|
6629
6629
|
case "carbon_monoxide": return {
|
|
6630
|
-
deviceType:
|
|
6631
|
-
role:
|
|
6630
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6631
|
+
role: require_ha_broker_source.DeviceRole.COSensor,
|
|
6632
6632
|
capabilities: ["carbon-monoxide"]
|
|
6633
6633
|
};
|
|
6634
6634
|
case "gas": return {
|
|
6635
|
-
deviceType:
|
|
6636
|
-
role:
|
|
6635
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6636
|
+
role: require_ha_broker_source.DeviceRole.GasSensor,
|
|
6637
6637
|
capabilities: ["gas"]
|
|
6638
6638
|
};
|
|
6639
6639
|
case "tamper":
|
|
6640
6640
|
case "safety": return {
|
|
6641
|
-
deviceType:
|
|
6642
|
-
role:
|
|
6641
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6642
|
+
role: require_ha_broker_source.DeviceRole.TamperSensor,
|
|
6643
6643
|
capabilities: ["tamper"]
|
|
6644
6644
|
};
|
|
6645
6645
|
case "vibration": return {
|
|
6646
|
-
deviceType:
|
|
6647
|
-
role:
|
|
6646
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6647
|
+
role: require_ha_broker_source.DeviceRole.VibrationSensor,
|
|
6648
6648
|
capabilities: ["vibration"]
|
|
6649
6649
|
};
|
|
6650
6650
|
case "connectivity": return {
|
|
6651
|
-
deviceType:
|
|
6652
|
-
role:
|
|
6651
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6652
|
+
role: require_ha_broker_source.DeviceRole.ConnectivitySensor,
|
|
6653
6653
|
capabilities: ["connectivity"]
|
|
6654
6654
|
};
|
|
6655
6655
|
case "sound": return {
|
|
6656
|
-
deviceType:
|
|
6657
|
-
role:
|
|
6656
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6657
|
+
role: require_ha_broker_source.DeviceRole.SoundSensor,
|
|
6658
6658
|
capabilities: ["binary"]
|
|
6659
6659
|
};
|
|
6660
6660
|
case "battery": return {
|
|
6661
|
-
deviceType:
|
|
6662
|
-
role:
|
|
6661
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6662
|
+
role: require_ha_broker_source.DeviceRole.BatterySensor,
|
|
6663
6663
|
capabilities: ["binary"]
|
|
6664
6664
|
};
|
|
6665
6665
|
default: return {
|
|
6666
|
-
deviceType:
|
|
6667
|
-
role:
|
|
6666
|
+
deviceType: require_ha_broker_source.DeviceType.Sensor,
|
|
6667
|
+
role: require_ha_broker_source.DeviceRole.BinarySensor,
|
|
6668
6668
|
capabilities: ["binary"]
|
|
6669
6669
|
};
|
|
6670
6670
|
}
|
|
@@ -6687,40 +6687,40 @@ function readNumericAttr(attributes, key) {
|
|
|
6687
6687
|
* Sensor; an HA-tracked light with motion sensor becomes Light).
|
|
6688
6688
|
*/
|
|
6689
6689
|
var PARENT_TYPE_PRIORITY = [
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6690
|
+
require_ha_broker_source.DeviceType.MediaPlayer,
|
|
6691
|
+
require_ha_broker_source.DeviceType.AlarmPanel,
|
|
6692
|
+
require_ha_broker_source.DeviceType.Thermostat,
|
|
6693
|
+
require_ha_broker_source.DeviceType.Climate,
|
|
6694
|
+
require_ha_broker_source.DeviceType.Humidifier,
|
|
6695
|
+
require_ha_broker_source.DeviceType.WaterHeater,
|
|
6696
|
+
require_ha_broker_source.DeviceType.Lock,
|
|
6697
|
+
require_ha_broker_source.DeviceType.Cover,
|
|
6698
|
+
require_ha_broker_source.DeviceType.Valve,
|
|
6699
|
+
require_ha_broker_source.DeviceType.Fan,
|
|
6700
|
+
require_ha_broker_source.DeviceType.Vacuum,
|
|
6701
|
+
require_ha_broker_source.DeviceType.LawnMower,
|
|
6702
|
+
require_ha_broker_source.DeviceType.Washer,
|
|
6703
|
+
require_ha_broker_source.DeviceType.Dryer,
|
|
6704
|
+
require_ha_broker_source.DeviceType.Dishwasher,
|
|
6705
|
+
require_ha_broker_source.DeviceType.Light,
|
|
6706
|
+
require_ha_broker_source.DeviceType.Switch,
|
|
6707
|
+
require_ha_broker_source.DeviceType.Siren,
|
|
6708
|
+
require_ha_broker_source.DeviceType.Button,
|
|
6709
|
+
require_ha_broker_source.DeviceType.Control,
|
|
6710
|
+
require_ha_broker_source.DeviceType.Notifier,
|
|
6711
|
+
require_ha_broker_source.DeviceType.Script,
|
|
6712
|
+
require_ha_broker_source.DeviceType.Automation,
|
|
6713
|
+
require_ha_broker_source.DeviceType.Update,
|
|
6714
|
+
require_ha_broker_source.DeviceType.Presence,
|
|
6715
|
+
require_ha_broker_source.DeviceType.Weather,
|
|
6716
|
+
require_ha_broker_source.DeviceType.Image,
|
|
6717
|
+
require_ha_broker_source.DeviceType.Sensor
|
|
6718
6718
|
];
|
|
6719
6719
|
function inferParentDeviceType(mappings) {
|
|
6720
6720
|
const set = /* @__PURE__ */ new Set();
|
|
6721
6721
|
for (const m of mappings) if (m) set.add(m.deviceType);
|
|
6722
6722
|
for (const dt of PARENT_TYPE_PRIORITY) if (set.has(dt)) return dt;
|
|
6723
|
-
return
|
|
6723
|
+
return require_ha_broker_source.DeviceType.Generic;
|
|
6724
6724
|
}
|
|
6725
6725
|
//#endregion
|
|
6726
6726
|
//#region src/ha-candidate-mapper.ts
|
|
@@ -6742,7 +6742,7 @@ function haDeviceToCandidate(dev) {
|
|
|
6742
6742
|
return {
|
|
6743
6743
|
childNativeId: e.entityId,
|
|
6744
6744
|
name: e.name,
|
|
6745
|
-
type: e.mappedTo?.deviceType ??
|
|
6745
|
+
type: e.mappedTo?.deviceType ?? require_ha_broker_source.DeviceType.Generic,
|
|
6746
6746
|
status: entityStatus$1(e.state),
|
|
6747
6747
|
metadata: e.area !== null ? { externalLocation: e.area } : {},
|
|
6748
6748
|
alreadyAdopted: e.alreadyAdopted,
|
|
@@ -6889,7 +6889,7 @@ function buildDiscoveryCandidates(input) {
|
|
|
6889
6889
|
};
|
|
6890
6890
|
candidates.push({
|
|
6891
6891
|
stableId,
|
|
6892
|
-
type:
|
|
6892
|
+
type: require_ha_broker_source.DeviceType.Container,
|
|
6893
6893
|
suggestedName,
|
|
6894
6894
|
prefilledConfig,
|
|
6895
6895
|
sourceInfo
|
|
@@ -6917,52 +6917,52 @@ function buildDiscoveryCandidates(input) {
|
|
|
6917
6917
|
* shown as a Devices-tab candidate.
|
|
6918
6918
|
*/
|
|
6919
6919
|
var HA_ORPHAN_ENTITIES_DEVICE_ID = "__ha_orphan_entities__";
|
|
6920
|
-
var HaEntityMappingSchema =
|
|
6920
|
+
var HaEntityMappingSchema = require_ha_broker_source.object({
|
|
6921
6921
|
/** CamStack DeviceType for the accessory child. */
|
|
6922
|
-
deviceType:
|
|
6922
|
+
deviceType: require_ha_broker_source._enum(require_ha_broker_source.DeviceType),
|
|
6923
6923
|
/** Optional CamStack DeviceRole sub-role (e.g. `ContactSensor` for
|
|
6924
6924
|
* a binary_sensor with `device_class: door`). */
|
|
6925
|
-
role:
|
|
6925
|
+
role: require_ha_broker_source._enum(require_ha_broker_source.DeviceRole).nullable(),
|
|
6926
6926
|
/** Capability names the accessory child will register
|
|
6927
6927
|
* (`switch` / `temperature-sensor` / …). UI may render the cap
|
|
6928
6928
|
* badges to help the operator decide what to hide. */
|
|
6929
|
-
capabilities:
|
|
6929
|
+
capabilities: require_ha_broker_source.array(require_ha_broker_source.string()).readonly(),
|
|
6930
6930
|
/** Mapping-derived DeviceFeature flags (e.g. `lock-open`). Persisted onto
|
|
6931
6931
|
* the child's `device.features` so the UI gates feature affordances. */
|
|
6932
|
-
features:
|
|
6932
|
+
features: require_ha_broker_source.array(require_ha_broker_source.string()).readonly().optional(),
|
|
6933
6933
|
/** Locale-render shape for a `DateTimeSensor`-role enum sensor
|
|
6934
6934
|
* (`device_class=timestamp` → `'datetime'`, `date` → `'date'`). Threaded
|
|
6935
6935
|
* onto the child config so the enum-sensor device seeds it into the cap
|
|
6936
6936
|
* slice. Absent for every non-DateTimeSensor mapping. */
|
|
6937
|
-
dateTimeFormat:
|
|
6937
|
+
dateTimeFormat: require_ha_broker_source.EnumSensorDateTimeFormatSchema.optional()
|
|
6938
6938
|
}).nullable();
|
|
6939
|
-
var HaDiscoveredEntitySchema =
|
|
6939
|
+
var HaDiscoveredEntitySchema = require_ha_broker_source.object({
|
|
6940
6940
|
/** Fully-qualified HA entity id (`switch.kitchen`). */
|
|
6941
|
-
entityId:
|
|
6941
|
+
entityId: require_ha_broker_source.string(),
|
|
6942
6942
|
/** HA domain — first segment of entity_id (`switch` / `light` /
|
|
6943
6943
|
* `sensor` / `binary_sensor` / `cover` / …). */
|
|
6944
|
-
domain:
|
|
6944
|
+
domain: require_ha_broker_source.string(),
|
|
6945
6945
|
/** Operator-visible friendly name (HA `friendly_name` attribute or
|
|
6946
6946
|
* the entity_id when missing). */
|
|
6947
|
-
name:
|
|
6947
|
+
name: require_ha_broker_source.string(),
|
|
6948
6948
|
/** Current state value (e.g. `'on'`, `'21.5'`, `'open'`). */
|
|
6949
|
-
state:
|
|
6949
|
+
state: require_ha_broker_source.string(),
|
|
6950
6950
|
/** HA `device_class` attribute when present — drives the role +
|
|
6951
6951
|
* cap mapping for sensors / binary_sensors / covers. */
|
|
6952
|
-
deviceClass:
|
|
6952
|
+
deviceClass: require_ha_broker_source.string().nullable(),
|
|
6953
6953
|
/** HA `unit_of_measurement` attribute when present. */
|
|
6954
|
-
unitOfMeasurement:
|
|
6954
|
+
unitOfMeasurement: require_ha_broker_source.string().nullable(),
|
|
6955
6955
|
/** Area name for this entity — the entity's own HA area if set, else its
|
|
6956
6956
|
* parent device's area. Null when neither is assigned. */
|
|
6957
|
-
area:
|
|
6957
|
+
area: require_ha_broker_source.string().nullable().default(null),
|
|
6958
6958
|
/** HA `options` attribute — present on `select` / `input_select` entities.
|
|
6959
6959
|
* Captured at discovery so the adopt handler can persist them alongside
|
|
6960
6960
|
* other entity config fields. Absent on non-select entities. */
|
|
6961
|
-
options:
|
|
6961
|
+
options: require_ha_broker_source.array(require_ha_broker_source.string()).nullable().default(null),
|
|
6962
6962
|
/** HA `entity_category` — `config` / `diagnostic` / null (a normal control).
|
|
6963
6963
|
* Drives the accordion section the adopted child renders in. Null/absent for
|
|
6964
6964
|
* the common control case. */
|
|
6965
|
-
entityCategory:
|
|
6965
|
+
entityCategory: require_ha_broker_source._enum(["config", "diagnostic"]).nullable().default(null),
|
|
6966
6966
|
/** Pre-computed CamStack mapping. `null` when the entity's domain
|
|
6967
6967
|
* has no supported mapping (the operator may still adopt the
|
|
6968
6968
|
* parent — the entity will be skipped or surfaced as a fallback). */
|
|
@@ -6970,48 +6970,48 @@ var HaDiscoveredEntitySchema = require_dist.object({
|
|
|
6970
6970
|
/** When `true`, the entity was already materialised as a CamStack
|
|
6971
6971
|
* accessory child under a prior adoption — surfaced so the UI can
|
|
6972
6972
|
* highlight existing wiring. */
|
|
6973
|
-
alreadyAdopted:
|
|
6973
|
+
alreadyAdopted: require_ha_broker_source.boolean(),
|
|
6974
6974
|
/** When `alreadyAdopted === true`, the kernel-assigned accessory
|
|
6975
6975
|
* child id. */
|
|
6976
|
-
adoptedCamDeviceId:
|
|
6976
|
+
adoptedCamDeviceId: require_ha_broker_source.number().int().nonnegative().nullable()
|
|
6977
6977
|
});
|
|
6978
|
-
|
|
6978
|
+
require_ha_broker_source.object({
|
|
6979
6979
|
/** Stable HA `device_registry` id — survives renames + restarts. */
|
|
6980
|
-
haDeviceId:
|
|
6980
|
+
haDeviceId: require_ha_broker_source.string(),
|
|
6981
6981
|
/** Operator-visible name (HA device `name` or first entity's
|
|
6982
6982
|
* friendly_name when device has none). */
|
|
6983
|
-
name:
|
|
6983
|
+
name: require_ha_broker_source.string(),
|
|
6984
6984
|
/** Area name from HA `area_registry` join. Null when unassigned. */
|
|
6985
|
-
area:
|
|
6986
|
-
manufacturer:
|
|
6987
|
-
model:
|
|
6988
|
-
swVersion:
|
|
6985
|
+
area: require_ha_broker_source.string().nullable(),
|
|
6986
|
+
manufacturer: require_ha_broker_source.string().nullable(),
|
|
6987
|
+
model: require_ha_broker_source.string().nullable(),
|
|
6988
|
+
swVersion: require_ha_broker_source.string().nullable(),
|
|
6989
6989
|
/** Dominant integration / platform domain for this device, derived from its
|
|
6990
6990
|
* entities' HA `entity_registry.platform` (e.g. `dreame_vacuum`). Generic /
|
|
6991
6991
|
* helper platforms (`unifi` / `hacs` / `hassio`) are excluded when a real
|
|
6992
6992
|
* platform is available. Null when the device has no entities. */
|
|
6993
|
-
integration:
|
|
6993
|
+
integration: require_ha_broker_source.string().nullable().default(null),
|
|
6994
6994
|
/** Convenience field — count of `entities[]`. */
|
|
6995
|
-
entityCount:
|
|
6995
|
+
entityCount: require_ha_broker_source.number().int().nonnegative(),
|
|
6996
6996
|
/** Every entity HA's `entity_registry` links to this device. The
|
|
6997
6997
|
* list survives row collapse — full devices are returned so
|
|
6998
6998
|
* accordion expansion is a no-roundtrip render. */
|
|
6999
|
-
entities:
|
|
6999
|
+
entities: require_ha_broker_source.array(HaDiscoveredEntitySchema).readonly(),
|
|
7000
7000
|
/** Whether this HA device has an active CamStack adoption. */
|
|
7001
|
-
alreadyAdopted:
|
|
7001
|
+
alreadyAdopted: require_ha_broker_source.boolean(),
|
|
7002
7002
|
/** When `alreadyAdopted === true`, the kernel-assigned parent id. */
|
|
7003
|
-
adoptedCamDeviceId:
|
|
7003
|
+
adoptedCamDeviceId: require_ha_broker_source.number().int().nonnegative().nullable()
|
|
7004
7004
|
});
|
|
7005
|
-
|
|
7005
|
+
require_ha_broker_source.object({
|
|
7006
7006
|
/** Last refresh timestamp (ms epoch) — null when never refreshed. */
|
|
7007
|
-
lastDiscoveryAt:
|
|
7007
|
+
lastDiscoveryAt: require_ha_broker_source.number().int().nonnegative().nullable(),
|
|
7008
7008
|
/** Count of HA devices in the discovery cache (across all brokers). */
|
|
7009
|
-
deviceCount:
|
|
7009
|
+
deviceCount: require_ha_broker_source.number().int().nonnegative(),
|
|
7010
7010
|
/** Count of HA devices currently materialised as CamStack parent
|
|
7011
7011
|
* devices. */
|
|
7012
|
-
adoptedCount:
|
|
7012
|
+
adoptedCount: require_ha_broker_source.number().int().nonnegative(),
|
|
7013
7013
|
/** Last error message from a refresh attempt. */
|
|
7014
|
-
lastError:
|
|
7014
|
+
lastError: require_ha_broker_source.string().nullable()
|
|
7015
7015
|
});
|
|
7016
7016
|
//#endregion
|
|
7017
7017
|
//#region src/ha-integration-domain.ts
|
|
@@ -7150,7 +7150,7 @@ function negotiateEncoding(acceptEncoding) {
|
|
|
7150
7150
|
}
|
|
7151
7151
|
/** Build the `addon-routes` provider that serves the bundled Home Assistant icon. */
|
|
7152
7152
|
function createHaIconRouteProvider() {
|
|
7153
|
-
return
|
|
7153
|
+
return require_ha_broker_source.buildAddonRouteProvider(HA_ROUTE_ID, [{
|
|
7154
7154
|
method: "GET",
|
|
7155
7155
|
path: `/icons/${HA_ICON_KIND}`,
|
|
7156
7156
|
access: "public",
|
|
@@ -7169,11 +7169,11 @@ function createHaIconRouteProvider() {
|
|
|
7169
7169
|
* Broker entry kind (B2): credentials live in records; integrations keep brokerId.
|
|
7170
7170
|
*/
|
|
7171
7171
|
var HA_BROKERS_KIND = "brokers";
|
|
7172
|
-
var HaBrokerBodySchema =
|
|
7172
|
+
var HaBrokerBodySchema = require_ha_broker_source.entryBody({
|
|
7173
7173
|
auth: HaBrokerEntrySchema.shape.auth,
|
|
7174
|
-
integrationId:
|
|
7174
|
+
integrationId: require_ha_broker_source.string().optional()
|
|
7175
7175
|
});
|
|
7176
|
-
var haBrokersEntryKind =
|
|
7176
|
+
var haBrokersEntryKind = require_ha_broker_source.defineEntryKind(HA_BROKERS_KIND, {
|
|
7177
7177
|
title: "Home Assistant brokers",
|
|
7178
7178
|
schema: HaBrokerBodySchema,
|
|
7179
7179
|
writeTrigger: "an operator adds, edits or removes a Home Assistant broker connection"
|
|
@@ -7187,8 +7187,8 @@ var haBrokersEntryKind = require_dist.defineEntryKind(HA_BROKERS_KIND, {
|
|
|
7187
7187
|
* credential — delivery reuses the broker WebSocket connection (the token
|
|
7188
7188
|
* lives in the broker config, not in the target).
|
|
7189
7189
|
*/
|
|
7190
|
-
var HaTargetBodySchema =
|
|
7191
|
-
var haRecordKinds =
|
|
7190
|
+
var HaTargetBodySchema = require_ha_broker_source.TargetSchema.omit({ id: true });
|
|
7191
|
+
var haRecordKinds = require_ha_broker_source.defineRecordKinds({
|
|
7192
7192
|
/**
|
|
7193
7193
|
* One row per configured Home Assistant push target. Operator-managed via the
|
|
7194
7194
|
* notification-output cap CRUD; no TTL.
|
|
@@ -7248,21 +7248,27 @@ function haConfigSchema() {
|
|
|
7248
7248
|
title: "Home Assistant notify",
|
|
7249
7249
|
titleKey: "provider-homeassistant:haConfig.s_connection.title",
|
|
7250
7250
|
fields: [{
|
|
7251
|
-
type: "
|
|
7251
|
+
type: "broker-select",
|
|
7252
|
+
key: "brokerId",
|
|
7253
|
+
label: "Broker",
|
|
7254
|
+
labelKey: "provider-homeassistant:haConfig.s_connection.brokerId.label",
|
|
7255
|
+
description: "The Home Assistant connection the notification goes through.",
|
|
7256
|
+
descriptionKey: "provider-homeassistant:haConfig.s_connection.brokerId.description",
|
|
7257
|
+
brokerKind: require_ha_broker_source.HA_BROKER_KIND
|
|
7258
|
+
}, {
|
|
7259
|
+
type: "select",
|
|
7252
7260
|
key: "service",
|
|
7253
7261
|
label: "Notify service",
|
|
7254
7262
|
labelKey: "provider-homeassistant:haConfig.s_connection.service.label",
|
|
7255
7263
|
required: true,
|
|
7264
|
+
options: [],
|
|
7256
7265
|
placeholder: "mobile_app_pixel_7",
|
|
7257
|
-
description: "
|
|
7258
|
-
descriptionKey: "provider-homeassistant:haConfig.s_connection.service.description"
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
labelKey: "provider-homeassistant:haConfig.s_connection.brokerId.label",
|
|
7264
|
-
description: "Optional; blank uses the only configured broker.",
|
|
7265
|
-
descriptionKey: "provider-homeassistant:haConfig.s_connection.brokerId.description"
|
|
7266
|
+
description: "Loaded from the broker once it is picked. If the list does not load, type the part after `notify.`.",
|
|
7267
|
+
descriptionKey: "provider-homeassistant:haConfig.s_connection.service.description",
|
|
7268
|
+
discoverOptions: {
|
|
7269
|
+
kind: HA_NOTIFICATION_KIND,
|
|
7270
|
+
dependsOn: ["brokerId"]
|
|
7271
|
+
}
|
|
7266
7272
|
}]
|
|
7267
7273
|
}] };
|
|
7268
7274
|
}
|
|
@@ -7403,24 +7409,70 @@ function buildNotifyServiceData(prepared) {
|
|
|
7403
7409
|
* `get_services` returns `{ [domain]: { [service]: {...} } }`; we read the
|
|
7404
7410
|
* `notify` domain. mobile_app_* services (rich push features) sort first.
|
|
7405
7411
|
*/
|
|
7406
|
-
function parseNotifyServices(result, brokerId) {
|
|
7412
|
+
function parseNotifyServices(result, brokerId, deviceNames) {
|
|
7407
7413
|
if (typeof result !== "object" || result === null) return [];
|
|
7408
7414
|
const notify = result["notify"];
|
|
7409
7415
|
if (typeof notify !== "object" || notify === null) return [];
|
|
7410
|
-
return [...Object.
|
|
7416
|
+
return [...Object.entries(notify)].sort(([a], [b]) => {
|
|
7411
7417
|
const am = a.startsWith("mobile_app_") ? 0 : 1;
|
|
7412
7418
|
const bm = b.startsWith("mobile_app_") ? 0 : 1;
|
|
7413
7419
|
if (am !== bm) return am - bm;
|
|
7414
7420
|
return a.localeCompare(b);
|
|
7415
|
-
}).map((service) => ({
|
|
7421
|
+
}).map(([service, definition]) => ({
|
|
7416
7422
|
kind: HA_NOTIFICATION_KIND,
|
|
7417
|
-
suggestedName:
|
|
7423
|
+
suggestedName: friendlyServiceName(service, definition, deviceNames),
|
|
7418
7424
|
config: {
|
|
7419
7425
|
service,
|
|
7420
7426
|
...brokerId !== void 0 ? { brokerId } : {}
|
|
7421
7427
|
}
|
|
7422
7428
|
}));
|
|
7423
7429
|
}
|
|
7430
|
+
function nonEmptyText(value) {
|
|
7431
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
7432
|
+
}
|
|
7433
|
+
/** `alexa_media_echo` -> `Alexa Media Echo`. */
|
|
7434
|
+
function prettifyServiceId(service) {
|
|
7435
|
+
return service.split("_").filter((word) => word.length > 0).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
7436
|
+
}
|
|
7437
|
+
/**
|
|
7438
|
+
* The name an operator recognises: the device name for a mobile app, else the
|
|
7439
|
+
* service's own `name`, else its `description`, else the prettified id.
|
|
7440
|
+
*/
|
|
7441
|
+
function friendlyServiceName(service, definition, deviceNames) {
|
|
7442
|
+
const device = deviceNames?.get(service);
|
|
7443
|
+
if (device !== void 0) return device;
|
|
7444
|
+
if (typeof definition === "object" && definition !== null) {
|
|
7445
|
+
const fields = { ...definition };
|
|
7446
|
+
const name = nonEmptyText(fields["name"]);
|
|
7447
|
+
if (name !== void 0) return name;
|
|
7448
|
+
const description = nonEmptyText(fields["description"]);
|
|
7449
|
+
if (description !== void 0) return description;
|
|
7450
|
+
}
|
|
7451
|
+
return prettifyServiceId(service);
|
|
7452
|
+
}
|
|
7453
|
+
/** HA's slug of a device name, as it appears in `mobile_app_<slug>`. */
|
|
7454
|
+
function slugifyDeviceName(name) {
|
|
7455
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
7456
|
+
}
|
|
7457
|
+
/**
|
|
7458
|
+
* `mobile_app_<slug>` -> device name, read from a `config/device_registry/list`
|
|
7459
|
+
* reply. Only devices of the mobile_app integration count; the name the user
|
|
7460
|
+
* gave wins over the one the app reported.
|
|
7461
|
+
*/
|
|
7462
|
+
function mobileAppDeviceNames(registry) {
|
|
7463
|
+
const names = /* @__PURE__ */ new Map();
|
|
7464
|
+
if (!Array.isArray(registry)) return names;
|
|
7465
|
+
for (const entry of registry) {
|
|
7466
|
+
if (typeof entry !== "object" || entry === null) continue;
|
|
7467
|
+
const device = { ...entry };
|
|
7468
|
+
const identifiers = device["identifiers"];
|
|
7469
|
+
if (!(Array.isArray(identifiers) && identifiers.some((pair) => Array.isArray(pair) && pair[0] === "mobile_app"))) continue;
|
|
7470
|
+
const name = nonEmptyText(device["name_by_user"]) ?? nonEmptyText(device["name"]);
|
|
7471
|
+
if (name === void 0) continue;
|
|
7472
|
+
names.set(`mobile_app_${slugifyDeviceName(name)}`, name);
|
|
7473
|
+
}
|
|
7474
|
+
return names;
|
|
7475
|
+
}
|
|
7424
7476
|
/**
|
|
7425
7477
|
* CRUD over the `ha-notification-targets` record kind.
|
|
7426
7478
|
*
|
|
@@ -7442,7 +7494,7 @@ var HaTargetStore = class HaTargetStore {
|
|
|
7442
7494
|
const page = await this.kind.query({ limit: 1e3 });
|
|
7443
7495
|
const out = [];
|
|
7444
7496
|
for (const record of page.records) {
|
|
7445
|
-
const parsed =
|
|
7497
|
+
const parsed = require_ha_broker_source.TargetSchema.safeParse({
|
|
7446
7498
|
id: record.id,
|
|
7447
7499
|
...record.data
|
|
7448
7500
|
});
|
|
@@ -7453,7 +7505,7 @@ var HaTargetStore = class HaTargetStore {
|
|
|
7453
7505
|
async getById(id) {
|
|
7454
7506
|
const row = await this.kind.get(id);
|
|
7455
7507
|
if (row === null) return null;
|
|
7456
|
-
const parsed =
|
|
7508
|
+
const parsed = require_ha_broker_source.TargetSchema.safeParse({
|
|
7457
7509
|
id: row.id,
|
|
7458
7510
|
...row.data
|
|
7459
7511
|
});
|
|
@@ -7514,7 +7566,7 @@ function createHaNotificationOutputProvider(deps) {
|
|
|
7514
7566
|
}
|
|
7515
7567
|
/** Degrade → build → publish. NEVER throws through the cap. */
|
|
7516
7568
|
async function dispatch(target, notification) {
|
|
7517
|
-
const prepared =
|
|
7569
|
+
const prepared = require_ha_broker_source.prepareNotification(descriptor.caps, notification);
|
|
7518
7570
|
const service = readService(target.config);
|
|
7519
7571
|
if (!service) return {
|
|
7520
7572
|
success: false,
|
|
@@ -7538,11 +7590,11 @@ function createHaNotificationOutputProvider(deps) {
|
|
|
7538
7590
|
logger?.warn("ha notify publish failed", { meta: {
|
|
7539
7591
|
brokerId,
|
|
7540
7592
|
service,
|
|
7541
|
-
error:
|
|
7593
|
+
error: require_ha_broker_source.errMsg(err)
|
|
7542
7594
|
} });
|
|
7543
7595
|
return {
|
|
7544
7596
|
success: false,
|
|
7545
|
-
error:
|
|
7597
|
+
error: require_ha_broker_source.errMsg(err),
|
|
7546
7598
|
renderedAs: prepared.renderedAs
|
|
7547
7599
|
};
|
|
7548
7600
|
}
|
|
@@ -7574,16 +7626,28 @@ function createHaNotificationOutputProvider(deps) {
|
|
|
7574
7626
|
},
|
|
7575
7627
|
discoverTargets: async ({ kind, config }) => {
|
|
7576
7628
|
if (kind !== "homeassistant") return [];
|
|
7629
|
+
const deviceNamesOf = async (brokerId) => {
|
|
7630
|
+
if (deps.listDevices === void 0) return /* @__PURE__ */ new Map();
|
|
7631
|
+
try {
|
|
7632
|
+
return mobileAppDeviceNames(await deps.listDevices(brokerId));
|
|
7633
|
+
} catch (err) {
|
|
7634
|
+
logger?.warn("ha device registry read failed; naming services from their ids", { meta: {
|
|
7635
|
+
brokerId,
|
|
7636
|
+
error: require_ha_broker_source.errMsg(err)
|
|
7637
|
+
} });
|
|
7638
|
+
return /* @__PURE__ */ new Map();
|
|
7639
|
+
}
|
|
7640
|
+
};
|
|
7577
7641
|
const explicit = config ? readBrokerId(config) : void 0;
|
|
7578
7642
|
const brokerIds = explicit ? [explicit] : [...deps.listBrokerIds()];
|
|
7579
7643
|
const out = [];
|
|
7580
7644
|
for (const brokerId of brokerIds) try {
|
|
7581
7645
|
const result = await deps.getServices(brokerId);
|
|
7582
|
-
out.push(...parseNotifyServices(result, brokerId));
|
|
7646
|
+
out.push(...parseNotifyServices(result, brokerId, await deviceNamesOf(brokerId)));
|
|
7583
7647
|
} catch (err) {
|
|
7584
7648
|
logger?.warn("ha get_services discovery failed", { meta: {
|
|
7585
7649
|
brokerId,
|
|
7586
|
-
error:
|
|
7650
|
+
error: require_ha_broker_source.errMsg(err)
|
|
7587
7651
|
} });
|
|
7588
7652
|
}
|
|
7589
7653
|
return out;
|
|
@@ -7661,7 +7725,7 @@ var HaBrokerStore = class HaBrokerStore {
|
|
|
7661
7725
|
const resolved = await this.kind.getResolved(record.id);
|
|
7662
7726
|
if (resolved !== null) data = resolved.data;
|
|
7663
7727
|
} catch (err) {
|
|
7664
|
-
if (!(err instanceof
|
|
7728
|
+
if (!(err instanceof require_ha_broker_source.RecordSecretUnavailableError)) throw err;
|
|
7665
7729
|
}
|
|
7666
7730
|
const entry = rowToEntry(record.id, data);
|
|
7667
7731
|
if (entry !== null) out.push(entry);
|
|
@@ -7674,7 +7738,7 @@ var HaBrokerStore = class HaBrokerStore {
|
|
|
7674
7738
|
if (row === null) return null;
|
|
7675
7739
|
return rowToEntry(row.id, row.data);
|
|
7676
7740
|
} catch (err) {
|
|
7677
|
-
if (err instanceof
|
|
7741
|
+
if (err instanceof require_ha_broker_source.RecordSecretUnavailableError) return null;
|
|
7678
7742
|
throw err;
|
|
7679
7743
|
}
|
|
7680
7744
|
}
|
|
@@ -8036,7 +8100,7 @@ function entityToStandaloneCandidate(entity, alreadyAdopted) {
|
|
|
8036
8100
|
return {
|
|
8037
8101
|
childNativeId: entity.entityId,
|
|
8038
8102
|
name: entity.name,
|
|
8039
|
-
type: entity.mappedTo?.deviceType ??
|
|
8103
|
+
type: entity.mappedTo?.deviceType ?? require_ha_broker_source.DeviceType.Generic,
|
|
8040
8104
|
status: entityStatus(entity.state),
|
|
8041
8105
|
metadata: entity.area !== null ? { externalLocation: entity.area } : {},
|
|
8042
8106
|
alreadyAdopted,
|
|
@@ -8171,7 +8235,7 @@ function readPersistedStandaloneSpec(device) {
|
|
|
8171
8235
|
* adoption-proof source field), so it is projected directly here, mirroring the
|
|
8172
8236
|
* Container's `EnumSensorDateTimeFormatSchema.safeParse` guard. */
|
|
8173
8237
|
function readDateTimeFormat(config) {
|
|
8174
|
-
const parsed =
|
|
8238
|
+
const parsed = require_ha_broker_source.EnumSensorDateTimeFormatSchema.safeParse(config["dateTimeFormat"]);
|
|
8175
8239
|
return parsed.success ? parsed.data : void 0;
|
|
8176
8240
|
}
|
|
8177
8241
|
/** Flatten a live device's config into a plain blob for `readHaSource`. */
|
|
@@ -8338,12 +8402,12 @@ var DEFAULT_CONFIG = {
|
|
|
8338
8402
|
* …) and route HA state pushes into runtime-state slices + cap
|
|
8339
8403
|
* mutations into HA call_service.
|
|
8340
8404
|
*/
|
|
8341
|
-
var HaProviderAddon = class HaProviderAddon extends
|
|
8405
|
+
var HaProviderAddon = class HaProviderAddon extends require_ha_broker_source.BaseDeviceProvider {
|
|
8342
8406
|
addonId = "provider-homeassistant";
|
|
8343
8407
|
providerName = "Home Assistant";
|
|
8344
8408
|
deviceClasses = {
|
|
8345
|
-
[
|
|
8346
|
-
[
|
|
8409
|
+
[require_ha_broker_source.DeviceType.Container]: HaContainerDevice,
|
|
8410
|
+
[require_ha_broker_source.DeviceType.EventEmitter]: HaEventBusDevice
|
|
8347
8411
|
};
|
|
8348
8412
|
async onGetCreationSchema(_type) {
|
|
8349
8413
|
return null;
|
|
@@ -8403,23 +8467,23 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8403
8467
|
this.subscribeIntegrationLifecycle();
|
|
8404
8468
|
return [
|
|
8405
8469
|
{
|
|
8406
|
-
capability:
|
|
8470
|
+
capability: require_ha_broker_source.brokerCapability,
|
|
8407
8471
|
provider: this.buildBrokerProvider()
|
|
8408
8472
|
},
|
|
8409
8473
|
{
|
|
8410
|
-
capability:
|
|
8474
|
+
capability: require_ha_broker_source.deviceAdoptionCapability,
|
|
8411
8475
|
provider: this.buildAdoptionProvider()
|
|
8412
8476
|
},
|
|
8413
8477
|
{
|
|
8414
|
-
capability:
|
|
8478
|
+
capability: require_ha_broker_source.notificationOutputCapability,
|
|
8415
8479
|
provider: await this.buildNotificationOutputProvider()
|
|
8416
8480
|
},
|
|
8417
8481
|
{
|
|
8418
|
-
capability:
|
|
8482
|
+
capability: require_ha_broker_source.addonRoutesCapability,
|
|
8419
8483
|
provider: createHaIconRouteProvider()
|
|
8420
8484
|
},
|
|
8421
8485
|
{
|
|
8422
|
-
capability:
|
|
8486
|
+
capability: require_ha_broker_source.calendarSourceCapability,
|
|
8423
8487
|
provider: createHaCalendarSource({
|
|
8424
8488
|
brokers: this.requireRegistry(),
|
|
8425
8489
|
logger: this.ctx.logger.child("calendar-source"),
|
|
@@ -8448,6 +8512,11 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8448
8512
|
if (!manager) throw new Error(`ha-broker '${brokerId}' not found`);
|
|
8449
8513
|
return manager.sendMessage({ type: "get_services" });
|
|
8450
8514
|
},
|
|
8515
|
+
listDevices: async (brokerId) => {
|
|
8516
|
+
const manager = this.requireRegistry().getManager(brokerId);
|
|
8517
|
+
if (!manager) throw new Error(`ha-broker '${brokerId}' not found`);
|
|
8518
|
+
return manager.sendMessage({ type: "config/device_registry/list" });
|
|
8519
|
+
},
|
|
8451
8520
|
listBrokerIds: () => this.activeBrokers.map((b) => b.id),
|
|
8452
8521
|
logger: this.ctx.logger.child("notification-output")
|
|
8453
8522
|
});
|
|
@@ -8535,7 +8604,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8535
8604
|
integrationCount: haIntegrations.length
|
|
8536
8605
|
} });
|
|
8537
8606
|
} catch (err) {
|
|
8538
|
-
this.ctx.logger.warn("integration→broker reconcile failed", { meta: { error:
|
|
8607
|
+
this.ctx.logger.warn("integration→broker reconcile failed", { meta: { error: require_ha_broker_source.errMsg(err) } });
|
|
8539
8608
|
}
|
|
8540
8609
|
}
|
|
8541
8610
|
subscribeIntegrationLifecycle() {
|
|
@@ -8596,7 +8665,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8596
8665
|
try {
|
|
8597
8666
|
await this.registry?.shutdown();
|
|
8598
8667
|
} catch (err) {
|
|
8599
|
-
this.ctx.logger.warn("ha provider shutdown error", { meta: { error:
|
|
8668
|
+
this.ctx.logger.warn("ha provider shutdown error", { meta: { error: require_ha_broker_source.errMsg(err) } });
|
|
8600
8669
|
}
|
|
8601
8670
|
this.registry = null;
|
|
8602
8671
|
await super.onShutdown();
|
|
@@ -8628,7 +8697,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8628
8697
|
} catch (err) {
|
|
8629
8698
|
this.ctx.logger.warn("ha onConfigChanged: removeEntry failed", { meta: {
|
|
8630
8699
|
brokerId: liveId,
|
|
8631
|
-
error:
|
|
8700
|
+
error: require_ha_broker_source.errMsg(err)
|
|
8632
8701
|
} });
|
|
8633
8702
|
}
|
|
8634
8703
|
for (const entry of persisted) {
|
|
@@ -8642,7 +8711,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8642
8711
|
} catch (err) {
|
|
8643
8712
|
this.ctx.logger.warn("ha onConfigChanged: updateEntry failed", { meta: {
|
|
8644
8713
|
brokerId: entry.id,
|
|
8645
|
-
error:
|
|
8714
|
+
error: require_ha_broker_source.errMsg(err)
|
|
8646
8715
|
} });
|
|
8647
8716
|
}
|
|
8648
8717
|
continue;
|
|
@@ -8663,7 +8732,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8663
8732
|
} catch (err) {
|
|
8664
8733
|
this.ctx.logger.warn("ha onConfigChanged: failed to start new broker", { meta: {
|
|
8665
8734
|
brokerName: entry.name,
|
|
8666
|
-
error:
|
|
8735
|
+
error: require_ha_broker_source.errMsg(err)
|
|
8667
8736
|
} });
|
|
8668
8737
|
}
|
|
8669
8738
|
}
|
|
@@ -8813,7 +8882,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8813
8882
|
const refreshedAt = Date.now();
|
|
8814
8883
|
if (lastDiscoveryAt === null || refreshedAt > lastDiscoveryAt) lastDiscoveryAt = refreshedAt;
|
|
8815
8884
|
} catch (err) {
|
|
8816
|
-
lastError =
|
|
8885
|
+
lastError = require_ha_broker_source.errMsg(err);
|
|
8817
8886
|
}
|
|
8818
8887
|
const adoptedCount = (await this.ctx.kernel.devices.getAll()).filter((d) => d.parentDeviceId === null && String(d.config.get("system") ?? "") === "homeassistant").length;
|
|
8819
8888
|
return {
|
|
@@ -8959,7 +9028,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8959
9028
|
name: deviceName
|
|
8960
9029
|
};
|
|
8961
9030
|
const summary = await this.createDevice({
|
|
8962
|
-
type:
|
|
9031
|
+
type: require_ha_broker_source.DeviceType.Container,
|
|
8963
9032
|
config: containerConfig
|
|
8964
9033
|
});
|
|
8965
9034
|
const accessoryDeviceIds = (await this.ctx.kernel.devices.getChildren(summary.id)).map((c) => c.id);
|
|
@@ -8989,7 +9058,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
8989
9058
|
meta: {
|
|
8990
9059
|
brokerId,
|
|
8991
9060
|
haDeviceId,
|
|
8992
|
-
error:
|
|
9061
|
+
error: require_ha_broker_source.errMsg(err)
|
|
8993
9062
|
}
|
|
8994
9063
|
});
|
|
8995
9064
|
}
|
|
@@ -9136,7 +9205,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9136
9205
|
meta: {
|
|
9137
9206
|
brokerId,
|
|
9138
9207
|
entityId,
|
|
9139
|
-
error:
|
|
9208
|
+
error: require_ha_broker_source.errMsg(err)
|
|
9140
9209
|
}
|
|
9141
9210
|
});
|
|
9142
9211
|
}
|
|
@@ -9157,7 +9226,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9157
9226
|
*/
|
|
9158
9227
|
async assignImportedLocation(deviceId, externalLocation, knownLocations) {
|
|
9159
9228
|
try {
|
|
9160
|
-
const match =
|
|
9229
|
+
const match = require_ha_broker_source.bestLocationMatch(externalLocation, knownLocations);
|
|
9161
9230
|
const name = match ?? externalLocation;
|
|
9162
9231
|
let locations = knownLocations;
|
|
9163
9232
|
if (match === null) {
|
|
@@ -9173,7 +9242,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9173
9242
|
this.ctx.logger.warn("ha-adoption: location import failed (non-fatal)", { meta: {
|
|
9174
9243
|
deviceId,
|
|
9175
9244
|
externalLocation,
|
|
9176
|
-
error:
|
|
9245
|
+
error: require_ha_broker_source.errMsg(err)
|
|
9177
9246
|
} });
|
|
9178
9247
|
return knownLocations;
|
|
9179
9248
|
}
|
|
@@ -9374,7 +9443,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9374
9443
|
} catch (err) {
|
|
9375
9444
|
this.ctx.logger.warn("ha bus-event aggregator ensure failed", { meta: {
|
|
9376
9445
|
brokerId,
|
|
9377
|
-
error:
|
|
9446
|
+
error: require_ha_broker_source.errMsg(err)
|
|
9378
9447
|
} });
|
|
9379
9448
|
}
|
|
9380
9449
|
await reconcileBroker(brokerId, {
|
|
@@ -9384,7 +9453,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9384
9453
|
onFetchError: (id, error) => {
|
|
9385
9454
|
this.ctx.logger.warn("ha re-sync: inventory fetch failed", { meta: {
|
|
9386
9455
|
brokerId: id,
|
|
9387
|
-
error:
|
|
9456
|
+
error: require_ha_broker_source.errMsg(error)
|
|
9388
9457
|
} });
|
|
9389
9458
|
}
|
|
9390
9459
|
});
|
|
@@ -9422,7 +9491,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9422
9491
|
meta: {
|
|
9423
9492
|
brokerId,
|
|
9424
9493
|
haDeviceId,
|
|
9425
|
-
error:
|
|
9494
|
+
error: require_ha_broker_source.errMsg(err)
|
|
9426
9495
|
}
|
|
9427
9496
|
});
|
|
9428
9497
|
}
|
|
@@ -9467,7 +9536,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9467
9536
|
tags: { deviceId: action.deviceId },
|
|
9468
9537
|
meta: {
|
|
9469
9538
|
brokerId,
|
|
9470
|
-
error:
|
|
9539
|
+
error: require_ha_broker_source.errMsg(err)
|
|
9471
9540
|
}
|
|
9472
9541
|
});
|
|
9473
9542
|
}
|
|
@@ -9548,7 +9617,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9548
9617
|
brokerId,
|
|
9549
9618
|
kind: "event-bus"
|
|
9550
9619
|
}, null, {
|
|
9551
|
-
type:
|
|
9620
|
+
type: require_ha_broker_source.DeviceType.EventEmitter,
|
|
9552
9621
|
name: "Home Assistant Events"
|
|
9553
9622
|
});
|
|
9554
9623
|
this.eventBusDeviceIds.set(brokerId, device.id);
|
|
@@ -9578,7 +9647,7 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
9578
9647
|
this.ctx.logger.debug("ha bus-event dropped — aggregator not ready", { meta: {
|
|
9579
9648
|
brokerId,
|
|
9580
9649
|
eventType: ev.eventType,
|
|
9581
|
-
error:
|
|
9650
|
+
error: require_ha_broker_source.errMsg(err)
|
|
9582
9651
|
} });
|
|
9583
9652
|
return;
|
|
9584
9653
|
}
|