@camstack/addon-pipeline 1.2.629 → 1.2.631
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 +10 -1
- package/README.md +39 -20
- package/dist/audio-analyzer/index.js +3 -3
- package/dist/audio-analyzer/index.mjs +3 -3
- package/dist/{custom-model-catalog-DyFqiWQw.js → custom-model-catalog-5IT-gwL2.js} +2 -2
- package/dist/{custom-model-catalog--z5qDAbz.mjs → custom-model-catalog-DLv2FLul.mjs} +2 -2
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-vvIUo4Fg.js → dist-CVvwej3J.js} +541 -45
- package/dist/{dist-DkFeDO1Z.mjs → dist-DV6W_qKY.mjs} +541 -45
- package/dist/{model-catalogs-DcAtdzQX.mjs → model-catalogs-CI9KoY4D.mjs} +1 -1
- package/dist/{model-catalogs-dHtp4VIV.js → model-catalogs-lWWyJZqw.js} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-j-hM0LYt.js → node-BQ7P2No5.js} +1 -1
- package/dist/{node-CT-ETMWK.mjs → node-KEh_tmT2.mjs} +1 -1
- package/dist/pipeline-runner/index.js +3 -3
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/{process-memory-B9lUUQZw.js → process-memory-C-3bSKF5.js} +1 -1
- package/dist/{process-memory-BwZIeAKw.mjs → process-memory-ChQO96Xb.mjs} +1 -1
- package/dist/recorder/index.js +2 -2
- package/dist/recorder/index.mjs +2 -2
- package/dist/{segment-demux-js-BCBpOp5j.js → segment-demux-js-8YepQCG3.js} +1 -1
- package/dist/{segment-demux-js-CW7aiIml.mjs → segment-demux-js-Dy75tkrR.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DUUHEAPV.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CKN6MEA_.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BPnizAbp.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BL5-HIQd.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-BiqKaq23.mjs → hostInit-BqjKmOsK.mjs} +3 -3
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +3 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BQMKjVwR.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Ca0Qmh7u.mjs +0 -26
|
@@ -5575,7 +5575,7 @@ var ZodIssueCode = {
|
|
|
5575
5575
|
var ZodFirstPartyTypeKind;
|
|
5576
5576
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5577
5577
|
//#endregion
|
|
5578
|
-
//#region ../types/dist/sleep
|
|
5578
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5579
5579
|
/**
|
|
5580
5580
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5581
5581
|
* window to float samples (D455).
|
|
@@ -9107,6 +9107,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9107
9107
|
"filesystem-browse",
|
|
9108
9108
|
"flood",
|
|
9109
9109
|
"gas",
|
|
9110
|
+
"group-active",
|
|
9110
9111
|
"group-commands",
|
|
9111
9112
|
"group-status",
|
|
9112
9113
|
"heating-valve",
|
|
@@ -9129,6 +9130,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9129
9130
|
"login-method",
|
|
9130
9131
|
"media-player",
|
|
9131
9132
|
"mesh-network",
|
|
9133
|
+
"meter",
|
|
9132
9134
|
"metrics-provider",
|
|
9133
9135
|
"model-convert",
|
|
9134
9136
|
"model-distributor",
|
|
@@ -9927,6 +9929,10 @@ Object.freeze({
|
|
|
9927
9929
|
"path": "detected",
|
|
9928
9930
|
"valueType": "boolean"
|
|
9929
9931
|
}],
|
|
9932
|
+
"group-active": [{
|
|
9933
|
+
"path": "active",
|
|
9934
|
+
"valueType": "boolean"
|
|
9935
|
+
}],
|
|
9930
9936
|
"group-status": [
|
|
9931
9937
|
{
|
|
9932
9938
|
"path": "included",
|
|
@@ -10186,6 +10192,10 @@ Object.freeze({
|
|
|
10186
10192
|
]
|
|
10187
10193
|
}
|
|
10188
10194
|
],
|
|
10195
|
+
"meter": [{
|
|
10196
|
+
"path": "value",
|
|
10197
|
+
"valueType": "number"
|
|
10198
|
+
}],
|
|
10189
10199
|
"motion": [
|
|
10190
10200
|
{
|
|
10191
10201
|
"path": "detected",
|
|
@@ -11081,7 +11091,7 @@ function sleep(ms) {
|
|
|
11081
11091
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
11082
11092
|
}
|
|
11083
11093
|
//#endregion
|
|
11084
|
-
//#region ../types/dist/err-msg-
|
|
11094
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
11085
11095
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
11086
11096
|
DeviceType["Camera"] = "camera";
|
|
11087
11097
|
DeviceType["Hub"] = "hub";
|
|
@@ -11175,8 +11185,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
11175
11185
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
11176
11186
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
11177
11187
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
11178
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
11188
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
11189
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
11179
11190
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
11191
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
11192
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
11193
|
+
DeviceType["Washer"] = "washer";
|
|
11194
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
11195
|
+
DeviceType["Dryer"] = "dryer";
|
|
11180
11196
|
return DeviceType;
|
|
11181
11197
|
}({});
|
|
11182
11198
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -11434,7 +11450,7 @@ function errMsg(err) {
|
|
|
11434
11450
|
return String(err);
|
|
11435
11451
|
}
|
|
11436
11452
|
//#endregion
|
|
11437
|
-
//#region ../types/dist/composition-
|
|
11453
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
11438
11454
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
11439
11455
|
opus: "libopus",
|
|
11440
11456
|
aac: "aac",
|
|
@@ -12585,6 +12601,13 @@ var table = {
|
|
|
12585
12601
|
apply: () => {
|
|
12586
12602
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
12587
12603
|
}
|
|
12604
|
+
},
|
|
12605
|
+
schmitt: {
|
|
12606
|
+
minArgs: 3,
|
|
12607
|
+
maxArgs: 5,
|
|
12608
|
+
apply: () => {
|
|
12609
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
12610
|
+
}
|
|
12588
12611
|
}
|
|
12589
12612
|
};
|
|
12590
12613
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -13026,6 +13049,99 @@ function validateExpressionSource(src) {
|
|
|
13026
13049
|
return null;
|
|
13027
13050
|
}
|
|
13028
13051
|
/**
|
|
13052
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
13053
|
+
*
|
|
13054
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
13055
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
13056
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
13057
|
+
*
|
|
13058
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
13059
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
13060
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
13061
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
13062
|
+
* can move later without moving the others.
|
|
13063
|
+
*/
|
|
13064
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
13065
|
+
var APPLIANCE_KINDS = [
|
|
13066
|
+
"washer",
|
|
13067
|
+
"dryer",
|
|
13068
|
+
"dishwasher"
|
|
13069
|
+
];
|
|
13070
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
13071
|
+
/**
|
|
13072
|
+
* Statistics and integrals over a history read (D944).
|
|
13073
|
+
*
|
|
13074
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
13075
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
13076
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
13077
|
+
* as zero. A truncated read is not published.
|
|
13078
|
+
*/
|
|
13079
|
+
var STATISTIC_STATS = [
|
|
13080
|
+
"min",
|
|
13081
|
+
"max",
|
|
13082
|
+
"mean",
|
|
13083
|
+
"sum",
|
|
13084
|
+
"count",
|
|
13085
|
+
"change"
|
|
13086
|
+
];
|
|
13087
|
+
/**
|
|
13088
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
13089
|
+
*
|
|
13090
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
13091
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
13092
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
13093
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
13094
|
+
*/
|
|
13095
|
+
var MINUTE_MS = 6e4;
|
|
13096
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
13097
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
13098
|
+
var ROLLING_SPANS = [
|
|
13099
|
+
"1h",
|
|
13100
|
+
"24h",
|
|
13101
|
+
"2d",
|
|
13102
|
+
"7d",
|
|
13103
|
+
"30d",
|
|
13104
|
+
"custom"
|
|
13105
|
+
];
|
|
13106
|
+
var CALENDAR_PERIODS = [
|
|
13107
|
+
"today",
|
|
13108
|
+
"yesterday",
|
|
13109
|
+
"this-week",
|
|
13110
|
+
"this-month"
|
|
13111
|
+
];
|
|
13112
|
+
var RESET_PERIODS = [
|
|
13113
|
+
"never",
|
|
13114
|
+
"daily",
|
|
13115
|
+
"weekly",
|
|
13116
|
+
"monthly"
|
|
13117
|
+
];
|
|
13118
|
+
5 * MINUTE_MS;
|
|
13119
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
13120
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
13121
|
+
var rollingWindowObject = object({
|
|
13122
|
+
kind: literal("rolling"),
|
|
13123
|
+
span: _enum(ROLLING_SPANS),
|
|
13124
|
+
customMinutes: number().int().min(5).optional()
|
|
13125
|
+
}).check((payload) => {
|
|
13126
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
13127
|
+
code: "custom",
|
|
13128
|
+
message: "a custom range needs a duration in minutes",
|
|
13129
|
+
path: ["customMinutes"],
|
|
13130
|
+
input: payload.value
|
|
13131
|
+
});
|
|
13132
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
13133
|
+
code: "custom",
|
|
13134
|
+
message: "only a custom range carries a duration",
|
|
13135
|
+
path: ["customMinutes"],
|
|
13136
|
+
input: payload.value
|
|
13137
|
+
});
|
|
13138
|
+
});
|
|
13139
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
13140
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
13141
|
+
kind: literal("calendar"),
|
|
13142
|
+
period: _enum(CALENDAR_PERIODS)
|
|
13143
|
+
})]);
|
|
13144
|
+
/**
|
|
13029
13145
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
13030
13146
|
* id. Split out so helper schemas can name it without a cycle through
|
|
13031
13147
|
* `composition.ts` (D659).
|
|
@@ -13051,7 +13167,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
13051
13167
|
"occupancy",
|
|
13052
13168
|
"binary",
|
|
13053
13169
|
"switch",
|
|
13054
|
-
"light"
|
|
13170
|
+
"light",
|
|
13171
|
+
"fan",
|
|
13172
|
+
"cover",
|
|
13173
|
+
"valve",
|
|
13174
|
+
"lock",
|
|
13175
|
+
"media-player",
|
|
13176
|
+
"climate"
|
|
13055
13177
|
];
|
|
13056
13178
|
var NUMERIC_AGGREGATES = [
|
|
13057
13179
|
"mean",
|
|
@@ -13081,14 +13203,73 @@ var HelperMemberSchema = object({
|
|
|
13081
13203
|
cap: string().min(1),
|
|
13082
13204
|
fieldPath: string().min(1)
|
|
13083
13205
|
});
|
|
13084
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13206
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
13207
|
+
object({
|
|
13208
|
+
kind: literal("group"),
|
|
13209
|
+
templateId: GroupTemplateIdSchema,
|
|
13210
|
+
aggregate: AggregateReducerSchema,
|
|
13211
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
13212
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
13213
|
+
active: ActiveCriterionSchema.optional()
|
|
13214
|
+
}),
|
|
13215
|
+
object({
|
|
13216
|
+
kind: literal("appliance"),
|
|
13217
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
13218
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
13219
|
+
thresholdWatts: number().positive(),
|
|
13220
|
+
startDwellMs: number().int().nonnegative(),
|
|
13221
|
+
stopDwellMs: number().int().nonnegative(),
|
|
13222
|
+
member: HelperMemberSchema
|
|
13223
|
+
}),
|
|
13224
|
+
object({
|
|
13225
|
+
kind: literal("statistic"),
|
|
13226
|
+
stat: _enum(STATISTIC_STATS),
|
|
13227
|
+
window: StatisticWindowSchema,
|
|
13228
|
+
source: HelperMemberSchema
|
|
13229
|
+
}),
|
|
13230
|
+
object({
|
|
13231
|
+
kind: literal("integral"),
|
|
13232
|
+
reset: _enum(RESET_PERIODS),
|
|
13233
|
+
output: _enum(["energy", "meter"]),
|
|
13234
|
+
source: HelperMemberSchema
|
|
13235
|
+
}),
|
|
13236
|
+
object({
|
|
13237
|
+
kind: literal("threshold"),
|
|
13238
|
+
source: HelperMemberSchema,
|
|
13239
|
+
high: number(),
|
|
13240
|
+
low: number(),
|
|
13241
|
+
onForMs: number().int().nonnegative(),
|
|
13242
|
+
offForMs: number().int().nonnegative()
|
|
13243
|
+
}),
|
|
13244
|
+
object({
|
|
13245
|
+
kind: literal("arithmetic"),
|
|
13246
|
+
op: _enum([
|
|
13247
|
+
"sum",
|
|
13248
|
+
"difference",
|
|
13249
|
+
"ratio"
|
|
13250
|
+
]),
|
|
13251
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
13252
|
+
}),
|
|
13253
|
+
object({
|
|
13254
|
+
kind: literal("expression"),
|
|
13255
|
+
expr: string().min(1),
|
|
13256
|
+
inputs: array(object({
|
|
13257
|
+
name: string().min(1),
|
|
13258
|
+
member: HelperMemberSchema
|
|
13259
|
+
})).min(1).max(64),
|
|
13260
|
+
output: _enum(["number", "boolean"])
|
|
13261
|
+
}),
|
|
13262
|
+
object({
|
|
13263
|
+
kind: literal("derivative"),
|
|
13264
|
+
window: RollingWindowSchema,
|
|
13265
|
+
per: _enum([
|
|
13266
|
+
"second",
|
|
13267
|
+
"minute",
|
|
13268
|
+
"hour"
|
|
13269
|
+
]),
|
|
13270
|
+
source: HelperMemberSchema
|
|
13271
|
+
})
|
|
13272
|
+
]);
|
|
13092
13273
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
13093
13274
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
13094
13275
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -13149,6 +13330,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
13149
13330
|
"all"
|
|
13150
13331
|
]),
|
|
13151
13332
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
13333
|
+
/**
|
|
13334
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
13335
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
13336
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
13337
|
+
*/
|
|
13338
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
13152
13339
|
/** `value` is the reading; the others are the member counts. */
|
|
13153
13340
|
publish: _enum([
|
|
13154
13341
|
"value",
|
|
@@ -13162,6 +13349,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
13162
13349
|
"omit",
|
|
13163
13350
|
"offline"
|
|
13164
13351
|
])
|
|
13352
|
+
}),
|
|
13353
|
+
object({
|
|
13354
|
+
kind: literal("series"),
|
|
13355
|
+
read: CompositionFieldReadSchema,
|
|
13356
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
13357
|
+
publish: _enum([
|
|
13358
|
+
"value",
|
|
13359
|
+
"included",
|
|
13360
|
+
"excluded",
|
|
13361
|
+
"total"
|
|
13362
|
+
]),
|
|
13363
|
+
/**
|
|
13364
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
13365
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
13366
|
+
*/
|
|
13367
|
+
empty: _enum([
|
|
13368
|
+
"null",
|
|
13369
|
+
"omit",
|
|
13370
|
+
"offline"
|
|
13371
|
+
])
|
|
13165
13372
|
})
|
|
13166
13373
|
]);
|
|
13167
13374
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -19795,7 +20002,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
19795
20002
|
*/
|
|
19796
20003
|
interactiveConnectPath: string().min(1).optional(),
|
|
19797
20004
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
19798
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
20005
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
20006
|
+
/**
|
|
20007
|
+
* The kind signs in through a server-held interactive session instead of
|
|
20008
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
20009
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
20010
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
20011
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
20012
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
20013
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
20014
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
20015
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
20016
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
20017
|
+
* offers it as the default path; the fields the session fills are
|
|
20018
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
20019
|
+
*/
|
|
20020
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
19799
20021
|
}))
|
|
19800
20022
|
});
|
|
19801
20023
|
var ListInputSchema = object({
|
|
@@ -21148,7 +21370,8 @@ var CompositionProblemSchema = object({
|
|
|
21148
21370
|
"native-capability-replace",
|
|
21149
21371
|
"mixed-quantity",
|
|
21150
21372
|
"helper-mismatch",
|
|
21151
|
-
"member-constraint"
|
|
21373
|
+
"member-constraint",
|
|
21374
|
+
"retention"
|
|
21152
21375
|
]),
|
|
21153
21376
|
path: string(),
|
|
21154
21377
|
message: string()
|
|
@@ -21382,13 +21605,17 @@ Object.freeze({
|
|
|
21382
21605
|
latchedAt: {
|
|
21383
21606
|
kind: "fixed",
|
|
21384
21607
|
result: ["number", "null"]
|
|
21608
|
+
},
|
|
21609
|
+
schmitt: {
|
|
21610
|
+
kind: "fixed",
|
|
21611
|
+
result: ["boolean", "null"]
|
|
21385
21612
|
}
|
|
21386
21613
|
});
|
|
21387
21614
|
/**
|
|
21388
21615
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
21389
21616
|
* Data, not a form default written into the block.
|
|
21390
21617
|
*/
|
|
21391
|
-
var NOW = {
|
|
21618
|
+
var NOW$2 = {
|
|
21392
21619
|
fieldPath: "lastFetchedAt",
|
|
21393
21620
|
expr: "now"
|
|
21394
21621
|
};
|
|
@@ -21402,6 +21629,8 @@ function numeric(input) {
|
|
|
21402
21629
|
family: "numeric",
|
|
21403
21630
|
deviceType: DeviceType.Sensor,
|
|
21404
21631
|
memberDeviceType: DeviceType.Sensor,
|
|
21632
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
21633
|
+
activeWhen: void 0,
|
|
21405
21634
|
commandCaps: [],
|
|
21406
21635
|
baseUnit: baseUnitOf(input.quantity),
|
|
21407
21636
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -21417,6 +21646,8 @@ function binary(input) {
|
|
|
21417
21646
|
family: "binary",
|
|
21418
21647
|
deviceType: DeviceType.Sensor,
|
|
21419
21648
|
memberDeviceType: DeviceType.Sensor,
|
|
21649
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
21650
|
+
activeWhen: void 0,
|
|
21420
21651
|
commandCaps: [],
|
|
21421
21652
|
quantity: "none",
|
|
21422
21653
|
baseUnit: void 0,
|
|
@@ -21434,7 +21665,7 @@ var GROUP_TEMPLATES = [
|
|
|
21434
21665
|
quantity: "temperature",
|
|
21435
21666
|
defaultAggregate: "mean",
|
|
21436
21667
|
empty: "null",
|
|
21437
|
-
companions: [NOW]
|
|
21668
|
+
companions: [NOW$2]
|
|
21438
21669
|
}),
|
|
21439
21670
|
numeric({
|
|
21440
21671
|
id: "humidity",
|
|
@@ -21445,7 +21676,7 @@ var GROUP_TEMPLATES = [
|
|
|
21445
21676
|
quantity: "humidity",
|
|
21446
21677
|
defaultAggregate: "mean",
|
|
21447
21678
|
empty: "null",
|
|
21448
|
-
companions: [NOW]
|
|
21679
|
+
companions: [NOW$2]
|
|
21449
21680
|
}),
|
|
21450
21681
|
numeric({
|
|
21451
21682
|
id: "pressure",
|
|
@@ -21456,7 +21687,7 @@ var GROUP_TEMPLATES = [
|
|
|
21456
21687
|
quantity: "pressure",
|
|
21457
21688
|
defaultAggregate: "mean",
|
|
21458
21689
|
empty: "null",
|
|
21459
|
-
companions: [NOW]
|
|
21690
|
+
companions: [NOW$2]
|
|
21460
21691
|
}),
|
|
21461
21692
|
numeric({
|
|
21462
21693
|
id: "illuminance",
|
|
@@ -21467,7 +21698,7 @@ var GROUP_TEMPLATES = [
|
|
|
21467
21698
|
quantity: "illuminance",
|
|
21468
21699
|
defaultAggregate: "mean",
|
|
21469
21700
|
empty: "null",
|
|
21470
|
-
companions: [NOW]
|
|
21701
|
+
companions: [NOW$2]
|
|
21471
21702
|
}),
|
|
21472
21703
|
numeric({
|
|
21473
21704
|
id: "power",
|
|
@@ -21478,7 +21709,7 @@ var GROUP_TEMPLATES = [
|
|
|
21478
21709
|
quantity: "power",
|
|
21479
21710
|
defaultAggregate: "sum",
|
|
21480
21711
|
empty: "omit",
|
|
21481
|
-
companions: [NOW]
|
|
21712
|
+
companions: [NOW$2]
|
|
21482
21713
|
}),
|
|
21483
21714
|
numeric({
|
|
21484
21715
|
id: "energy",
|
|
@@ -21489,7 +21720,7 @@ var GROUP_TEMPLATES = [
|
|
|
21489
21720
|
quantity: "energy",
|
|
21490
21721
|
defaultAggregate: "sum",
|
|
21491
21722
|
empty: "omit",
|
|
21492
|
-
companions: [NOW]
|
|
21723
|
+
companions: [NOW$2]
|
|
21493
21724
|
}),
|
|
21494
21725
|
numeric({
|
|
21495
21726
|
id: "battery",
|
|
@@ -21524,7 +21755,7 @@ var GROUP_TEMPLATES = [
|
|
|
21524
21755
|
quantity: "device",
|
|
21525
21756
|
defaultAggregate: "mean",
|
|
21526
21757
|
empty: "null",
|
|
21527
|
-
companions: [NOW]
|
|
21758
|
+
companions: [NOW$2]
|
|
21528
21759
|
}),
|
|
21529
21760
|
binary({
|
|
21530
21761
|
id: "motion",
|
|
@@ -21618,6 +21849,11 @@ var GROUP_TEMPLATES = [
|
|
|
21618
21849
|
summary: "On when at least one switch is on, or when all of them are. Offline and unknown members are left out of that decision, never read as off, and still receive the command.",
|
|
21619
21850
|
deviceType: DeviceType.Switch,
|
|
21620
21851
|
outputCap: "switch",
|
|
21852
|
+
outputField: "on",
|
|
21853
|
+
member: {
|
|
21854
|
+
cap: "switch",
|
|
21855
|
+
fieldPath: "on"
|
|
21856
|
+
},
|
|
21621
21857
|
commandCaps: ["switch"]
|
|
21622
21858
|
}),
|
|
21623
21859
|
actuator({
|
|
@@ -21625,34 +21861,136 @@ var GROUP_TEMPLATES = [
|
|
|
21625
21861
|
summary: "On when at least one light is on, or when all of them are. Brightness and colour are offered only when every member has them. A command is not sent to a member that lacks it.",
|
|
21626
21862
|
deviceType: DeviceType.Light,
|
|
21627
21863
|
outputCap: "switch",
|
|
21864
|
+
outputField: "on",
|
|
21865
|
+
member: {
|
|
21866
|
+
cap: "switch",
|
|
21867
|
+
fieldPath: "on"
|
|
21868
|
+
},
|
|
21628
21869
|
commandCaps: [
|
|
21629
21870
|
"switch",
|
|
21630
21871
|
"brightness",
|
|
21631
21872
|
"color"
|
|
21632
21873
|
]
|
|
21874
|
+
}),
|
|
21875
|
+
actuator({
|
|
21876
|
+
id: "fan",
|
|
21877
|
+
summary: "On when at least one fan is on, or when all of them are. Speed, preset, direction and oscillation are offered only when every fan has them. A command is not sent to a fan that lacks it.",
|
|
21878
|
+
deviceType: DeviceType.Fan,
|
|
21879
|
+
outputCap: "switch",
|
|
21880
|
+
outputField: "on",
|
|
21881
|
+
member: {
|
|
21882
|
+
cap: "switch",
|
|
21883
|
+
fieldPath: "on"
|
|
21884
|
+
},
|
|
21885
|
+
commandCaps: ["switch", "fan-control"]
|
|
21886
|
+
}),
|
|
21887
|
+
actuator({
|
|
21888
|
+
id: "cover",
|
|
21889
|
+
summary: "Open when at least one cover is open or part-open, or only when all of them are. Position and tilt are offered only when every cover has them. A cover that reports nothing is left out, never read as closed.",
|
|
21890
|
+
deviceType: DeviceType.Cover,
|
|
21891
|
+
outputCap: "group-active",
|
|
21892
|
+
outputField: "active",
|
|
21893
|
+
member: {
|
|
21894
|
+
cap: "cover",
|
|
21895
|
+
fieldPath: "state"
|
|
21896
|
+
},
|
|
21897
|
+
activeWhen: [
|
|
21898
|
+
"open",
|
|
21899
|
+
"opening",
|
|
21900
|
+
"stopped"
|
|
21901
|
+
],
|
|
21902
|
+
commandCaps: ["cover"]
|
|
21903
|
+
}),
|
|
21904
|
+
actuator({
|
|
21905
|
+
id: "valve",
|
|
21906
|
+
summary: "Open when at least one valve is open or part-open, or only when all of them are. Position is offered only when every valve has it. A valve that reports nothing is left out, never read as closed.",
|
|
21907
|
+
deviceType: DeviceType.Valve,
|
|
21908
|
+
outputCap: "group-active",
|
|
21909
|
+
outputField: "active",
|
|
21910
|
+
member: {
|
|
21911
|
+
cap: "valve",
|
|
21912
|
+
fieldPath: "state"
|
|
21913
|
+
},
|
|
21914
|
+
activeWhen: [
|
|
21915
|
+
"open",
|
|
21916
|
+
"opening",
|
|
21917
|
+
"stopped"
|
|
21918
|
+
],
|
|
21919
|
+
commandCaps: ["valve"]
|
|
21920
|
+
}),
|
|
21921
|
+
actuator({
|
|
21922
|
+
id: "lock",
|
|
21923
|
+
summary: "Locked when at least one lock is locked, or only when all of them are. A jammed or moving lock is not locked. Locking is one tap; unlocking the group needs a confirmation every time, and nothing is sent without it.",
|
|
21924
|
+
deviceType: DeviceType.Lock,
|
|
21925
|
+
outputCap: "group-active",
|
|
21926
|
+
outputField: "active",
|
|
21927
|
+
member: {
|
|
21928
|
+
cap: "lock-control",
|
|
21929
|
+
fieldPath: "state"
|
|
21930
|
+
},
|
|
21931
|
+
activeWhen: ["locked"],
|
|
21932
|
+
commandCaps: ["lock-control"]
|
|
21933
|
+
}),
|
|
21934
|
+
actuator({
|
|
21935
|
+
id: "media-player",
|
|
21936
|
+
summary: "Playing when at least one player is playing, or only when all of them are. Volume is offered only when every player has it. A player that reports nothing is left out, never read as stopped.",
|
|
21937
|
+
deviceType: DeviceType.MediaPlayer,
|
|
21938
|
+
outputCap: "group-active",
|
|
21939
|
+
outputField: "active",
|
|
21940
|
+
member: {
|
|
21941
|
+
cap: "media-player",
|
|
21942
|
+
fieldPath: "state"
|
|
21943
|
+
},
|
|
21944
|
+
activeWhen: ["playing", "buffering"],
|
|
21945
|
+
commandCaps: ["media-player"]
|
|
21946
|
+
}),
|
|
21947
|
+
actuator({
|
|
21948
|
+
id: "climate",
|
|
21949
|
+
summary: "Running when at least one thermostat or air conditioner is not off, or only when all of them are. Target temperature and fan are offered only when every device has them. A device that reports nothing is left out, never read as off.",
|
|
21950
|
+
deviceType: DeviceType.Thermostat,
|
|
21951
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
21952
|
+
outputCap: "group-active",
|
|
21953
|
+
outputField: "active",
|
|
21954
|
+
member: {
|
|
21955
|
+
cap: "climate-control",
|
|
21956
|
+
fieldPath: "mode"
|
|
21957
|
+
},
|
|
21958
|
+
activeWhen: [
|
|
21959
|
+
"heat",
|
|
21960
|
+
"cool",
|
|
21961
|
+
"auto",
|
|
21962
|
+
"heat_cool",
|
|
21963
|
+
"fan_only",
|
|
21964
|
+
"dry"
|
|
21965
|
+
],
|
|
21966
|
+
commandCaps: ["climate-control"]
|
|
21633
21967
|
})
|
|
21634
21968
|
];
|
|
21635
21969
|
function actuator(input) {
|
|
21636
21970
|
return {
|
|
21637
|
-
|
|
21971
|
+
id: input.id,
|
|
21972
|
+
summary: input.summary,
|
|
21973
|
+
deviceType: input.deviceType,
|
|
21974
|
+
outputCap: input.outputCap,
|
|
21975
|
+
outputField: input.outputField,
|
|
21976
|
+
commandCaps: input.commandCaps,
|
|
21638
21977
|
family: "actuator",
|
|
21639
21978
|
role: void 0,
|
|
21640
21979
|
memberDeviceType: input.deviceType,
|
|
21641
|
-
|
|
21980
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
21981
|
+
activeWhen: input.activeWhen,
|
|
21642
21982
|
quantity: "none",
|
|
21643
21983
|
baseUnit: void 0,
|
|
21644
21984
|
aggregates: BINARY_AGGREGATES,
|
|
21645
21985
|
defaultAggregate: "any",
|
|
21646
21986
|
empty: "offline",
|
|
21647
|
-
accept: [
|
|
21648
|
-
cap: "switch",
|
|
21649
|
-
fieldPath: "on"
|
|
21650
|
-
}],
|
|
21987
|
+
accept: [input.member],
|
|
21651
21988
|
companions: [CHANGED]
|
|
21652
21989
|
};
|
|
21653
21990
|
}
|
|
21654
21991
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
21655
21992
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
21993
|
+
DeviceType.Camera;
|
|
21656
21994
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
21657
21995
|
/**
|
|
21658
21996
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -46786,7 +47124,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
46786
47124
|
});
|
|
46787
47125
|
/**
|
|
46788
47126
|
* Optional, richer endpoint shape returned by providers that expose
|
|
46789
|
-
* MORE than one ingress concurrently (Tailscale
|
|
47127
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
46790
47128
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
46791
47129
|
* the originating provider config (mode + sourcePort) so the
|
|
46792
47130
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -49755,7 +50093,20 @@ var NcRuleInputSchema = object({
|
|
|
49755
50093
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
49756
50094
|
* path does not run Zod defaults.
|
|
49757
50095
|
*/
|
|
49758
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
50096
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
50097
|
+
/**
|
|
50098
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
50099
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
50100
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
50101
|
+
* same mark the Library writes, and records whose notification it was and
|
|
50102
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
50103
|
+
*
|
|
50104
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
50105
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
50106
|
+
* authored before this field meant. An editor turns it off by writing
|
|
50107
|
+
* `false`, so it needs no `clear` key.
|
|
50108
|
+
*/
|
|
50109
|
+
askVerdict: boolean().optional()
|
|
49759
50110
|
});
|
|
49760
50111
|
/**
|
|
49761
50112
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -61059,7 +61410,8 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
61059
61410
|
DeviceType.Switch,
|
|
61060
61411
|
DeviceType.PetFeeder,
|
|
61061
61412
|
DeviceType.Container,
|
|
61062
|
-
DeviceType.Thermostat
|
|
61413
|
+
DeviceType.Thermostat,
|
|
61414
|
+
DeviceType.EventEmitter
|
|
61063
61415
|
];
|
|
61064
61416
|
/** Generic Customize target for the percentage reading (D936). */
|
|
61065
61417
|
var batteryCustomize = {
|
|
@@ -62940,7 +63292,13 @@ results: array(object({
|
|
|
62940
63292
|
/** Ms epoch of the attempt. */
|
|
62941
63293
|
at: number()
|
|
62942
63294
|
})) });
|
|
62943
|
-
DeviceType.Switch, DeviceType.Light;
|
|
63295
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
63296
|
+
object({
|
|
63297
|
+
active: boolean().meta({ label: "Active" }),
|
|
63298
|
+
/** Ms epoch when the slice was last updated. */
|
|
63299
|
+
lastChangedAt: number()
|
|
63300
|
+
});
|
|
63301
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
62944
63302
|
object({
|
|
62945
63303
|
/** Members whose current value entered the aggregate. */
|
|
62946
63304
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -62958,7 +63316,7 @@ object({
|
|
|
62958
63316
|
label: "Members"
|
|
62959
63317
|
}))
|
|
62960
63318
|
});
|
|
62961
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
63319
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
62962
63320
|
object({
|
|
62963
63321
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
62964
63322
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -63865,7 +64223,14 @@ DeviceType.Lock, method(object({
|
|
|
63865
64223
|
auth: "protected"
|
|
63866
64224
|
}), method(object({
|
|
63867
64225
|
deviceId: number().int().nonnegative(),
|
|
63868
|
-
code: string().min(1).optional()
|
|
64226
|
+
code: string().min(1).optional(),
|
|
64227
|
+
/**
|
|
64228
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
64229
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
64230
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
64231
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
64232
|
+
*/
|
|
64233
|
+
confirm: boolean().optional()
|
|
63869
64234
|
}), _void(), {
|
|
63870
64235
|
kind: "mutation",
|
|
63871
64236
|
auth: "protected"
|
|
@@ -63873,6 +64238,11 @@ DeviceType.Lock, method(object({
|
|
|
63873
64238
|
kind: "mutation",
|
|
63874
64239
|
auth: "protected"
|
|
63875
64240
|
});
|
|
64241
|
+
object({
|
|
64242
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
64243
|
+
lastFetchedAt: number()
|
|
64244
|
+
});
|
|
64245
|
+
DeviceType.Sensor;
|
|
63876
64246
|
/**
|
|
63877
64247
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
63878
64248
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -65780,9 +66150,9 @@ object({
|
|
|
65780
66150
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
65781
66151
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
65782
66152
|
/** Voltage in volts. */
|
|
65783
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
66153
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
65784
66154
|
/** Current in amperes. */
|
|
65785
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
66155
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
65786
66156
|
/** Apparent power in volt-amperes. */
|
|
65787
66157
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
65788
66158
|
/** Power factor (0..1) if reported. */
|
|
@@ -65790,7 +66160,23 @@ object({
|
|
|
65790
66160
|
/** Ms epoch when the slice was last updated. */
|
|
65791
66161
|
lastFetchedAt: number()
|
|
65792
66162
|
});
|
|
65793
|
-
|
|
66163
|
+
[
|
|
66164
|
+
DeviceType.Sensor,
|
|
66165
|
+
DeviceType.Switch,
|
|
66166
|
+
DeviceType.Light,
|
|
66167
|
+
DeviceType.Fan,
|
|
66168
|
+
DeviceType.Climate,
|
|
66169
|
+
DeviceType.Thermostat,
|
|
66170
|
+
DeviceType.Humidifier,
|
|
66171
|
+
DeviceType.WaterHeater,
|
|
66172
|
+
DeviceType.MediaPlayer,
|
|
66173
|
+
DeviceType.Washer,
|
|
66174
|
+
DeviceType.Dryer,
|
|
66175
|
+
DeviceType.Dishwasher,
|
|
66176
|
+
DeviceType.Vacuum,
|
|
66177
|
+
DeviceType.LawnMower,
|
|
66178
|
+
DeviceType.PetFeeder
|
|
66179
|
+
].filter((type) => type !== DeviceType.Sensor);
|
|
65794
66180
|
/**
|
|
65795
66181
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
65796
66182
|
* on `DeviceType.Presence`. Read-only — no setters: presence is
|
|
@@ -66237,7 +66623,7 @@ object({
|
|
|
66237
66623
|
phase: string().nullable()
|
|
66238
66624
|
});
|
|
66239
66625
|
Object.values(DeviceType);
|
|
66240
|
-
DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
66626
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
66241
66627
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
|
|
66242
66628
|
kind: "mutation",
|
|
66243
66629
|
auth: "admin"
|
|
@@ -68800,7 +69186,7 @@ object({
|
|
|
68800
69186
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
68801
69187
|
lastChangedAt: number()
|
|
68802
69188
|
});
|
|
68803
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
69189
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
68804
69190
|
deviceId: number(),
|
|
68805
69191
|
on: boolean()
|
|
68806
69192
|
}), _void(), {
|
|
@@ -70532,8 +70918,9 @@ function dominantClipLabels(events) {
|
|
|
70532
70918
|
}
|
|
70533
70919
|
return [...counts.entries()].toSorted((x, y) => y[1] - x[1]).slice(0, 3).map(([name]) => name);
|
|
70534
70920
|
}
|
|
70921
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
70535
70922
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
70536
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
70923
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
70537
70924
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
70538
70925
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
70539
70926
|
new Set(CAP_NAMES);
|
|
@@ -70604,7 +70991,7 @@ function deriveBatteryPresence(input) {
|
|
|
70604
70991
|
const budget = input.unreachableAfterMs ?? 216e5;
|
|
70605
70992
|
return input.nowMs - lastContactAt > budget ? "unreachable" : "sleeping";
|
|
70606
70993
|
}
|
|
70607
|
-
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher;
|
|
70994
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer;
|
|
70608
70995
|
new Set(Object.values(DeviceType));
|
|
70609
70996
|
Object.freeze({
|
|
70610
70997
|
"accessories.getStatus": {
|
|
@@ -73827,6 +74214,13 @@ Object.freeze({
|
|
|
73827
74214
|
access: "view",
|
|
73828
74215
|
role: "viewer"
|
|
73829
74216
|
},
|
|
74217
|
+
"groupActive.getStatus": {
|
|
74218
|
+
capName: "group-active",
|
|
74219
|
+
capScope: "device",
|
|
74220
|
+
addonId: null,
|
|
74221
|
+
access: "view",
|
|
74222
|
+
role: "viewer"
|
|
74223
|
+
},
|
|
73830
74224
|
"groupCommands.getStatus": {
|
|
73831
74225
|
capName: "group-commands",
|
|
73832
74226
|
capScope: "device",
|
|
@@ -74793,6 +75187,13 @@ Object.freeze({
|
|
|
74793
75187
|
access: "create",
|
|
74794
75188
|
role: "admin"
|
|
74795
75189
|
},
|
|
75190
|
+
"meter.getStatus": {
|
|
75191
|
+
capName: "meter",
|
|
75192
|
+
capScope: "device",
|
|
75193
|
+
addonId: null,
|
|
75194
|
+
access: "view",
|
|
75195
|
+
role: "viewer"
|
|
75196
|
+
},
|
|
74796
75197
|
"metricsProvider.collectSnapshot": {
|
|
74797
75198
|
capName: "metrics-provider",
|
|
74798
75199
|
capScope: "system",
|
|
@@ -82891,7 +83292,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
82891
83292
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
82892
83293
|
icon: "square"
|
|
82893
83294
|
}
|
|
82894
|
-
}
|
|
83295
|
+
},
|
|
83296
|
+
overrides: { byType: {
|
|
83297
|
+
[DeviceType.Washer]: {
|
|
83298
|
+
state: { running: {
|
|
83299
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
83300
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
83301
|
+
} },
|
|
83302
|
+
events: {
|
|
83303
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
83304
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
83305
|
+
}
|
|
83306
|
+
},
|
|
83307
|
+
[DeviceType.Dryer]: {
|
|
83308
|
+
state: { running: {
|
|
83309
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
83310
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
83311
|
+
} },
|
|
83312
|
+
events: {
|
|
83313
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
83314
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
83315
|
+
}
|
|
83316
|
+
},
|
|
83317
|
+
[DeviceType.Dishwasher]: {
|
|
83318
|
+
state: { running: {
|
|
83319
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
83320
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
83321
|
+
} },
|
|
83322
|
+
events: {
|
|
83323
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
83324
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
83325
|
+
}
|
|
83326
|
+
}
|
|
83327
|
+
} }
|
|
82895
83328
|
},
|
|
82896
83329
|
update: {
|
|
82897
83330
|
scope: "device",
|
|
@@ -83663,6 +84096,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83663
84096
|
icon: "flame"
|
|
83664
84097
|
}]
|
|
83665
84098
|
},
|
|
84099
|
+
"group-active": {
|
|
84100
|
+
scope: "device",
|
|
84101
|
+
noun: t("Group state", "Stato del gruppo")
|
|
84102
|
+
},
|
|
83666
84103
|
"group-commands": {
|
|
83667
84104
|
scope: "device",
|
|
83668
84105
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -83719,6 +84156,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83719
84156
|
}],
|
|
83720
84157
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
83721
84158
|
},
|
|
84159
|
+
meter: {
|
|
84160
|
+
scope: "device",
|
|
84161
|
+
noun: t("Meter", "Contatore"),
|
|
84162
|
+
state: [{
|
|
84163
|
+
kind: "numeric",
|
|
84164
|
+
field: "value",
|
|
84165
|
+
quantity: t("the total", "il totale"),
|
|
84166
|
+
label: t("Total", "Totale"),
|
|
84167
|
+
icon: "gauge"
|
|
84168
|
+
}]
|
|
84169
|
+
},
|
|
83722
84170
|
"numeric-sensor": {
|
|
83723
84171
|
scope: "device",
|
|
83724
84172
|
noun: t("Sensor", "Sensore"),
|
|
@@ -84191,8 +84639,47 @@ function projectAction(cap, action) {
|
|
|
84191
84639
|
};
|
|
84192
84640
|
}
|
|
84193
84641
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
84194
|
-
DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher;
|
|
84642
|
+
DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer;
|
|
84195
84643
|
DeviceFeature.BatteryOperated;
|
|
84644
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
84645
|
+
var HA_AS = "a power sensor (device_class power). Home Assistant has no laundry domain. running-state stays unexported until a null reading can be published as unavailable.";
|
|
84646
|
+
var HOMEKIT_REASON = "HomeKit has no laundry-appliance service. The export tab would pair an accessory with nothing on it: running-state is withheld until a null reading can be unavailable, and power is not a HomeKit service this export honours.";
|
|
84647
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
84648
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
84649
|
+
var MATTER_REASON = "No Matter export is built. The closest device types are Laundry Washer (0x0073) and Laundry Dryer (0x0074); a power threshold is not the Laundry Washer Mode cluster.";
|
|
84650
|
+
function withheld(reason) {
|
|
84651
|
+
return {
|
|
84652
|
+
[DeviceType.Washer]: {
|
|
84653
|
+
exported: false,
|
|
84654
|
+
reason
|
|
84655
|
+
},
|
|
84656
|
+
[DeviceType.Dryer]: {
|
|
84657
|
+
exported: false,
|
|
84658
|
+
reason
|
|
84659
|
+
},
|
|
84660
|
+
[DeviceType.Dishwasher]: {
|
|
84661
|
+
exported: false,
|
|
84662
|
+
reason
|
|
84663
|
+
}
|
|
84664
|
+
};
|
|
84665
|
+
}
|
|
84666
|
+
function offered(received) {
|
|
84667
|
+
return {
|
|
84668
|
+
[DeviceType.Washer]: {
|
|
84669
|
+
exported: true,
|
|
84670
|
+
as: received
|
|
84671
|
+
},
|
|
84672
|
+
[DeviceType.Dryer]: {
|
|
84673
|
+
exported: true,
|
|
84674
|
+
as: received
|
|
84675
|
+
},
|
|
84676
|
+
[DeviceType.Dishwasher]: {
|
|
84677
|
+
exported: true,
|
|
84678
|
+
as: received
|
|
84679
|
+
}
|
|
84680
|
+
};
|
|
84681
|
+
}
|
|
84682
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
84196
84683
|
Object.freeze({
|
|
84197
84684
|
"accessories.getStatus": [{
|
|
84198
84685
|
name: "deviceId",
|
|
@@ -85159,6 +85646,11 @@ Object.freeze({
|
|
|
85159
85646
|
form: "single",
|
|
85160
85647
|
optional: false
|
|
85161
85648
|
}],
|
|
85649
|
+
"groupActive.getStatus": [{
|
|
85650
|
+
name: "deviceId",
|
|
85651
|
+
form: "single",
|
|
85652
|
+
optional: false
|
|
85653
|
+
}],
|
|
85162
85654
|
"groupCommands.getStatus": [{
|
|
85163
85655
|
name: "deviceId",
|
|
85164
85656
|
form: "single",
|
|
@@ -85369,6 +85861,11 @@ Object.freeze({
|
|
|
85369
85861
|
form: "single",
|
|
85370
85862
|
optional: false
|
|
85371
85863
|
}],
|
|
85864
|
+
"meter.getStatus": [{
|
|
85865
|
+
name: "deviceId",
|
|
85866
|
+
form: "single",
|
|
85867
|
+
optional: false
|
|
85868
|
+
}],
|
|
85372
85869
|
"motion.getStatus": [{
|
|
85373
85870
|
name: "deviceId",
|
|
85374
85871
|
form: "single",
|
|
@@ -86976,7 +87473,6 @@ Object.freeze({
|
|
|
86976
87473
|
"network-access": "ingress",
|
|
86977
87474
|
"smtp-provider": "email"
|
|
86978
87475
|
});
|
|
86979
|
-
DeviceType.Camera;
|
|
86980
87476
|
/**
|
|
86981
87477
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
86982
87478
|
* `z.infer`, they do not restate the shape.
|