@camstack/addon-pipeline-orchestrator 1.2.631 → 1.2.632
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 +19 -10
- package/dist/_stub.js +15 -15
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-B749Uhfl.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-aMGY7kkZ.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DF61VdV8.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Dqc5BVYp.mjs +26 -0
- package/dist/{hostInit-BPB2Gtx5.mjs → hostInit-Cl9p1qwo.mjs} +3 -3
- package/dist/index.js +540 -45
- package/dist/index.mjs +540 -45
- package/dist/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D0o6BdcQ.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-E1Gh6b6l.mjs +0 -26
package/dist/index.mjs
CHANGED
|
@@ -5578,7 +5578,7 @@ var ZodIssueCode = {
|
|
|
5578
5578
|
var ZodFirstPartyTypeKind;
|
|
5579
5579
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5580
5580
|
//#endregion
|
|
5581
|
-
//#region ../types/dist/sleep
|
|
5581
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5582
5582
|
/**
|
|
5583
5583
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5584
5584
|
* window to float samples (D455).
|
|
@@ -9485,6 +9485,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9485
9485
|
"filesystem-browse",
|
|
9486
9486
|
"flood",
|
|
9487
9487
|
"gas",
|
|
9488
|
+
"group-active",
|
|
9488
9489
|
"group-commands",
|
|
9489
9490
|
"group-status",
|
|
9490
9491
|
"heating-valve",
|
|
@@ -9507,6 +9508,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9507
9508
|
"login-method",
|
|
9508
9509
|
"media-player",
|
|
9509
9510
|
"mesh-network",
|
|
9511
|
+
"meter",
|
|
9510
9512
|
"metrics-provider",
|
|
9511
9513
|
"model-convert",
|
|
9512
9514
|
"model-distributor",
|
|
@@ -10305,6 +10307,10 @@ Object.freeze({
|
|
|
10305
10307
|
"path": "detected",
|
|
10306
10308
|
"valueType": "boolean"
|
|
10307
10309
|
}],
|
|
10310
|
+
"group-active": [{
|
|
10311
|
+
"path": "active",
|
|
10312
|
+
"valueType": "boolean"
|
|
10313
|
+
}],
|
|
10308
10314
|
"group-status": [
|
|
10309
10315
|
{
|
|
10310
10316
|
"path": "included",
|
|
@@ -10564,6 +10570,10 @@ Object.freeze({
|
|
|
10564
10570
|
]
|
|
10565
10571
|
}
|
|
10566
10572
|
],
|
|
10573
|
+
"meter": [{
|
|
10574
|
+
"path": "value",
|
|
10575
|
+
"valueType": "number"
|
|
10576
|
+
}],
|
|
10567
10577
|
"motion": [
|
|
10568
10578
|
{
|
|
10569
10579
|
"path": "detected",
|
|
@@ -11331,7 +11341,7 @@ function sleep(ms) {
|
|
|
11331
11341
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
11332
11342
|
}
|
|
11333
11343
|
//#endregion
|
|
11334
|
-
//#region ../types/dist/err-msg-
|
|
11344
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
11335
11345
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
11336
11346
|
DeviceType["Camera"] = "camera";
|
|
11337
11347
|
DeviceType["Hub"] = "hub";
|
|
@@ -11425,8 +11435,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
11425
11435
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
11426
11436
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
11427
11437
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
11428
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
11438
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
11439
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
11429
11440
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
11441
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
11442
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
11443
|
+
DeviceType["Washer"] = "washer";
|
|
11444
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
11445
|
+
DeviceType["Dryer"] = "dryer";
|
|
11430
11446
|
return DeviceType;
|
|
11431
11447
|
}({});
|
|
11432
11448
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -11684,7 +11700,7 @@ function errMsg$2(err) {
|
|
|
11684
11700
|
return String(err);
|
|
11685
11701
|
}
|
|
11686
11702
|
//#endregion
|
|
11687
|
-
//#region ../types/dist/composition-
|
|
11703
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
11688
11704
|
/**
|
|
11689
11705
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11690
11706
|
*
|
|
@@ -12128,6 +12144,13 @@ var table = {
|
|
|
12128
12144
|
apply: () => {
|
|
12129
12145
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
12130
12146
|
}
|
|
12147
|
+
},
|
|
12148
|
+
schmitt: {
|
|
12149
|
+
minArgs: 3,
|
|
12150
|
+
maxArgs: 5,
|
|
12151
|
+
apply: () => {
|
|
12152
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
12153
|
+
}
|
|
12131
12154
|
}
|
|
12132
12155
|
};
|
|
12133
12156
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -12569,6 +12592,99 @@ function validateExpressionSource(src) {
|
|
|
12569
12592
|
return null;
|
|
12570
12593
|
}
|
|
12571
12594
|
/**
|
|
12595
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
12596
|
+
*
|
|
12597
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
12598
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
12599
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
12600
|
+
*
|
|
12601
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
12602
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
12603
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
12604
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
12605
|
+
* can move later without moving the others.
|
|
12606
|
+
*/
|
|
12607
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
12608
|
+
var APPLIANCE_KINDS = [
|
|
12609
|
+
"washer",
|
|
12610
|
+
"dryer",
|
|
12611
|
+
"dishwasher"
|
|
12612
|
+
];
|
|
12613
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
12614
|
+
/**
|
|
12615
|
+
* Statistics and integrals over a history read (D944).
|
|
12616
|
+
*
|
|
12617
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
12618
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
12619
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
12620
|
+
* as zero. A truncated read is not published.
|
|
12621
|
+
*/
|
|
12622
|
+
var STATISTIC_STATS = [
|
|
12623
|
+
"min",
|
|
12624
|
+
"max",
|
|
12625
|
+
"mean",
|
|
12626
|
+
"sum",
|
|
12627
|
+
"count",
|
|
12628
|
+
"change"
|
|
12629
|
+
];
|
|
12630
|
+
/**
|
|
12631
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
12632
|
+
*
|
|
12633
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
12634
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
12635
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
12636
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
12637
|
+
*/
|
|
12638
|
+
var MINUTE_MS = 6e4;
|
|
12639
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
12640
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
12641
|
+
var ROLLING_SPANS = [
|
|
12642
|
+
"1h",
|
|
12643
|
+
"24h",
|
|
12644
|
+
"2d",
|
|
12645
|
+
"7d",
|
|
12646
|
+
"30d",
|
|
12647
|
+
"custom"
|
|
12648
|
+
];
|
|
12649
|
+
var CALENDAR_PERIODS = [
|
|
12650
|
+
"today",
|
|
12651
|
+
"yesterday",
|
|
12652
|
+
"this-week",
|
|
12653
|
+
"this-month"
|
|
12654
|
+
];
|
|
12655
|
+
var RESET_PERIODS = [
|
|
12656
|
+
"never",
|
|
12657
|
+
"daily",
|
|
12658
|
+
"weekly",
|
|
12659
|
+
"monthly"
|
|
12660
|
+
];
|
|
12661
|
+
5 * MINUTE_MS;
|
|
12662
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
12663
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
12664
|
+
var rollingWindowObject = object({
|
|
12665
|
+
kind: literal("rolling"),
|
|
12666
|
+
span: _enum(ROLLING_SPANS),
|
|
12667
|
+
customMinutes: number().int().min(5).optional()
|
|
12668
|
+
}).check((payload) => {
|
|
12669
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
12670
|
+
code: "custom",
|
|
12671
|
+
message: "a custom range needs a duration in minutes",
|
|
12672
|
+
path: ["customMinutes"],
|
|
12673
|
+
input: payload.value
|
|
12674
|
+
});
|
|
12675
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
12676
|
+
code: "custom",
|
|
12677
|
+
message: "only a custom range carries a duration",
|
|
12678
|
+
path: ["customMinutes"],
|
|
12679
|
+
input: payload.value
|
|
12680
|
+
});
|
|
12681
|
+
});
|
|
12682
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
12683
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
12684
|
+
kind: literal("calendar"),
|
|
12685
|
+
period: _enum(CALENDAR_PERIODS)
|
|
12686
|
+
})]);
|
|
12687
|
+
/**
|
|
12572
12688
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
12573
12689
|
* id. Split out so helper schemas can name it without a cycle through
|
|
12574
12690
|
* `composition.ts` (D659).
|
|
@@ -12594,7 +12710,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
12594
12710
|
"occupancy",
|
|
12595
12711
|
"binary",
|
|
12596
12712
|
"switch",
|
|
12597
|
-
"light"
|
|
12713
|
+
"light",
|
|
12714
|
+
"fan",
|
|
12715
|
+
"cover",
|
|
12716
|
+
"valve",
|
|
12717
|
+
"lock",
|
|
12718
|
+
"media-player",
|
|
12719
|
+
"climate"
|
|
12598
12720
|
];
|
|
12599
12721
|
var NUMERIC_AGGREGATES = [
|
|
12600
12722
|
"mean",
|
|
@@ -12624,14 +12746,73 @@ var HelperMemberSchema = object({
|
|
|
12624
12746
|
cap: string().min(1),
|
|
12625
12747
|
fieldPath: string().min(1)
|
|
12626
12748
|
});
|
|
12627
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12749
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12750
|
+
object({
|
|
12751
|
+
kind: literal("group"),
|
|
12752
|
+
templateId: GroupTemplateIdSchema,
|
|
12753
|
+
aggregate: AggregateReducerSchema,
|
|
12754
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
12755
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
12756
|
+
active: ActiveCriterionSchema.optional()
|
|
12757
|
+
}),
|
|
12758
|
+
object({
|
|
12759
|
+
kind: literal("appliance"),
|
|
12760
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
12761
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
12762
|
+
thresholdWatts: number().positive(),
|
|
12763
|
+
startDwellMs: number().int().nonnegative(),
|
|
12764
|
+
stopDwellMs: number().int().nonnegative(),
|
|
12765
|
+
member: HelperMemberSchema
|
|
12766
|
+
}),
|
|
12767
|
+
object({
|
|
12768
|
+
kind: literal("statistic"),
|
|
12769
|
+
stat: _enum(STATISTIC_STATS),
|
|
12770
|
+
window: StatisticWindowSchema,
|
|
12771
|
+
source: HelperMemberSchema
|
|
12772
|
+
}),
|
|
12773
|
+
object({
|
|
12774
|
+
kind: literal("integral"),
|
|
12775
|
+
reset: _enum(RESET_PERIODS),
|
|
12776
|
+
output: _enum(["energy", "meter"]),
|
|
12777
|
+
source: HelperMemberSchema
|
|
12778
|
+
}),
|
|
12779
|
+
object({
|
|
12780
|
+
kind: literal("threshold"),
|
|
12781
|
+
source: HelperMemberSchema,
|
|
12782
|
+
high: number(),
|
|
12783
|
+
low: number(),
|
|
12784
|
+
onForMs: number().int().nonnegative(),
|
|
12785
|
+
offForMs: number().int().nonnegative()
|
|
12786
|
+
}),
|
|
12787
|
+
object({
|
|
12788
|
+
kind: literal("arithmetic"),
|
|
12789
|
+
op: _enum([
|
|
12790
|
+
"sum",
|
|
12791
|
+
"difference",
|
|
12792
|
+
"ratio"
|
|
12793
|
+
]),
|
|
12794
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
12795
|
+
}),
|
|
12796
|
+
object({
|
|
12797
|
+
kind: literal("expression"),
|
|
12798
|
+
expr: string().min(1),
|
|
12799
|
+
inputs: array(object({
|
|
12800
|
+
name: string().min(1),
|
|
12801
|
+
member: HelperMemberSchema
|
|
12802
|
+
})).min(1).max(64),
|
|
12803
|
+
output: _enum(["number", "boolean"])
|
|
12804
|
+
}),
|
|
12805
|
+
object({
|
|
12806
|
+
kind: literal("derivative"),
|
|
12807
|
+
window: RollingWindowSchema,
|
|
12808
|
+
per: _enum([
|
|
12809
|
+
"second",
|
|
12810
|
+
"minute",
|
|
12811
|
+
"hour"
|
|
12812
|
+
]),
|
|
12813
|
+
source: HelperMemberSchema
|
|
12814
|
+
})
|
|
12815
|
+
]);
|
|
12635
12816
|
/**
|
|
12636
12817
|
* A COMPOSITION: a device assembled from other devices' state (D659).
|
|
12637
12818
|
*
|
|
@@ -12713,6 +12894,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12713
12894
|
"all"
|
|
12714
12895
|
]),
|
|
12715
12896
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12897
|
+
/**
|
|
12898
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
12899
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
12900
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
12901
|
+
*/
|
|
12902
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
12716
12903
|
/** `value` is the reading; the others are the member counts. */
|
|
12717
12904
|
publish: _enum([
|
|
12718
12905
|
"value",
|
|
@@ -12726,6 +12913,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12726
12913
|
"omit",
|
|
12727
12914
|
"offline"
|
|
12728
12915
|
])
|
|
12916
|
+
}),
|
|
12917
|
+
object({
|
|
12918
|
+
kind: literal("series"),
|
|
12919
|
+
read: CompositionFieldReadSchema,
|
|
12920
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
12921
|
+
publish: _enum([
|
|
12922
|
+
"value",
|
|
12923
|
+
"included",
|
|
12924
|
+
"excluded",
|
|
12925
|
+
"total"
|
|
12926
|
+
]),
|
|
12927
|
+
/**
|
|
12928
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12929
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12930
|
+
*/
|
|
12931
|
+
empty: _enum([
|
|
12932
|
+
"null",
|
|
12933
|
+
"omit",
|
|
12934
|
+
"offline"
|
|
12935
|
+
])
|
|
12729
12936
|
})
|
|
12730
12937
|
]);
|
|
12731
12938
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -18234,7 +18441,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
18234
18441
|
*/
|
|
18235
18442
|
interactiveConnectPath: string().min(1).optional(),
|
|
18236
18443
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
18237
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
18444
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
18445
|
+
/**
|
|
18446
|
+
* The kind signs in through a server-held interactive session instead of
|
|
18447
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
18448
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
18449
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
18450
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
18451
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
18452
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
18453
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
18454
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
18455
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
18456
|
+
* offers it as the default path; the fields the session fills are
|
|
18457
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
18458
|
+
*/
|
|
18459
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
18238
18460
|
}))
|
|
18239
18461
|
});
|
|
18240
18462
|
var ListInputSchema = object({
|
|
@@ -19271,7 +19493,8 @@ var CompositionProblemSchema = object({
|
|
|
19271
19493
|
"native-capability-replace",
|
|
19272
19494
|
"mixed-quantity",
|
|
19273
19495
|
"helper-mismatch",
|
|
19274
|
-
"member-constraint"
|
|
19496
|
+
"member-constraint",
|
|
19497
|
+
"retention"
|
|
19275
19498
|
]),
|
|
19276
19499
|
path: string(),
|
|
19277
19500
|
message: string()
|
|
@@ -19505,13 +19728,17 @@ Object.freeze({
|
|
|
19505
19728
|
latchedAt: {
|
|
19506
19729
|
kind: "fixed",
|
|
19507
19730
|
result: ["number", "null"]
|
|
19731
|
+
},
|
|
19732
|
+
schmitt: {
|
|
19733
|
+
kind: "fixed",
|
|
19734
|
+
result: ["boolean", "null"]
|
|
19508
19735
|
}
|
|
19509
19736
|
});
|
|
19510
19737
|
/**
|
|
19511
19738
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
19512
19739
|
* Data, not a form default written into the block.
|
|
19513
19740
|
*/
|
|
19514
|
-
var NOW = {
|
|
19741
|
+
var NOW$2 = {
|
|
19515
19742
|
fieldPath: "lastFetchedAt",
|
|
19516
19743
|
expr: "now"
|
|
19517
19744
|
};
|
|
@@ -19525,6 +19752,8 @@ function numeric(input) {
|
|
|
19525
19752
|
family: "numeric",
|
|
19526
19753
|
deviceType: DeviceType.Sensor,
|
|
19527
19754
|
memberDeviceType: DeviceType.Sensor,
|
|
19755
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
19756
|
+
activeWhen: void 0,
|
|
19528
19757
|
commandCaps: [],
|
|
19529
19758
|
baseUnit: baseUnitOf(input.quantity),
|
|
19530
19759
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -19540,6 +19769,8 @@ function binary(input) {
|
|
|
19540
19769
|
family: "binary",
|
|
19541
19770
|
deviceType: DeviceType.Sensor,
|
|
19542
19771
|
memberDeviceType: DeviceType.Sensor,
|
|
19772
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
19773
|
+
activeWhen: void 0,
|
|
19543
19774
|
commandCaps: [],
|
|
19544
19775
|
quantity: "none",
|
|
19545
19776
|
baseUnit: void 0,
|
|
@@ -19557,7 +19788,7 @@ var GROUP_TEMPLATES = [
|
|
|
19557
19788
|
quantity: "temperature",
|
|
19558
19789
|
defaultAggregate: "mean",
|
|
19559
19790
|
empty: "null",
|
|
19560
|
-
companions: [NOW]
|
|
19791
|
+
companions: [NOW$2]
|
|
19561
19792
|
}),
|
|
19562
19793
|
numeric({
|
|
19563
19794
|
id: "humidity",
|
|
@@ -19568,7 +19799,7 @@ var GROUP_TEMPLATES = [
|
|
|
19568
19799
|
quantity: "humidity",
|
|
19569
19800
|
defaultAggregate: "mean",
|
|
19570
19801
|
empty: "null",
|
|
19571
|
-
companions: [NOW]
|
|
19802
|
+
companions: [NOW$2]
|
|
19572
19803
|
}),
|
|
19573
19804
|
numeric({
|
|
19574
19805
|
id: "pressure",
|
|
@@ -19579,7 +19810,7 @@ var GROUP_TEMPLATES = [
|
|
|
19579
19810
|
quantity: "pressure",
|
|
19580
19811
|
defaultAggregate: "mean",
|
|
19581
19812
|
empty: "null",
|
|
19582
|
-
companions: [NOW]
|
|
19813
|
+
companions: [NOW$2]
|
|
19583
19814
|
}),
|
|
19584
19815
|
numeric({
|
|
19585
19816
|
id: "illuminance",
|
|
@@ -19590,7 +19821,7 @@ var GROUP_TEMPLATES = [
|
|
|
19590
19821
|
quantity: "illuminance",
|
|
19591
19822
|
defaultAggregate: "mean",
|
|
19592
19823
|
empty: "null",
|
|
19593
|
-
companions: [NOW]
|
|
19824
|
+
companions: [NOW$2]
|
|
19594
19825
|
}),
|
|
19595
19826
|
numeric({
|
|
19596
19827
|
id: "power",
|
|
@@ -19601,7 +19832,7 @@ var GROUP_TEMPLATES = [
|
|
|
19601
19832
|
quantity: "power",
|
|
19602
19833
|
defaultAggregate: "sum",
|
|
19603
19834
|
empty: "omit",
|
|
19604
|
-
companions: [NOW]
|
|
19835
|
+
companions: [NOW$2]
|
|
19605
19836
|
}),
|
|
19606
19837
|
numeric({
|
|
19607
19838
|
id: "energy",
|
|
@@ -19612,7 +19843,7 @@ var GROUP_TEMPLATES = [
|
|
|
19612
19843
|
quantity: "energy",
|
|
19613
19844
|
defaultAggregate: "sum",
|
|
19614
19845
|
empty: "omit",
|
|
19615
|
-
companions: [NOW]
|
|
19846
|
+
companions: [NOW$2]
|
|
19616
19847
|
}),
|
|
19617
19848
|
numeric({
|
|
19618
19849
|
id: "battery",
|
|
@@ -19647,7 +19878,7 @@ var GROUP_TEMPLATES = [
|
|
|
19647
19878
|
quantity: "device",
|
|
19648
19879
|
defaultAggregate: "mean",
|
|
19649
19880
|
empty: "null",
|
|
19650
|
-
companions: [NOW]
|
|
19881
|
+
companions: [NOW$2]
|
|
19651
19882
|
}),
|
|
19652
19883
|
binary({
|
|
19653
19884
|
id: "motion",
|
|
@@ -19741,6 +19972,11 @@ var GROUP_TEMPLATES = [
|
|
|
19741
19972
|
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.",
|
|
19742
19973
|
deviceType: DeviceType.Switch,
|
|
19743
19974
|
outputCap: "switch",
|
|
19975
|
+
outputField: "on",
|
|
19976
|
+
member: {
|
|
19977
|
+
cap: "switch",
|
|
19978
|
+
fieldPath: "on"
|
|
19979
|
+
},
|
|
19744
19980
|
commandCaps: ["switch"]
|
|
19745
19981
|
}),
|
|
19746
19982
|
actuator({
|
|
@@ -19748,34 +19984,136 @@ var GROUP_TEMPLATES = [
|
|
|
19748
19984
|
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.",
|
|
19749
19985
|
deviceType: DeviceType.Light,
|
|
19750
19986
|
outputCap: "switch",
|
|
19987
|
+
outputField: "on",
|
|
19988
|
+
member: {
|
|
19989
|
+
cap: "switch",
|
|
19990
|
+
fieldPath: "on"
|
|
19991
|
+
},
|
|
19751
19992
|
commandCaps: [
|
|
19752
19993
|
"switch",
|
|
19753
19994
|
"brightness",
|
|
19754
19995
|
"color"
|
|
19755
19996
|
]
|
|
19997
|
+
}),
|
|
19998
|
+
actuator({
|
|
19999
|
+
id: "fan",
|
|
20000
|
+
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.",
|
|
20001
|
+
deviceType: DeviceType.Fan,
|
|
20002
|
+
outputCap: "switch",
|
|
20003
|
+
outputField: "on",
|
|
20004
|
+
member: {
|
|
20005
|
+
cap: "switch",
|
|
20006
|
+
fieldPath: "on"
|
|
20007
|
+
},
|
|
20008
|
+
commandCaps: ["switch", "fan-control"]
|
|
20009
|
+
}),
|
|
20010
|
+
actuator({
|
|
20011
|
+
id: "cover",
|
|
20012
|
+
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.",
|
|
20013
|
+
deviceType: DeviceType.Cover,
|
|
20014
|
+
outputCap: "group-active",
|
|
20015
|
+
outputField: "active",
|
|
20016
|
+
member: {
|
|
20017
|
+
cap: "cover",
|
|
20018
|
+
fieldPath: "state"
|
|
20019
|
+
},
|
|
20020
|
+
activeWhen: [
|
|
20021
|
+
"open",
|
|
20022
|
+
"opening",
|
|
20023
|
+
"stopped"
|
|
20024
|
+
],
|
|
20025
|
+
commandCaps: ["cover"]
|
|
20026
|
+
}),
|
|
20027
|
+
actuator({
|
|
20028
|
+
id: "valve",
|
|
20029
|
+
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.",
|
|
20030
|
+
deviceType: DeviceType.Valve,
|
|
20031
|
+
outputCap: "group-active",
|
|
20032
|
+
outputField: "active",
|
|
20033
|
+
member: {
|
|
20034
|
+
cap: "valve",
|
|
20035
|
+
fieldPath: "state"
|
|
20036
|
+
},
|
|
20037
|
+
activeWhen: [
|
|
20038
|
+
"open",
|
|
20039
|
+
"opening",
|
|
20040
|
+
"stopped"
|
|
20041
|
+
],
|
|
20042
|
+
commandCaps: ["valve"]
|
|
20043
|
+
}),
|
|
20044
|
+
actuator({
|
|
20045
|
+
id: "lock",
|
|
20046
|
+
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.",
|
|
20047
|
+
deviceType: DeviceType.Lock,
|
|
20048
|
+
outputCap: "group-active",
|
|
20049
|
+
outputField: "active",
|
|
20050
|
+
member: {
|
|
20051
|
+
cap: "lock-control",
|
|
20052
|
+
fieldPath: "state"
|
|
20053
|
+
},
|
|
20054
|
+
activeWhen: ["locked"],
|
|
20055
|
+
commandCaps: ["lock-control"]
|
|
20056
|
+
}),
|
|
20057
|
+
actuator({
|
|
20058
|
+
id: "media-player",
|
|
20059
|
+
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.",
|
|
20060
|
+
deviceType: DeviceType.MediaPlayer,
|
|
20061
|
+
outputCap: "group-active",
|
|
20062
|
+
outputField: "active",
|
|
20063
|
+
member: {
|
|
20064
|
+
cap: "media-player",
|
|
20065
|
+
fieldPath: "state"
|
|
20066
|
+
},
|
|
20067
|
+
activeWhen: ["playing", "buffering"],
|
|
20068
|
+
commandCaps: ["media-player"]
|
|
20069
|
+
}),
|
|
20070
|
+
actuator({
|
|
20071
|
+
id: "climate",
|
|
20072
|
+
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.",
|
|
20073
|
+
deviceType: DeviceType.Thermostat,
|
|
20074
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
20075
|
+
outputCap: "group-active",
|
|
20076
|
+
outputField: "active",
|
|
20077
|
+
member: {
|
|
20078
|
+
cap: "climate-control",
|
|
20079
|
+
fieldPath: "mode"
|
|
20080
|
+
},
|
|
20081
|
+
activeWhen: [
|
|
20082
|
+
"heat",
|
|
20083
|
+
"cool",
|
|
20084
|
+
"auto",
|
|
20085
|
+
"heat_cool",
|
|
20086
|
+
"fan_only",
|
|
20087
|
+
"dry"
|
|
20088
|
+
],
|
|
20089
|
+
commandCaps: ["climate-control"]
|
|
19756
20090
|
})
|
|
19757
20091
|
];
|
|
19758
20092
|
function actuator(input) {
|
|
19759
20093
|
return {
|
|
19760
|
-
|
|
20094
|
+
id: input.id,
|
|
20095
|
+
summary: input.summary,
|
|
20096
|
+
deviceType: input.deviceType,
|
|
20097
|
+
outputCap: input.outputCap,
|
|
20098
|
+
outputField: input.outputField,
|
|
20099
|
+
commandCaps: input.commandCaps,
|
|
19761
20100
|
family: "actuator",
|
|
19762
20101
|
role: void 0,
|
|
19763
20102
|
memberDeviceType: input.deviceType,
|
|
19764
|
-
|
|
20103
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
20104
|
+
activeWhen: input.activeWhen,
|
|
19765
20105
|
quantity: "none",
|
|
19766
20106
|
baseUnit: void 0,
|
|
19767
20107
|
aggregates: BINARY_AGGREGATES,
|
|
19768
20108
|
defaultAggregate: "any",
|
|
19769
20109
|
empty: "offline",
|
|
19770
|
-
accept: [
|
|
19771
|
-
cap: "switch",
|
|
19772
|
-
fieldPath: "on"
|
|
19773
|
-
}],
|
|
20110
|
+
accept: [input.member],
|
|
19774
20111
|
companions: [CHANGED]
|
|
19775
20112
|
};
|
|
19776
20113
|
}
|
|
19777
20114
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
19778
20115
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
20116
|
+
DeviceType.Camera;
|
|
19779
20117
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
19780
20118
|
/**
|
|
19781
20119
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -44790,7 +45128,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
44790
45128
|
});
|
|
44791
45129
|
/**
|
|
44792
45130
|
* Optional, richer endpoint shape returned by providers that expose
|
|
44793
|
-
* MORE than one ingress concurrently (Tailscale
|
|
45131
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
44794
45132
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
44795
45133
|
* the originating provider config (mode + sourcePort) so the
|
|
44796
45134
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -47701,7 +48039,20 @@ var NcRuleInputSchema = object({
|
|
|
47701
48039
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
47702
48040
|
* path does not run Zod defaults.
|
|
47703
48041
|
*/
|
|
47704
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
48042
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
48043
|
+
/**
|
|
48044
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
48045
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
48046
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
48047
|
+
* same mark the Library writes, and records whose notification it was and
|
|
48048
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
48049
|
+
*
|
|
48050
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
48051
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
48052
|
+
* authored before this field meant. An editor turns it off by writing
|
|
48053
|
+
* `false`, so it needs no `clear` key.
|
|
48054
|
+
*/
|
|
48055
|
+
askVerdict: boolean().optional()
|
|
47705
48056
|
});
|
|
47706
48057
|
/**
|
|
47707
48058
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -59081,7 +59432,7 @@ var BatteryStatusSchema = object({
|
|
|
59081
59432
|
*/
|
|
59082
59433
|
binary: boolean().optional().meta({ label: "Binary indicator" })
|
|
59083
59434
|
});
|
|
59084
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
|
|
59435
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter;
|
|
59085
59436
|
method(object({
|
|
59086
59437
|
deviceId: number(),
|
|
59087
59438
|
/** Bound on the wait. Sensible range 3000–10000ms. */
|
|
@@ -60834,7 +61185,13 @@ results: array(object({
|
|
|
60834
61185
|
/** Ms epoch of the attempt. */
|
|
60835
61186
|
at: number()
|
|
60836
61187
|
})) });
|
|
60837
|
-
DeviceType.Switch, DeviceType.Light;
|
|
61188
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
61189
|
+
object({
|
|
61190
|
+
active: boolean().meta({ label: "Active" }),
|
|
61191
|
+
/** Ms epoch when the slice was last updated. */
|
|
61192
|
+
lastChangedAt: number()
|
|
61193
|
+
});
|
|
61194
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
60838
61195
|
object({
|
|
60839
61196
|
/** Members whose current value entered the aggregate. */
|
|
60840
61197
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -60852,7 +61209,7 @@ object({
|
|
|
60852
61209
|
label: "Members"
|
|
60853
61210
|
}))
|
|
60854
61211
|
});
|
|
60855
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
61212
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
60856
61213
|
object({
|
|
60857
61214
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60858
61215
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -61759,7 +62116,14 @@ DeviceType.Lock, method(object({
|
|
|
61759
62116
|
auth: "protected"
|
|
61760
62117
|
}), method(object({
|
|
61761
62118
|
deviceId: number().int().nonnegative(),
|
|
61762
|
-
code: string().min(1).optional()
|
|
62119
|
+
code: string().min(1).optional(),
|
|
62120
|
+
/**
|
|
62121
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
62122
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
62123
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
62124
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
62125
|
+
*/
|
|
62126
|
+
confirm: boolean().optional()
|
|
61763
62127
|
}), _void(), {
|
|
61764
62128
|
kind: "mutation",
|
|
61765
62129
|
auth: "protected"
|
|
@@ -61767,6 +62131,11 @@ DeviceType.Lock, method(object({
|
|
|
61767
62131
|
kind: "mutation",
|
|
61768
62132
|
auth: "protected"
|
|
61769
62133
|
});
|
|
62134
|
+
object({
|
|
62135
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
62136
|
+
lastFetchedAt: number()
|
|
62137
|
+
});
|
|
62138
|
+
DeviceType.Sensor;
|
|
61770
62139
|
/**
|
|
61771
62140
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
61772
62141
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -64415,9 +64784,9 @@ object({
|
|
|
64415
64784
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64416
64785
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64417
64786
|
/** Voltage in volts. */
|
|
64418
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
64787
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
64419
64788
|
/** Current in amperes. */
|
|
64420
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
64789
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
64421
64790
|
/** Apparent power in volt-amperes. */
|
|
64422
64791
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64423
64792
|
/** Power factor (0..1) if reported. */
|
|
@@ -64425,7 +64794,23 @@ object({
|
|
|
64425
64794
|
/** Ms epoch when the slice was last updated. */
|
|
64426
64795
|
lastFetchedAt: number()
|
|
64427
64796
|
});
|
|
64428
|
-
|
|
64797
|
+
[
|
|
64798
|
+
DeviceType.Sensor,
|
|
64799
|
+
DeviceType.Switch,
|
|
64800
|
+
DeviceType.Light,
|
|
64801
|
+
DeviceType.Fan,
|
|
64802
|
+
DeviceType.Climate,
|
|
64803
|
+
DeviceType.Thermostat,
|
|
64804
|
+
DeviceType.Humidifier,
|
|
64805
|
+
DeviceType.WaterHeater,
|
|
64806
|
+
DeviceType.MediaPlayer,
|
|
64807
|
+
DeviceType.Washer,
|
|
64808
|
+
DeviceType.Dryer,
|
|
64809
|
+
DeviceType.Dishwasher,
|
|
64810
|
+
DeviceType.Vacuum,
|
|
64811
|
+
DeviceType.LawnMower,
|
|
64812
|
+
DeviceType.PetFeeder
|
|
64813
|
+
].filter((type) => type !== DeviceType.Sensor);
|
|
64429
64814
|
/**
|
|
64430
64815
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
64431
64816
|
* on `DeviceType.Presence`. Read-only — no setters: presence is
|
|
@@ -64872,7 +65257,7 @@ object({
|
|
|
64872
65257
|
phase: string().nullable()
|
|
64873
65258
|
});
|
|
64874
65259
|
Object.values(DeviceType);
|
|
64875
|
-
DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
65260
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
64876
65261
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
|
|
64877
65262
|
kind: "mutation",
|
|
64878
65263
|
auth: "admin"
|
|
@@ -66945,7 +67330,7 @@ object({
|
|
|
66945
67330
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
66946
67331
|
lastChangedAt: number()
|
|
66947
67332
|
});
|
|
66948
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
67333
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
66949
67334
|
deviceId: number(),
|
|
66950
67335
|
on: boolean()
|
|
66951
67336
|
}), _void(), {
|
|
@@ -68697,8 +69082,9 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
68697
69082
|
kind: "mutation",
|
|
68698
69083
|
auth: "admin"
|
|
68699
69084
|
});
|
|
69085
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
68700
69086
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
68701
|
-
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;
|
|
69087
|
+
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;
|
|
68702
69088
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
68703
69089
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
68704
69090
|
new Set(CAP_NAMES);
|
|
@@ -68751,7 +69137,7 @@ var AccessoryKind = {
|
|
|
68751
69137
|
PrivacyMask: DeviceRole.PrivacyMask
|
|
68752
69138
|
};
|
|
68753
69139
|
AccessoryKind.Siren, AccessoryKind.Floodlight, AccessoryKind.Spotlight, AccessoryKind.PirSensor, AccessoryKind.Chime, AccessoryKind.Autotrack, AccessoryKind.Nightvision, AccessoryKind.PrivacyMask;
|
|
68754
|
-
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;
|
|
69140
|
+
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;
|
|
68755
69141
|
new Set(Object.values(DeviceType));
|
|
68756
69142
|
Object.freeze({
|
|
68757
69143
|
"accessories.getStatus": {
|
|
@@ -71974,6 +72360,13 @@ Object.freeze({
|
|
|
71974
72360
|
access: "view",
|
|
71975
72361
|
role: "viewer"
|
|
71976
72362
|
},
|
|
72363
|
+
"groupActive.getStatus": {
|
|
72364
|
+
capName: "group-active",
|
|
72365
|
+
capScope: "device",
|
|
72366
|
+
addonId: null,
|
|
72367
|
+
access: "view",
|
|
72368
|
+
role: "viewer"
|
|
72369
|
+
},
|
|
71977
72370
|
"groupCommands.getStatus": {
|
|
71978
72371
|
capName: "group-commands",
|
|
71979
72372
|
capScope: "device",
|
|
@@ -72940,6 +73333,13 @@ Object.freeze({
|
|
|
72940
73333
|
access: "create",
|
|
72941
73334
|
role: "admin"
|
|
72942
73335
|
},
|
|
73336
|
+
"meter.getStatus": {
|
|
73337
|
+
capName: "meter",
|
|
73338
|
+
capScope: "device",
|
|
73339
|
+
addonId: null,
|
|
73340
|
+
access: "view",
|
|
73341
|
+
role: "viewer"
|
|
73342
|
+
},
|
|
72943
73343
|
"metricsProvider.collectSnapshot": {
|
|
72944
73344
|
capName: "metrics-provider",
|
|
72945
73345
|
capScope: "system",
|
|
@@ -81038,7 +81438,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
81038
81438
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
81039
81439
|
icon: "square"
|
|
81040
81440
|
}
|
|
81041
|
-
}
|
|
81441
|
+
},
|
|
81442
|
+
overrides: { byType: {
|
|
81443
|
+
[DeviceType.Washer]: {
|
|
81444
|
+
state: { running: {
|
|
81445
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
81446
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
81447
|
+
} },
|
|
81448
|
+
events: {
|
|
81449
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
81450
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
81451
|
+
}
|
|
81452
|
+
},
|
|
81453
|
+
[DeviceType.Dryer]: {
|
|
81454
|
+
state: { running: {
|
|
81455
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
81456
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
81457
|
+
} },
|
|
81458
|
+
events: {
|
|
81459
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
81460
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
81461
|
+
}
|
|
81462
|
+
},
|
|
81463
|
+
[DeviceType.Dishwasher]: {
|
|
81464
|
+
state: { running: {
|
|
81465
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
81466
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
81467
|
+
} },
|
|
81468
|
+
events: {
|
|
81469
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
81470
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
81471
|
+
}
|
|
81472
|
+
}
|
|
81473
|
+
} }
|
|
81042
81474
|
},
|
|
81043
81475
|
update: {
|
|
81044
81476
|
scope: "device",
|
|
@@ -81810,6 +82242,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
81810
82242
|
icon: "flame"
|
|
81811
82243
|
}]
|
|
81812
82244
|
},
|
|
82245
|
+
"group-active": {
|
|
82246
|
+
scope: "device",
|
|
82247
|
+
noun: t("Group state", "Stato del gruppo")
|
|
82248
|
+
},
|
|
81813
82249
|
"group-commands": {
|
|
81814
82250
|
scope: "device",
|
|
81815
82251
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -81866,6 +82302,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
81866
82302
|
}],
|
|
81867
82303
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
81868
82304
|
},
|
|
82305
|
+
meter: {
|
|
82306
|
+
scope: "device",
|
|
82307
|
+
noun: t("Meter", "Contatore"),
|
|
82308
|
+
state: [{
|
|
82309
|
+
kind: "numeric",
|
|
82310
|
+
field: "value",
|
|
82311
|
+
quantity: t("the total", "il totale"),
|
|
82312
|
+
label: t("Total", "Totale"),
|
|
82313
|
+
icon: "gauge"
|
|
82314
|
+
}]
|
|
82315
|
+
},
|
|
81869
82316
|
"numeric-sensor": {
|
|
81870
82317
|
scope: "device",
|
|
81871
82318
|
noun: t("Sensor", "Sensore"),
|
|
@@ -82338,7 +82785,7 @@ function projectAction(cap, action) {
|
|
|
82338
82785
|
};
|
|
82339
82786
|
}
|
|
82340
82787
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
82341
|
-
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;
|
|
82788
|
+
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;
|
|
82342
82789
|
/**
|
|
82343
82790
|
* Heuristic check — `device.features?.includes(profile.when.hasFeature)`.
|
|
82344
82791
|
*/
|
|
@@ -82368,6 +82815,45 @@ function resolveDeviceProfile(features) {
|
|
|
82368
82815
|
for (const profile of DEVICE_PROFILES) if (deviceMatchesProfile(features, profile)) return profile;
|
|
82369
82816
|
return null;
|
|
82370
82817
|
}
|
|
82818
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
82819
|
+
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.";
|
|
82820
|
+
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.";
|
|
82821
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
82822
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
82823
|
+
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.";
|
|
82824
|
+
function withheld(reason) {
|
|
82825
|
+
return {
|
|
82826
|
+
[DeviceType.Washer]: {
|
|
82827
|
+
exported: false,
|
|
82828
|
+
reason
|
|
82829
|
+
},
|
|
82830
|
+
[DeviceType.Dryer]: {
|
|
82831
|
+
exported: false,
|
|
82832
|
+
reason
|
|
82833
|
+
},
|
|
82834
|
+
[DeviceType.Dishwasher]: {
|
|
82835
|
+
exported: false,
|
|
82836
|
+
reason
|
|
82837
|
+
}
|
|
82838
|
+
};
|
|
82839
|
+
}
|
|
82840
|
+
function offered(received) {
|
|
82841
|
+
return {
|
|
82842
|
+
[DeviceType.Washer]: {
|
|
82843
|
+
exported: true,
|
|
82844
|
+
as: received
|
|
82845
|
+
},
|
|
82846
|
+
[DeviceType.Dryer]: {
|
|
82847
|
+
exported: true,
|
|
82848
|
+
as: received
|
|
82849
|
+
},
|
|
82850
|
+
[DeviceType.Dishwasher]: {
|
|
82851
|
+
exported: true,
|
|
82852
|
+
as: received
|
|
82853
|
+
}
|
|
82854
|
+
};
|
|
82855
|
+
}
|
|
82856
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
82371
82857
|
Object.freeze({
|
|
82372
82858
|
"accessories.getStatus": [{
|
|
82373
82859
|
name: "deviceId",
|
|
@@ -83334,6 +83820,11 @@ Object.freeze({
|
|
|
83334
83820
|
form: "single",
|
|
83335
83821
|
optional: false
|
|
83336
83822
|
}],
|
|
83823
|
+
"groupActive.getStatus": [{
|
|
83824
|
+
name: "deviceId",
|
|
83825
|
+
form: "single",
|
|
83826
|
+
optional: false
|
|
83827
|
+
}],
|
|
83337
83828
|
"groupCommands.getStatus": [{
|
|
83338
83829
|
name: "deviceId",
|
|
83339
83830
|
form: "single",
|
|
@@ -83544,6 +84035,11 @@ Object.freeze({
|
|
|
83544
84035
|
form: "single",
|
|
83545
84036
|
optional: false
|
|
83546
84037
|
}],
|
|
84038
|
+
"meter.getStatus": [{
|
|
84039
|
+
name: "deviceId",
|
|
84040
|
+
form: "single",
|
|
84041
|
+
optional: false
|
|
84042
|
+
}],
|
|
83547
84043
|
"motion.getStatus": [{
|
|
83548
84044
|
name: "deviceId",
|
|
83549
84045
|
form: "single",
|
|
@@ -85248,7 +85744,6 @@ var BucketAccumulator = class {
|
|
|
85248
85744
|
return n;
|
|
85249
85745
|
}
|
|
85250
85746
|
};
|
|
85251
|
-
DeviceType.Camera;
|
|
85252
85747
|
/**
|
|
85253
85748
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
85254
85749
|
* `z.infer`, they do not restate the shape.
|