@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.js
CHANGED
|
@@ -5606,7 +5606,7 @@ var ZodIssueCode = {
|
|
|
5606
5606
|
var ZodFirstPartyTypeKind;
|
|
5607
5607
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5608
5608
|
//#endregion
|
|
5609
|
-
//#region ../types/dist/sleep
|
|
5609
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5610
5610
|
/**
|
|
5611
5611
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5612
5612
|
* window to float samples (D455).
|
|
@@ -9513,6 +9513,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9513
9513
|
"filesystem-browse",
|
|
9514
9514
|
"flood",
|
|
9515
9515
|
"gas",
|
|
9516
|
+
"group-active",
|
|
9516
9517
|
"group-commands",
|
|
9517
9518
|
"group-status",
|
|
9518
9519
|
"heating-valve",
|
|
@@ -9535,6 +9536,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9535
9536
|
"login-method",
|
|
9536
9537
|
"media-player",
|
|
9537
9538
|
"mesh-network",
|
|
9539
|
+
"meter",
|
|
9538
9540
|
"metrics-provider",
|
|
9539
9541
|
"model-convert",
|
|
9540
9542
|
"model-distributor",
|
|
@@ -10333,6 +10335,10 @@ Object.freeze({
|
|
|
10333
10335
|
"path": "detected",
|
|
10334
10336
|
"valueType": "boolean"
|
|
10335
10337
|
}],
|
|
10338
|
+
"group-active": [{
|
|
10339
|
+
"path": "active",
|
|
10340
|
+
"valueType": "boolean"
|
|
10341
|
+
}],
|
|
10336
10342
|
"group-status": [
|
|
10337
10343
|
{
|
|
10338
10344
|
"path": "included",
|
|
@@ -10592,6 +10598,10 @@ Object.freeze({
|
|
|
10592
10598
|
]
|
|
10593
10599
|
}
|
|
10594
10600
|
],
|
|
10601
|
+
"meter": [{
|
|
10602
|
+
"path": "value",
|
|
10603
|
+
"valueType": "number"
|
|
10604
|
+
}],
|
|
10595
10605
|
"motion": [
|
|
10596
10606
|
{
|
|
10597
10607
|
"path": "detected",
|
|
@@ -11359,7 +11369,7 @@ function sleep(ms) {
|
|
|
11359
11369
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
11360
11370
|
}
|
|
11361
11371
|
//#endregion
|
|
11362
|
-
//#region ../types/dist/err-msg-
|
|
11372
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
11363
11373
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
11364
11374
|
DeviceType["Camera"] = "camera";
|
|
11365
11375
|
DeviceType["Hub"] = "hub";
|
|
@@ -11453,8 +11463,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
11453
11463
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
11454
11464
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
11455
11465
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
11456
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
11466
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
11467
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
11457
11468
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
11469
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
11470
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
11471
|
+
DeviceType["Washer"] = "washer";
|
|
11472
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
11473
|
+
DeviceType["Dryer"] = "dryer";
|
|
11458
11474
|
return DeviceType;
|
|
11459
11475
|
}({});
|
|
11460
11476
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -11712,7 +11728,7 @@ function errMsg$2(err) {
|
|
|
11712
11728
|
return String(err);
|
|
11713
11729
|
}
|
|
11714
11730
|
//#endregion
|
|
11715
|
-
//#region ../types/dist/composition-
|
|
11731
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
11716
11732
|
/**
|
|
11717
11733
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11718
11734
|
*
|
|
@@ -12156,6 +12172,13 @@ var table = {
|
|
|
12156
12172
|
apply: () => {
|
|
12157
12173
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
12158
12174
|
}
|
|
12175
|
+
},
|
|
12176
|
+
schmitt: {
|
|
12177
|
+
minArgs: 3,
|
|
12178
|
+
maxArgs: 5,
|
|
12179
|
+
apply: () => {
|
|
12180
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
12181
|
+
}
|
|
12159
12182
|
}
|
|
12160
12183
|
};
|
|
12161
12184
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -12597,6 +12620,99 @@ function validateExpressionSource(src) {
|
|
|
12597
12620
|
return null;
|
|
12598
12621
|
}
|
|
12599
12622
|
/**
|
|
12623
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
12624
|
+
*
|
|
12625
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
12626
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
12627
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
12628
|
+
*
|
|
12629
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
12630
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
12631
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
12632
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
12633
|
+
* can move later without moving the others.
|
|
12634
|
+
*/
|
|
12635
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
12636
|
+
var APPLIANCE_KINDS = [
|
|
12637
|
+
"washer",
|
|
12638
|
+
"dryer",
|
|
12639
|
+
"dishwasher"
|
|
12640
|
+
];
|
|
12641
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
12642
|
+
/**
|
|
12643
|
+
* Statistics and integrals over a history read (D944).
|
|
12644
|
+
*
|
|
12645
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
12646
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
12647
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
12648
|
+
* as zero. A truncated read is not published.
|
|
12649
|
+
*/
|
|
12650
|
+
var STATISTIC_STATS = [
|
|
12651
|
+
"min",
|
|
12652
|
+
"max",
|
|
12653
|
+
"mean",
|
|
12654
|
+
"sum",
|
|
12655
|
+
"count",
|
|
12656
|
+
"change"
|
|
12657
|
+
];
|
|
12658
|
+
/**
|
|
12659
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
12660
|
+
*
|
|
12661
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
12662
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
12663
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
12664
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
12665
|
+
*/
|
|
12666
|
+
var MINUTE_MS = 6e4;
|
|
12667
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
12668
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
12669
|
+
var ROLLING_SPANS = [
|
|
12670
|
+
"1h",
|
|
12671
|
+
"24h",
|
|
12672
|
+
"2d",
|
|
12673
|
+
"7d",
|
|
12674
|
+
"30d",
|
|
12675
|
+
"custom"
|
|
12676
|
+
];
|
|
12677
|
+
var CALENDAR_PERIODS = [
|
|
12678
|
+
"today",
|
|
12679
|
+
"yesterday",
|
|
12680
|
+
"this-week",
|
|
12681
|
+
"this-month"
|
|
12682
|
+
];
|
|
12683
|
+
var RESET_PERIODS = [
|
|
12684
|
+
"never",
|
|
12685
|
+
"daily",
|
|
12686
|
+
"weekly",
|
|
12687
|
+
"monthly"
|
|
12688
|
+
];
|
|
12689
|
+
5 * MINUTE_MS;
|
|
12690
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
12691
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
12692
|
+
var rollingWindowObject = object({
|
|
12693
|
+
kind: literal("rolling"),
|
|
12694
|
+
span: _enum(ROLLING_SPANS),
|
|
12695
|
+
customMinutes: number().int().min(5).optional()
|
|
12696
|
+
}).check((payload) => {
|
|
12697
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
12698
|
+
code: "custom",
|
|
12699
|
+
message: "a custom range needs a duration in minutes",
|
|
12700
|
+
path: ["customMinutes"],
|
|
12701
|
+
input: payload.value
|
|
12702
|
+
});
|
|
12703
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
12704
|
+
code: "custom",
|
|
12705
|
+
message: "only a custom range carries a duration",
|
|
12706
|
+
path: ["customMinutes"],
|
|
12707
|
+
input: payload.value
|
|
12708
|
+
});
|
|
12709
|
+
});
|
|
12710
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
12711
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
12712
|
+
kind: literal("calendar"),
|
|
12713
|
+
period: _enum(CALENDAR_PERIODS)
|
|
12714
|
+
})]);
|
|
12715
|
+
/**
|
|
12600
12716
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
12601
12717
|
* id. Split out so helper schemas can name it without a cycle through
|
|
12602
12718
|
* `composition.ts` (D659).
|
|
@@ -12622,7 +12738,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
12622
12738
|
"occupancy",
|
|
12623
12739
|
"binary",
|
|
12624
12740
|
"switch",
|
|
12625
|
-
"light"
|
|
12741
|
+
"light",
|
|
12742
|
+
"fan",
|
|
12743
|
+
"cover",
|
|
12744
|
+
"valve",
|
|
12745
|
+
"lock",
|
|
12746
|
+
"media-player",
|
|
12747
|
+
"climate"
|
|
12626
12748
|
];
|
|
12627
12749
|
var NUMERIC_AGGREGATES = [
|
|
12628
12750
|
"mean",
|
|
@@ -12652,14 +12774,73 @@ var HelperMemberSchema = object({
|
|
|
12652
12774
|
cap: string().min(1),
|
|
12653
12775
|
fieldPath: string().min(1)
|
|
12654
12776
|
});
|
|
12655
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12777
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12778
|
+
object({
|
|
12779
|
+
kind: literal("group"),
|
|
12780
|
+
templateId: GroupTemplateIdSchema,
|
|
12781
|
+
aggregate: AggregateReducerSchema,
|
|
12782
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
12783
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
12784
|
+
active: ActiveCriterionSchema.optional()
|
|
12785
|
+
}),
|
|
12786
|
+
object({
|
|
12787
|
+
kind: literal("appliance"),
|
|
12788
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
12789
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
12790
|
+
thresholdWatts: number().positive(),
|
|
12791
|
+
startDwellMs: number().int().nonnegative(),
|
|
12792
|
+
stopDwellMs: number().int().nonnegative(),
|
|
12793
|
+
member: HelperMemberSchema
|
|
12794
|
+
}),
|
|
12795
|
+
object({
|
|
12796
|
+
kind: literal("statistic"),
|
|
12797
|
+
stat: _enum(STATISTIC_STATS),
|
|
12798
|
+
window: StatisticWindowSchema,
|
|
12799
|
+
source: HelperMemberSchema
|
|
12800
|
+
}),
|
|
12801
|
+
object({
|
|
12802
|
+
kind: literal("integral"),
|
|
12803
|
+
reset: _enum(RESET_PERIODS),
|
|
12804
|
+
output: _enum(["energy", "meter"]),
|
|
12805
|
+
source: HelperMemberSchema
|
|
12806
|
+
}),
|
|
12807
|
+
object({
|
|
12808
|
+
kind: literal("threshold"),
|
|
12809
|
+
source: HelperMemberSchema,
|
|
12810
|
+
high: number(),
|
|
12811
|
+
low: number(),
|
|
12812
|
+
onForMs: number().int().nonnegative(),
|
|
12813
|
+
offForMs: number().int().nonnegative()
|
|
12814
|
+
}),
|
|
12815
|
+
object({
|
|
12816
|
+
kind: literal("arithmetic"),
|
|
12817
|
+
op: _enum([
|
|
12818
|
+
"sum",
|
|
12819
|
+
"difference",
|
|
12820
|
+
"ratio"
|
|
12821
|
+
]),
|
|
12822
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
12823
|
+
}),
|
|
12824
|
+
object({
|
|
12825
|
+
kind: literal("expression"),
|
|
12826
|
+
expr: string().min(1),
|
|
12827
|
+
inputs: array(object({
|
|
12828
|
+
name: string().min(1),
|
|
12829
|
+
member: HelperMemberSchema
|
|
12830
|
+
})).min(1).max(64),
|
|
12831
|
+
output: _enum(["number", "boolean"])
|
|
12832
|
+
}),
|
|
12833
|
+
object({
|
|
12834
|
+
kind: literal("derivative"),
|
|
12835
|
+
window: RollingWindowSchema,
|
|
12836
|
+
per: _enum([
|
|
12837
|
+
"second",
|
|
12838
|
+
"minute",
|
|
12839
|
+
"hour"
|
|
12840
|
+
]),
|
|
12841
|
+
source: HelperMemberSchema
|
|
12842
|
+
})
|
|
12843
|
+
]);
|
|
12663
12844
|
/**
|
|
12664
12845
|
* A COMPOSITION: a device assembled from other devices' state (D659).
|
|
12665
12846
|
*
|
|
@@ -12741,6 +12922,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12741
12922
|
"all"
|
|
12742
12923
|
]),
|
|
12743
12924
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12925
|
+
/**
|
|
12926
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
12927
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
12928
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
12929
|
+
*/
|
|
12930
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
12744
12931
|
/** `value` is the reading; the others are the member counts. */
|
|
12745
12932
|
publish: _enum([
|
|
12746
12933
|
"value",
|
|
@@ -12754,6 +12941,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12754
12941
|
"omit",
|
|
12755
12942
|
"offline"
|
|
12756
12943
|
])
|
|
12944
|
+
}),
|
|
12945
|
+
object({
|
|
12946
|
+
kind: literal("series"),
|
|
12947
|
+
read: CompositionFieldReadSchema,
|
|
12948
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
12949
|
+
publish: _enum([
|
|
12950
|
+
"value",
|
|
12951
|
+
"included",
|
|
12952
|
+
"excluded",
|
|
12953
|
+
"total"
|
|
12954
|
+
]),
|
|
12955
|
+
/**
|
|
12956
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12957
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12958
|
+
*/
|
|
12959
|
+
empty: _enum([
|
|
12960
|
+
"null",
|
|
12961
|
+
"omit",
|
|
12962
|
+
"offline"
|
|
12963
|
+
])
|
|
12757
12964
|
})
|
|
12758
12965
|
]);
|
|
12759
12966
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -18262,7 +18469,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
18262
18469
|
*/
|
|
18263
18470
|
interactiveConnectPath: string().min(1).optional(),
|
|
18264
18471
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
18265
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
18472
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
18473
|
+
/**
|
|
18474
|
+
* The kind signs in through a server-held interactive session instead of
|
|
18475
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
18476
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
18477
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
18478
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
18479
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
18480
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
18481
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
18482
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
18483
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
18484
|
+
* offers it as the default path; the fields the session fills are
|
|
18485
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
18486
|
+
*/
|
|
18487
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
18266
18488
|
}))
|
|
18267
18489
|
});
|
|
18268
18490
|
var ListInputSchema = object({
|
|
@@ -19299,7 +19521,8 @@ var CompositionProblemSchema = object({
|
|
|
19299
19521
|
"native-capability-replace",
|
|
19300
19522
|
"mixed-quantity",
|
|
19301
19523
|
"helper-mismatch",
|
|
19302
|
-
"member-constraint"
|
|
19524
|
+
"member-constraint",
|
|
19525
|
+
"retention"
|
|
19303
19526
|
]),
|
|
19304
19527
|
path: string(),
|
|
19305
19528
|
message: string()
|
|
@@ -19533,13 +19756,17 @@ Object.freeze({
|
|
|
19533
19756
|
latchedAt: {
|
|
19534
19757
|
kind: "fixed",
|
|
19535
19758
|
result: ["number", "null"]
|
|
19759
|
+
},
|
|
19760
|
+
schmitt: {
|
|
19761
|
+
kind: "fixed",
|
|
19762
|
+
result: ["boolean", "null"]
|
|
19536
19763
|
}
|
|
19537
19764
|
});
|
|
19538
19765
|
/**
|
|
19539
19766
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
19540
19767
|
* Data, not a form default written into the block.
|
|
19541
19768
|
*/
|
|
19542
|
-
var NOW = {
|
|
19769
|
+
var NOW$2 = {
|
|
19543
19770
|
fieldPath: "lastFetchedAt",
|
|
19544
19771
|
expr: "now"
|
|
19545
19772
|
};
|
|
@@ -19553,6 +19780,8 @@ function numeric(input) {
|
|
|
19553
19780
|
family: "numeric",
|
|
19554
19781
|
deviceType: DeviceType.Sensor,
|
|
19555
19782
|
memberDeviceType: DeviceType.Sensor,
|
|
19783
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
19784
|
+
activeWhen: void 0,
|
|
19556
19785
|
commandCaps: [],
|
|
19557
19786
|
baseUnit: baseUnitOf(input.quantity),
|
|
19558
19787
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -19568,6 +19797,8 @@ function binary(input) {
|
|
|
19568
19797
|
family: "binary",
|
|
19569
19798
|
deviceType: DeviceType.Sensor,
|
|
19570
19799
|
memberDeviceType: DeviceType.Sensor,
|
|
19800
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
19801
|
+
activeWhen: void 0,
|
|
19571
19802
|
commandCaps: [],
|
|
19572
19803
|
quantity: "none",
|
|
19573
19804
|
baseUnit: void 0,
|
|
@@ -19585,7 +19816,7 @@ var GROUP_TEMPLATES = [
|
|
|
19585
19816
|
quantity: "temperature",
|
|
19586
19817
|
defaultAggregate: "mean",
|
|
19587
19818
|
empty: "null",
|
|
19588
|
-
companions: [NOW]
|
|
19819
|
+
companions: [NOW$2]
|
|
19589
19820
|
}),
|
|
19590
19821
|
numeric({
|
|
19591
19822
|
id: "humidity",
|
|
@@ -19596,7 +19827,7 @@ var GROUP_TEMPLATES = [
|
|
|
19596
19827
|
quantity: "humidity",
|
|
19597
19828
|
defaultAggregate: "mean",
|
|
19598
19829
|
empty: "null",
|
|
19599
|
-
companions: [NOW]
|
|
19830
|
+
companions: [NOW$2]
|
|
19600
19831
|
}),
|
|
19601
19832
|
numeric({
|
|
19602
19833
|
id: "pressure",
|
|
@@ -19607,7 +19838,7 @@ var GROUP_TEMPLATES = [
|
|
|
19607
19838
|
quantity: "pressure",
|
|
19608
19839
|
defaultAggregate: "mean",
|
|
19609
19840
|
empty: "null",
|
|
19610
|
-
companions: [NOW]
|
|
19841
|
+
companions: [NOW$2]
|
|
19611
19842
|
}),
|
|
19612
19843
|
numeric({
|
|
19613
19844
|
id: "illuminance",
|
|
@@ -19618,7 +19849,7 @@ var GROUP_TEMPLATES = [
|
|
|
19618
19849
|
quantity: "illuminance",
|
|
19619
19850
|
defaultAggregate: "mean",
|
|
19620
19851
|
empty: "null",
|
|
19621
|
-
companions: [NOW]
|
|
19852
|
+
companions: [NOW$2]
|
|
19622
19853
|
}),
|
|
19623
19854
|
numeric({
|
|
19624
19855
|
id: "power",
|
|
@@ -19629,7 +19860,7 @@ var GROUP_TEMPLATES = [
|
|
|
19629
19860
|
quantity: "power",
|
|
19630
19861
|
defaultAggregate: "sum",
|
|
19631
19862
|
empty: "omit",
|
|
19632
|
-
companions: [NOW]
|
|
19863
|
+
companions: [NOW$2]
|
|
19633
19864
|
}),
|
|
19634
19865
|
numeric({
|
|
19635
19866
|
id: "energy",
|
|
@@ -19640,7 +19871,7 @@ var GROUP_TEMPLATES = [
|
|
|
19640
19871
|
quantity: "energy",
|
|
19641
19872
|
defaultAggregate: "sum",
|
|
19642
19873
|
empty: "omit",
|
|
19643
|
-
companions: [NOW]
|
|
19874
|
+
companions: [NOW$2]
|
|
19644
19875
|
}),
|
|
19645
19876
|
numeric({
|
|
19646
19877
|
id: "battery",
|
|
@@ -19675,7 +19906,7 @@ var GROUP_TEMPLATES = [
|
|
|
19675
19906
|
quantity: "device",
|
|
19676
19907
|
defaultAggregate: "mean",
|
|
19677
19908
|
empty: "null",
|
|
19678
|
-
companions: [NOW]
|
|
19909
|
+
companions: [NOW$2]
|
|
19679
19910
|
}),
|
|
19680
19911
|
binary({
|
|
19681
19912
|
id: "motion",
|
|
@@ -19769,6 +20000,11 @@ var GROUP_TEMPLATES = [
|
|
|
19769
20000
|
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.",
|
|
19770
20001
|
deviceType: DeviceType.Switch,
|
|
19771
20002
|
outputCap: "switch",
|
|
20003
|
+
outputField: "on",
|
|
20004
|
+
member: {
|
|
20005
|
+
cap: "switch",
|
|
20006
|
+
fieldPath: "on"
|
|
20007
|
+
},
|
|
19772
20008
|
commandCaps: ["switch"]
|
|
19773
20009
|
}),
|
|
19774
20010
|
actuator({
|
|
@@ -19776,34 +20012,136 @@ var GROUP_TEMPLATES = [
|
|
|
19776
20012
|
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.",
|
|
19777
20013
|
deviceType: DeviceType.Light,
|
|
19778
20014
|
outputCap: "switch",
|
|
20015
|
+
outputField: "on",
|
|
20016
|
+
member: {
|
|
20017
|
+
cap: "switch",
|
|
20018
|
+
fieldPath: "on"
|
|
20019
|
+
},
|
|
19779
20020
|
commandCaps: [
|
|
19780
20021
|
"switch",
|
|
19781
20022
|
"brightness",
|
|
19782
20023
|
"color"
|
|
19783
20024
|
]
|
|
20025
|
+
}),
|
|
20026
|
+
actuator({
|
|
20027
|
+
id: "fan",
|
|
20028
|
+
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.",
|
|
20029
|
+
deviceType: DeviceType.Fan,
|
|
20030
|
+
outputCap: "switch",
|
|
20031
|
+
outputField: "on",
|
|
20032
|
+
member: {
|
|
20033
|
+
cap: "switch",
|
|
20034
|
+
fieldPath: "on"
|
|
20035
|
+
},
|
|
20036
|
+
commandCaps: ["switch", "fan-control"]
|
|
20037
|
+
}),
|
|
20038
|
+
actuator({
|
|
20039
|
+
id: "cover",
|
|
20040
|
+
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.",
|
|
20041
|
+
deviceType: DeviceType.Cover,
|
|
20042
|
+
outputCap: "group-active",
|
|
20043
|
+
outputField: "active",
|
|
20044
|
+
member: {
|
|
20045
|
+
cap: "cover",
|
|
20046
|
+
fieldPath: "state"
|
|
20047
|
+
},
|
|
20048
|
+
activeWhen: [
|
|
20049
|
+
"open",
|
|
20050
|
+
"opening",
|
|
20051
|
+
"stopped"
|
|
20052
|
+
],
|
|
20053
|
+
commandCaps: ["cover"]
|
|
20054
|
+
}),
|
|
20055
|
+
actuator({
|
|
20056
|
+
id: "valve",
|
|
20057
|
+
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.",
|
|
20058
|
+
deviceType: DeviceType.Valve,
|
|
20059
|
+
outputCap: "group-active",
|
|
20060
|
+
outputField: "active",
|
|
20061
|
+
member: {
|
|
20062
|
+
cap: "valve",
|
|
20063
|
+
fieldPath: "state"
|
|
20064
|
+
},
|
|
20065
|
+
activeWhen: [
|
|
20066
|
+
"open",
|
|
20067
|
+
"opening",
|
|
20068
|
+
"stopped"
|
|
20069
|
+
],
|
|
20070
|
+
commandCaps: ["valve"]
|
|
20071
|
+
}),
|
|
20072
|
+
actuator({
|
|
20073
|
+
id: "lock",
|
|
20074
|
+
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.",
|
|
20075
|
+
deviceType: DeviceType.Lock,
|
|
20076
|
+
outputCap: "group-active",
|
|
20077
|
+
outputField: "active",
|
|
20078
|
+
member: {
|
|
20079
|
+
cap: "lock-control",
|
|
20080
|
+
fieldPath: "state"
|
|
20081
|
+
},
|
|
20082
|
+
activeWhen: ["locked"],
|
|
20083
|
+
commandCaps: ["lock-control"]
|
|
20084
|
+
}),
|
|
20085
|
+
actuator({
|
|
20086
|
+
id: "media-player",
|
|
20087
|
+
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.",
|
|
20088
|
+
deviceType: DeviceType.MediaPlayer,
|
|
20089
|
+
outputCap: "group-active",
|
|
20090
|
+
outputField: "active",
|
|
20091
|
+
member: {
|
|
20092
|
+
cap: "media-player",
|
|
20093
|
+
fieldPath: "state"
|
|
20094
|
+
},
|
|
20095
|
+
activeWhen: ["playing", "buffering"],
|
|
20096
|
+
commandCaps: ["media-player"]
|
|
20097
|
+
}),
|
|
20098
|
+
actuator({
|
|
20099
|
+
id: "climate",
|
|
20100
|
+
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.",
|
|
20101
|
+
deviceType: DeviceType.Thermostat,
|
|
20102
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
20103
|
+
outputCap: "group-active",
|
|
20104
|
+
outputField: "active",
|
|
20105
|
+
member: {
|
|
20106
|
+
cap: "climate-control",
|
|
20107
|
+
fieldPath: "mode"
|
|
20108
|
+
},
|
|
20109
|
+
activeWhen: [
|
|
20110
|
+
"heat",
|
|
20111
|
+
"cool",
|
|
20112
|
+
"auto",
|
|
20113
|
+
"heat_cool",
|
|
20114
|
+
"fan_only",
|
|
20115
|
+
"dry"
|
|
20116
|
+
],
|
|
20117
|
+
commandCaps: ["climate-control"]
|
|
19784
20118
|
})
|
|
19785
20119
|
];
|
|
19786
20120
|
function actuator(input) {
|
|
19787
20121
|
return {
|
|
19788
|
-
|
|
20122
|
+
id: input.id,
|
|
20123
|
+
summary: input.summary,
|
|
20124
|
+
deviceType: input.deviceType,
|
|
20125
|
+
outputCap: input.outputCap,
|
|
20126
|
+
outputField: input.outputField,
|
|
20127
|
+
commandCaps: input.commandCaps,
|
|
19789
20128
|
family: "actuator",
|
|
19790
20129
|
role: void 0,
|
|
19791
20130
|
memberDeviceType: input.deviceType,
|
|
19792
|
-
|
|
20131
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
20132
|
+
activeWhen: input.activeWhen,
|
|
19793
20133
|
quantity: "none",
|
|
19794
20134
|
baseUnit: void 0,
|
|
19795
20135
|
aggregates: BINARY_AGGREGATES,
|
|
19796
20136
|
defaultAggregate: "any",
|
|
19797
20137
|
empty: "offline",
|
|
19798
|
-
accept: [
|
|
19799
|
-
cap: "switch",
|
|
19800
|
-
fieldPath: "on"
|
|
19801
|
-
}],
|
|
20138
|
+
accept: [input.member],
|
|
19802
20139
|
companions: [CHANGED]
|
|
19803
20140
|
};
|
|
19804
20141
|
}
|
|
19805
20142
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
19806
20143
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
20144
|
+
DeviceType.Camera;
|
|
19807
20145
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
19808
20146
|
/**
|
|
19809
20147
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -44818,7 +45156,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
44818
45156
|
});
|
|
44819
45157
|
/**
|
|
44820
45158
|
* Optional, richer endpoint shape returned by providers that expose
|
|
44821
|
-
* MORE than one ingress concurrently (Tailscale
|
|
45159
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
44822
45160
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
44823
45161
|
* the originating provider config (mode + sourcePort) so the
|
|
44824
45162
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -47729,7 +48067,20 @@ var NcRuleInputSchema = object({
|
|
|
47729
48067
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
47730
48068
|
* path does not run Zod defaults.
|
|
47731
48069
|
*/
|
|
47732
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
48070
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
48071
|
+
/**
|
|
48072
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
48073
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
48074
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
48075
|
+
* same mark the Library writes, and records whose notification it was and
|
|
48076
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
48077
|
+
*
|
|
48078
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
48079
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
48080
|
+
* authored before this field meant. An editor turns it off by writing
|
|
48081
|
+
* `false`, so it needs no `clear` key.
|
|
48082
|
+
*/
|
|
48083
|
+
askVerdict: boolean().optional()
|
|
47733
48084
|
});
|
|
47734
48085
|
/**
|
|
47735
48086
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -59109,7 +59460,7 @@ var BatteryStatusSchema = object({
|
|
|
59109
59460
|
*/
|
|
59110
59461
|
binary: boolean().optional().meta({ label: "Binary indicator" })
|
|
59111
59462
|
});
|
|
59112
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
|
|
59463
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter;
|
|
59113
59464
|
method(object({
|
|
59114
59465
|
deviceId: number(),
|
|
59115
59466
|
/** Bound on the wait. Sensible range 3000–10000ms. */
|
|
@@ -60862,7 +61213,13 @@ results: array(object({
|
|
|
60862
61213
|
/** Ms epoch of the attempt. */
|
|
60863
61214
|
at: number()
|
|
60864
61215
|
})) });
|
|
60865
|
-
DeviceType.Switch, DeviceType.Light;
|
|
61216
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
61217
|
+
object({
|
|
61218
|
+
active: boolean().meta({ label: "Active" }),
|
|
61219
|
+
/** Ms epoch when the slice was last updated. */
|
|
61220
|
+
lastChangedAt: number()
|
|
61221
|
+
});
|
|
61222
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
60866
61223
|
object({
|
|
60867
61224
|
/** Members whose current value entered the aggregate. */
|
|
60868
61225
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -60880,7 +61237,7 @@ object({
|
|
|
60880
61237
|
label: "Members"
|
|
60881
61238
|
}))
|
|
60882
61239
|
});
|
|
60883
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
61240
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
60884
61241
|
object({
|
|
60885
61242
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60886
61243
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -61787,7 +62144,14 @@ DeviceType.Lock, method(object({
|
|
|
61787
62144
|
auth: "protected"
|
|
61788
62145
|
}), method(object({
|
|
61789
62146
|
deviceId: number().int().nonnegative(),
|
|
61790
|
-
code: string().min(1).optional()
|
|
62147
|
+
code: string().min(1).optional(),
|
|
62148
|
+
/**
|
|
62149
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
62150
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
62151
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
62152
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
62153
|
+
*/
|
|
62154
|
+
confirm: boolean().optional()
|
|
61791
62155
|
}), _void(), {
|
|
61792
62156
|
kind: "mutation",
|
|
61793
62157
|
auth: "protected"
|
|
@@ -61795,6 +62159,11 @@ DeviceType.Lock, method(object({
|
|
|
61795
62159
|
kind: "mutation",
|
|
61796
62160
|
auth: "protected"
|
|
61797
62161
|
});
|
|
62162
|
+
object({
|
|
62163
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
62164
|
+
lastFetchedAt: number()
|
|
62165
|
+
});
|
|
62166
|
+
DeviceType.Sensor;
|
|
61798
62167
|
/**
|
|
61799
62168
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
61800
62169
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -64443,9 +64812,9 @@ object({
|
|
|
64443
64812
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64444
64813
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64445
64814
|
/** Voltage in volts. */
|
|
64446
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
64815
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
64447
64816
|
/** Current in amperes. */
|
|
64448
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
64817
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
64449
64818
|
/** Apparent power in volt-amperes. */
|
|
64450
64819
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64451
64820
|
/** Power factor (0..1) if reported. */
|
|
@@ -64453,7 +64822,23 @@ object({
|
|
|
64453
64822
|
/** Ms epoch when the slice was last updated. */
|
|
64454
64823
|
lastFetchedAt: number()
|
|
64455
64824
|
});
|
|
64456
|
-
|
|
64825
|
+
[
|
|
64826
|
+
DeviceType.Sensor,
|
|
64827
|
+
DeviceType.Switch,
|
|
64828
|
+
DeviceType.Light,
|
|
64829
|
+
DeviceType.Fan,
|
|
64830
|
+
DeviceType.Climate,
|
|
64831
|
+
DeviceType.Thermostat,
|
|
64832
|
+
DeviceType.Humidifier,
|
|
64833
|
+
DeviceType.WaterHeater,
|
|
64834
|
+
DeviceType.MediaPlayer,
|
|
64835
|
+
DeviceType.Washer,
|
|
64836
|
+
DeviceType.Dryer,
|
|
64837
|
+
DeviceType.Dishwasher,
|
|
64838
|
+
DeviceType.Vacuum,
|
|
64839
|
+
DeviceType.LawnMower,
|
|
64840
|
+
DeviceType.PetFeeder
|
|
64841
|
+
].filter((type) => type !== DeviceType.Sensor);
|
|
64457
64842
|
/**
|
|
64458
64843
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
64459
64844
|
* on `DeviceType.Presence`. Read-only — no setters: presence is
|
|
@@ -64900,7 +65285,7 @@ object({
|
|
|
64900
65285
|
phase: string().nullable()
|
|
64901
65286
|
});
|
|
64902
65287
|
Object.values(DeviceType);
|
|
64903
|
-
DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
65288
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
64904
65289
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
|
|
64905
65290
|
kind: "mutation",
|
|
64906
65291
|
auth: "admin"
|
|
@@ -66973,7 +67358,7 @@ object({
|
|
|
66973
67358
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
66974
67359
|
lastChangedAt: number()
|
|
66975
67360
|
});
|
|
66976
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
67361
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
66977
67362
|
deviceId: number(),
|
|
66978
67363
|
on: boolean()
|
|
66979
67364
|
}), _void(), {
|
|
@@ -68725,8 +69110,9 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
68725
69110
|
kind: "mutation",
|
|
68726
69111
|
auth: "admin"
|
|
68727
69112
|
});
|
|
69113
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
68728
69114
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
68729
|
-
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;
|
|
69115
|
+
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;
|
|
68730
69116
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
68731
69117
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
68732
69118
|
new Set(CAP_NAMES);
|
|
@@ -68779,7 +69165,7 @@ var AccessoryKind = {
|
|
|
68779
69165
|
PrivacyMask: DeviceRole.PrivacyMask
|
|
68780
69166
|
};
|
|
68781
69167
|
AccessoryKind.Siren, AccessoryKind.Floodlight, AccessoryKind.Spotlight, AccessoryKind.PirSensor, AccessoryKind.Chime, AccessoryKind.Autotrack, AccessoryKind.Nightvision, AccessoryKind.PrivacyMask;
|
|
68782
|
-
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;
|
|
69168
|
+
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;
|
|
68783
69169
|
new Set(Object.values(DeviceType));
|
|
68784
69170
|
Object.freeze({
|
|
68785
69171
|
"accessories.getStatus": {
|
|
@@ -72002,6 +72388,13 @@ Object.freeze({
|
|
|
72002
72388
|
access: "view",
|
|
72003
72389
|
role: "viewer"
|
|
72004
72390
|
},
|
|
72391
|
+
"groupActive.getStatus": {
|
|
72392
|
+
capName: "group-active",
|
|
72393
|
+
capScope: "device",
|
|
72394
|
+
addonId: null,
|
|
72395
|
+
access: "view",
|
|
72396
|
+
role: "viewer"
|
|
72397
|
+
},
|
|
72005
72398
|
"groupCommands.getStatus": {
|
|
72006
72399
|
capName: "group-commands",
|
|
72007
72400
|
capScope: "device",
|
|
@@ -72968,6 +73361,13 @@ Object.freeze({
|
|
|
72968
73361
|
access: "create",
|
|
72969
73362
|
role: "admin"
|
|
72970
73363
|
},
|
|
73364
|
+
"meter.getStatus": {
|
|
73365
|
+
capName: "meter",
|
|
73366
|
+
capScope: "device",
|
|
73367
|
+
addonId: null,
|
|
73368
|
+
access: "view",
|
|
73369
|
+
role: "viewer"
|
|
73370
|
+
},
|
|
72971
73371
|
"metricsProvider.collectSnapshot": {
|
|
72972
73372
|
capName: "metrics-provider",
|
|
72973
73373
|
capScope: "system",
|
|
@@ -81066,7 +81466,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
81066
81466
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
81067
81467
|
icon: "square"
|
|
81068
81468
|
}
|
|
81069
|
-
}
|
|
81469
|
+
},
|
|
81470
|
+
overrides: { byType: {
|
|
81471
|
+
[DeviceType.Washer]: {
|
|
81472
|
+
state: { running: {
|
|
81473
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
81474
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
81475
|
+
} },
|
|
81476
|
+
events: {
|
|
81477
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
81478
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
81479
|
+
}
|
|
81480
|
+
},
|
|
81481
|
+
[DeviceType.Dryer]: {
|
|
81482
|
+
state: { running: {
|
|
81483
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
81484
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
81485
|
+
} },
|
|
81486
|
+
events: {
|
|
81487
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
81488
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
81489
|
+
}
|
|
81490
|
+
},
|
|
81491
|
+
[DeviceType.Dishwasher]: {
|
|
81492
|
+
state: { running: {
|
|
81493
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
81494
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
81495
|
+
} },
|
|
81496
|
+
events: {
|
|
81497
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
81498
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
81499
|
+
}
|
|
81500
|
+
}
|
|
81501
|
+
} }
|
|
81070
81502
|
},
|
|
81071
81503
|
update: {
|
|
81072
81504
|
scope: "device",
|
|
@@ -81838,6 +82270,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
81838
82270
|
icon: "flame"
|
|
81839
82271
|
}]
|
|
81840
82272
|
},
|
|
82273
|
+
"group-active": {
|
|
82274
|
+
scope: "device",
|
|
82275
|
+
noun: t("Group state", "Stato del gruppo")
|
|
82276
|
+
},
|
|
81841
82277
|
"group-commands": {
|
|
81842
82278
|
scope: "device",
|
|
81843
82279
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -81894,6 +82330,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
81894
82330
|
}],
|
|
81895
82331
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
81896
82332
|
},
|
|
82333
|
+
meter: {
|
|
82334
|
+
scope: "device",
|
|
82335
|
+
noun: t("Meter", "Contatore"),
|
|
82336
|
+
state: [{
|
|
82337
|
+
kind: "numeric",
|
|
82338
|
+
field: "value",
|
|
82339
|
+
quantity: t("the total", "il totale"),
|
|
82340
|
+
label: t("Total", "Totale"),
|
|
82341
|
+
icon: "gauge"
|
|
82342
|
+
}]
|
|
82343
|
+
},
|
|
81897
82344
|
"numeric-sensor": {
|
|
81898
82345
|
scope: "device",
|
|
81899
82346
|
noun: t("Sensor", "Sensore"),
|
|
@@ -82366,7 +82813,7 @@ function projectAction(cap, action) {
|
|
|
82366
82813
|
};
|
|
82367
82814
|
}
|
|
82368
82815
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
82369
|
-
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;
|
|
82816
|
+
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;
|
|
82370
82817
|
/**
|
|
82371
82818
|
* Heuristic check — `device.features?.includes(profile.when.hasFeature)`.
|
|
82372
82819
|
*/
|
|
@@ -82396,6 +82843,45 @@ function resolveDeviceProfile(features) {
|
|
|
82396
82843
|
for (const profile of DEVICE_PROFILES) if (deviceMatchesProfile(features, profile)) return profile;
|
|
82397
82844
|
return null;
|
|
82398
82845
|
}
|
|
82846
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
82847
|
+
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.";
|
|
82848
|
+
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.";
|
|
82849
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
82850
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
82851
|
+
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.";
|
|
82852
|
+
function withheld(reason) {
|
|
82853
|
+
return {
|
|
82854
|
+
[DeviceType.Washer]: {
|
|
82855
|
+
exported: false,
|
|
82856
|
+
reason
|
|
82857
|
+
},
|
|
82858
|
+
[DeviceType.Dryer]: {
|
|
82859
|
+
exported: false,
|
|
82860
|
+
reason
|
|
82861
|
+
},
|
|
82862
|
+
[DeviceType.Dishwasher]: {
|
|
82863
|
+
exported: false,
|
|
82864
|
+
reason
|
|
82865
|
+
}
|
|
82866
|
+
};
|
|
82867
|
+
}
|
|
82868
|
+
function offered(received) {
|
|
82869
|
+
return {
|
|
82870
|
+
[DeviceType.Washer]: {
|
|
82871
|
+
exported: true,
|
|
82872
|
+
as: received
|
|
82873
|
+
},
|
|
82874
|
+
[DeviceType.Dryer]: {
|
|
82875
|
+
exported: true,
|
|
82876
|
+
as: received
|
|
82877
|
+
},
|
|
82878
|
+
[DeviceType.Dishwasher]: {
|
|
82879
|
+
exported: true,
|
|
82880
|
+
as: received
|
|
82881
|
+
}
|
|
82882
|
+
};
|
|
82883
|
+
}
|
|
82884
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
82399
82885
|
Object.freeze({
|
|
82400
82886
|
"accessories.getStatus": [{
|
|
82401
82887
|
name: "deviceId",
|
|
@@ -83362,6 +83848,11 @@ Object.freeze({
|
|
|
83362
83848
|
form: "single",
|
|
83363
83849
|
optional: false
|
|
83364
83850
|
}],
|
|
83851
|
+
"groupActive.getStatus": [{
|
|
83852
|
+
name: "deviceId",
|
|
83853
|
+
form: "single",
|
|
83854
|
+
optional: false
|
|
83855
|
+
}],
|
|
83365
83856
|
"groupCommands.getStatus": [{
|
|
83366
83857
|
name: "deviceId",
|
|
83367
83858
|
form: "single",
|
|
@@ -83572,6 +84063,11 @@ Object.freeze({
|
|
|
83572
84063
|
form: "single",
|
|
83573
84064
|
optional: false
|
|
83574
84065
|
}],
|
|
84066
|
+
"meter.getStatus": [{
|
|
84067
|
+
name: "deviceId",
|
|
84068
|
+
form: "single",
|
|
84069
|
+
optional: false
|
|
84070
|
+
}],
|
|
83575
84071
|
"motion.getStatus": [{
|
|
83576
84072
|
name: "deviceId",
|
|
83577
84073
|
form: "single",
|
|
@@ -85276,7 +85772,6 @@ var BucketAccumulator = class {
|
|
|
85276
85772
|
return n;
|
|
85277
85773
|
}
|
|
85278
85774
|
};
|
|
85279
|
-
DeviceType.Camera;
|
|
85280
85775
|
/**
|
|
85281
85776
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
85282
85777
|
* `z.infer`, they do not restate the shape.
|