@camstack/addon-provider-wyze 0.2.159 → 0.2.160
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 +29 -8
- package/dist/addon.js +680 -45
- package/dist/addon.mjs +680 -45
- package/package.json +1 -1
package/dist/addon.mjs
CHANGED
|
@@ -5453,7 +5453,7 @@ var ZodIssueCode = {
|
|
|
5453
5453
|
var ZodFirstPartyTypeKind;
|
|
5454
5454
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5455
5455
|
//#endregion
|
|
5456
|
-
//#region ../types/dist/sleep
|
|
5456
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5457
5457
|
/**
|
|
5458
5458
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5459
5459
|
* window to float samples (D455).
|
|
@@ -8646,6 +8646,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8646
8646
|
"filesystem-browse",
|
|
8647
8647
|
"flood",
|
|
8648
8648
|
"gas",
|
|
8649
|
+
"group-active",
|
|
8649
8650
|
"group-commands",
|
|
8650
8651
|
"group-status",
|
|
8651
8652
|
"heating-valve",
|
|
@@ -8668,6 +8669,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8668
8669
|
"login-method",
|
|
8669
8670
|
"media-player",
|
|
8670
8671
|
"mesh-network",
|
|
8672
|
+
"meter",
|
|
8671
8673
|
"metrics-provider",
|
|
8672
8674
|
"model-convert",
|
|
8673
8675
|
"model-distributor",
|
|
@@ -9466,6 +9468,10 @@ Object.freeze({
|
|
|
9466
9468
|
"path": "detected",
|
|
9467
9469
|
"valueType": "boolean"
|
|
9468
9470
|
}],
|
|
9471
|
+
"group-active": [{
|
|
9472
|
+
"path": "active",
|
|
9473
|
+
"valueType": "boolean"
|
|
9474
|
+
}],
|
|
9469
9475
|
"group-status": [
|
|
9470
9476
|
{
|
|
9471
9477
|
"path": "included",
|
|
@@ -9725,6 +9731,10 @@ Object.freeze({
|
|
|
9725
9731
|
]
|
|
9726
9732
|
}
|
|
9727
9733
|
],
|
|
9734
|
+
"meter": [{
|
|
9735
|
+
"path": "value",
|
|
9736
|
+
"valueType": "number"
|
|
9737
|
+
}],
|
|
9728
9738
|
"motion": [
|
|
9729
9739
|
{
|
|
9730
9740
|
"path": "detected",
|
|
@@ -10482,7 +10492,7 @@ function userError(code, params, englishFallback) {
|
|
|
10482
10492
|
return new CamstackError(code, params, englishFallback);
|
|
10483
10493
|
}
|
|
10484
10494
|
//#endregion
|
|
10485
|
-
//#region ../types/dist/err-msg-
|
|
10495
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
10486
10496
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
10487
10497
|
DeviceType["Camera"] = "camera";
|
|
10488
10498
|
DeviceType["Hub"] = "hub";
|
|
@@ -10576,8 +10586,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
10576
10586
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
10577
10587
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
10578
10588
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
10579
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10589
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10590
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
10580
10591
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
10592
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
10593
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
10594
|
+
DeviceType["Washer"] = "washer";
|
|
10595
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
10596
|
+
DeviceType["Dryer"] = "dryer";
|
|
10581
10597
|
return DeviceType;
|
|
10582
10598
|
}({});
|
|
10583
10599
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -10835,7 +10851,7 @@ function errMsg(err) {
|
|
|
10835
10851
|
return String(err);
|
|
10836
10852
|
}
|
|
10837
10853
|
//#endregion
|
|
10838
|
-
//#region ../types/dist/composition-
|
|
10854
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
10839
10855
|
/**
|
|
10840
10856
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10841
10857
|
*
|
|
@@ -11150,6 +11166,13 @@ var table = {
|
|
|
11150
11166
|
apply: () => {
|
|
11151
11167
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11152
11168
|
}
|
|
11169
|
+
},
|
|
11170
|
+
schmitt: {
|
|
11171
|
+
minArgs: 3,
|
|
11172
|
+
maxArgs: 5,
|
|
11173
|
+
apply: () => {
|
|
11174
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11175
|
+
}
|
|
11153
11176
|
}
|
|
11154
11177
|
};
|
|
11155
11178
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11591,6 +11614,99 @@ function validateExpressionSource(src) {
|
|
|
11591
11614
|
return null;
|
|
11592
11615
|
}
|
|
11593
11616
|
/**
|
|
11617
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
11618
|
+
*
|
|
11619
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
11620
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
11621
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
11622
|
+
*
|
|
11623
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
11624
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
11625
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
11626
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
11627
|
+
* can move later without moving the others.
|
|
11628
|
+
*/
|
|
11629
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
11630
|
+
var APPLIANCE_KINDS = [
|
|
11631
|
+
"washer",
|
|
11632
|
+
"dryer",
|
|
11633
|
+
"dishwasher"
|
|
11634
|
+
];
|
|
11635
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11636
|
+
/**
|
|
11637
|
+
* Statistics and integrals over a history read (D944).
|
|
11638
|
+
*
|
|
11639
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11640
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11641
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11642
|
+
* as zero. A truncated read is not published.
|
|
11643
|
+
*/
|
|
11644
|
+
var STATISTIC_STATS = [
|
|
11645
|
+
"min",
|
|
11646
|
+
"max",
|
|
11647
|
+
"mean",
|
|
11648
|
+
"sum",
|
|
11649
|
+
"count",
|
|
11650
|
+
"change"
|
|
11651
|
+
];
|
|
11652
|
+
/**
|
|
11653
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11654
|
+
*
|
|
11655
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11656
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11657
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11658
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11659
|
+
*/
|
|
11660
|
+
var MINUTE_MS = 6e4;
|
|
11661
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11662
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11663
|
+
var ROLLING_SPANS = [
|
|
11664
|
+
"1h",
|
|
11665
|
+
"24h",
|
|
11666
|
+
"2d",
|
|
11667
|
+
"7d",
|
|
11668
|
+
"30d",
|
|
11669
|
+
"custom"
|
|
11670
|
+
];
|
|
11671
|
+
var CALENDAR_PERIODS = [
|
|
11672
|
+
"today",
|
|
11673
|
+
"yesterday",
|
|
11674
|
+
"this-week",
|
|
11675
|
+
"this-month"
|
|
11676
|
+
];
|
|
11677
|
+
var RESET_PERIODS = [
|
|
11678
|
+
"never",
|
|
11679
|
+
"daily",
|
|
11680
|
+
"weekly",
|
|
11681
|
+
"monthly"
|
|
11682
|
+
];
|
|
11683
|
+
5 * MINUTE_MS;
|
|
11684
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11685
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11686
|
+
var rollingWindowObject = object({
|
|
11687
|
+
kind: literal("rolling"),
|
|
11688
|
+
span: _enum(ROLLING_SPANS),
|
|
11689
|
+
customMinutes: number().int().min(5).optional()
|
|
11690
|
+
}).check((payload) => {
|
|
11691
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11692
|
+
code: "custom",
|
|
11693
|
+
message: "a custom range needs a duration in minutes",
|
|
11694
|
+
path: ["customMinutes"],
|
|
11695
|
+
input: payload.value
|
|
11696
|
+
});
|
|
11697
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11698
|
+
code: "custom",
|
|
11699
|
+
message: "only a custom range carries a duration",
|
|
11700
|
+
path: ["customMinutes"],
|
|
11701
|
+
input: payload.value
|
|
11702
|
+
});
|
|
11703
|
+
});
|
|
11704
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
11705
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
11706
|
+
kind: literal("calendar"),
|
|
11707
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11708
|
+
})]);
|
|
11709
|
+
/**
|
|
11594
11710
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11595
11711
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11596
11712
|
* `composition.ts` (D659).
|
|
@@ -11616,7 +11732,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11616
11732
|
"occupancy",
|
|
11617
11733
|
"binary",
|
|
11618
11734
|
"switch",
|
|
11619
|
-
"light"
|
|
11735
|
+
"light",
|
|
11736
|
+
"fan",
|
|
11737
|
+
"cover",
|
|
11738
|
+
"valve",
|
|
11739
|
+
"lock",
|
|
11740
|
+
"media-player",
|
|
11741
|
+
"climate"
|
|
11620
11742
|
];
|
|
11621
11743
|
var NUMERIC_AGGREGATES = [
|
|
11622
11744
|
"mean",
|
|
@@ -11646,14 +11768,73 @@ var HelperMemberSchema = object({
|
|
|
11646
11768
|
cap: string().min(1),
|
|
11647
11769
|
fieldPath: string().min(1)
|
|
11648
11770
|
});
|
|
11649
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11650
|
-
|
|
11651
|
-
|
|
11652
|
-
|
|
11653
|
-
|
|
11654
|
-
|
|
11655
|
-
|
|
11656
|
-
|
|
11771
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11772
|
+
object({
|
|
11773
|
+
kind: literal("group"),
|
|
11774
|
+
templateId: GroupTemplateIdSchema,
|
|
11775
|
+
aggregate: AggregateReducerSchema,
|
|
11776
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11777
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11778
|
+
active: ActiveCriterionSchema.optional()
|
|
11779
|
+
}),
|
|
11780
|
+
object({
|
|
11781
|
+
kind: literal("appliance"),
|
|
11782
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
11783
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
11784
|
+
thresholdWatts: number().positive(),
|
|
11785
|
+
startDwellMs: number().int().nonnegative(),
|
|
11786
|
+
stopDwellMs: number().int().nonnegative(),
|
|
11787
|
+
member: HelperMemberSchema
|
|
11788
|
+
}),
|
|
11789
|
+
object({
|
|
11790
|
+
kind: literal("statistic"),
|
|
11791
|
+
stat: _enum(STATISTIC_STATS),
|
|
11792
|
+
window: StatisticWindowSchema,
|
|
11793
|
+
source: HelperMemberSchema
|
|
11794
|
+
}),
|
|
11795
|
+
object({
|
|
11796
|
+
kind: literal("integral"),
|
|
11797
|
+
reset: _enum(RESET_PERIODS),
|
|
11798
|
+
output: _enum(["energy", "meter"]),
|
|
11799
|
+
source: HelperMemberSchema
|
|
11800
|
+
}),
|
|
11801
|
+
object({
|
|
11802
|
+
kind: literal("threshold"),
|
|
11803
|
+
source: HelperMemberSchema,
|
|
11804
|
+
high: number(),
|
|
11805
|
+
low: number(),
|
|
11806
|
+
onForMs: number().int().nonnegative(),
|
|
11807
|
+
offForMs: number().int().nonnegative()
|
|
11808
|
+
}),
|
|
11809
|
+
object({
|
|
11810
|
+
kind: literal("arithmetic"),
|
|
11811
|
+
op: _enum([
|
|
11812
|
+
"sum",
|
|
11813
|
+
"difference",
|
|
11814
|
+
"ratio"
|
|
11815
|
+
]),
|
|
11816
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
11817
|
+
}),
|
|
11818
|
+
object({
|
|
11819
|
+
kind: literal("expression"),
|
|
11820
|
+
expr: string().min(1),
|
|
11821
|
+
inputs: array(object({
|
|
11822
|
+
name: string().min(1),
|
|
11823
|
+
member: HelperMemberSchema
|
|
11824
|
+
})).min(1).max(64),
|
|
11825
|
+
output: _enum(["number", "boolean"])
|
|
11826
|
+
}),
|
|
11827
|
+
object({
|
|
11828
|
+
kind: literal("derivative"),
|
|
11829
|
+
window: RollingWindowSchema,
|
|
11830
|
+
per: _enum([
|
|
11831
|
+
"second",
|
|
11832
|
+
"minute",
|
|
11833
|
+
"hour"
|
|
11834
|
+
]),
|
|
11835
|
+
source: HelperMemberSchema
|
|
11836
|
+
})
|
|
11837
|
+
]);
|
|
11657
11838
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11658
11839
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11659
11840
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -11714,6 +11895,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11714
11895
|
"all"
|
|
11715
11896
|
]),
|
|
11716
11897
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11898
|
+
/**
|
|
11899
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
11900
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
11901
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
11902
|
+
*/
|
|
11903
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
11717
11904
|
/** `value` is the reading; the others are the member counts. */
|
|
11718
11905
|
publish: _enum([
|
|
11719
11906
|
"value",
|
|
@@ -11727,6 +11914,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11727
11914
|
"omit",
|
|
11728
11915
|
"offline"
|
|
11729
11916
|
])
|
|
11917
|
+
}),
|
|
11918
|
+
object({
|
|
11919
|
+
kind: literal("series"),
|
|
11920
|
+
read: CompositionFieldReadSchema,
|
|
11921
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
11922
|
+
publish: _enum([
|
|
11923
|
+
"value",
|
|
11924
|
+
"included",
|
|
11925
|
+
"excluded",
|
|
11926
|
+
"total"
|
|
11927
|
+
]),
|
|
11928
|
+
/**
|
|
11929
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
11930
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
11931
|
+
*/
|
|
11932
|
+
empty: _enum([
|
|
11933
|
+
"null",
|
|
11934
|
+
"omit",
|
|
11935
|
+
"offline"
|
|
11936
|
+
])
|
|
11730
11937
|
})
|
|
11731
11938
|
]);
|
|
11732
11939
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -16906,7 +17113,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
16906
17113
|
*/
|
|
16907
17114
|
interactiveConnectPath: string().min(1).optional(),
|
|
16908
17115
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
16909
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
17116
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
17117
|
+
/**
|
|
17118
|
+
* The kind signs in through a server-held interactive session instead of
|
|
17119
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
17120
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
17121
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
17122
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
17123
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
17124
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
17125
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
17126
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
17127
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
17128
|
+
* offers it as the default path; the fields the session fills are
|
|
17129
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
17130
|
+
*/
|
|
17131
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
16910
17132
|
}))
|
|
16911
17133
|
});
|
|
16912
17134
|
var ListInputSchema = object({
|
|
@@ -18011,7 +18233,8 @@ var CompositionProblemSchema = object({
|
|
|
18011
18233
|
"native-capability-replace",
|
|
18012
18234
|
"mixed-quantity",
|
|
18013
18235
|
"helper-mismatch",
|
|
18014
|
-
"member-constraint"
|
|
18236
|
+
"member-constraint",
|
|
18237
|
+
"retention"
|
|
18015
18238
|
]),
|
|
18016
18239
|
path: string(),
|
|
18017
18240
|
message: string()
|
|
@@ -18245,13 +18468,17 @@ Object.freeze({
|
|
|
18245
18468
|
latchedAt: {
|
|
18246
18469
|
kind: "fixed",
|
|
18247
18470
|
result: ["number", "null"]
|
|
18471
|
+
},
|
|
18472
|
+
schmitt: {
|
|
18473
|
+
kind: "fixed",
|
|
18474
|
+
result: ["boolean", "null"]
|
|
18248
18475
|
}
|
|
18249
18476
|
});
|
|
18250
18477
|
/**
|
|
18251
18478
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18252
18479
|
* Data, not a form default written into the block.
|
|
18253
18480
|
*/
|
|
18254
|
-
var NOW = {
|
|
18481
|
+
var NOW$2 = {
|
|
18255
18482
|
fieldPath: "lastFetchedAt",
|
|
18256
18483
|
expr: "now"
|
|
18257
18484
|
};
|
|
@@ -18265,6 +18492,8 @@ function numeric(input) {
|
|
|
18265
18492
|
family: "numeric",
|
|
18266
18493
|
deviceType: DeviceType.Sensor,
|
|
18267
18494
|
memberDeviceType: DeviceType.Sensor,
|
|
18495
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18496
|
+
activeWhen: void 0,
|
|
18268
18497
|
commandCaps: [],
|
|
18269
18498
|
baseUnit: baseUnitOf(input.quantity),
|
|
18270
18499
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18280,6 +18509,8 @@ function binary(input) {
|
|
|
18280
18509
|
family: "binary",
|
|
18281
18510
|
deviceType: DeviceType.Sensor,
|
|
18282
18511
|
memberDeviceType: DeviceType.Sensor,
|
|
18512
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18513
|
+
activeWhen: void 0,
|
|
18283
18514
|
commandCaps: [],
|
|
18284
18515
|
quantity: "none",
|
|
18285
18516
|
baseUnit: void 0,
|
|
@@ -18297,7 +18528,7 @@ var GROUP_TEMPLATES = [
|
|
|
18297
18528
|
quantity: "temperature",
|
|
18298
18529
|
defaultAggregate: "mean",
|
|
18299
18530
|
empty: "null",
|
|
18300
|
-
companions: [NOW]
|
|
18531
|
+
companions: [NOW$2]
|
|
18301
18532
|
}),
|
|
18302
18533
|
numeric({
|
|
18303
18534
|
id: "humidity",
|
|
@@ -18308,7 +18539,7 @@ var GROUP_TEMPLATES = [
|
|
|
18308
18539
|
quantity: "humidity",
|
|
18309
18540
|
defaultAggregate: "mean",
|
|
18310
18541
|
empty: "null",
|
|
18311
|
-
companions: [NOW]
|
|
18542
|
+
companions: [NOW$2]
|
|
18312
18543
|
}),
|
|
18313
18544
|
numeric({
|
|
18314
18545
|
id: "pressure",
|
|
@@ -18319,7 +18550,7 @@ var GROUP_TEMPLATES = [
|
|
|
18319
18550
|
quantity: "pressure",
|
|
18320
18551
|
defaultAggregate: "mean",
|
|
18321
18552
|
empty: "null",
|
|
18322
|
-
companions: [NOW]
|
|
18553
|
+
companions: [NOW$2]
|
|
18323
18554
|
}),
|
|
18324
18555
|
numeric({
|
|
18325
18556
|
id: "illuminance",
|
|
@@ -18330,7 +18561,7 @@ var GROUP_TEMPLATES = [
|
|
|
18330
18561
|
quantity: "illuminance",
|
|
18331
18562
|
defaultAggregate: "mean",
|
|
18332
18563
|
empty: "null",
|
|
18333
|
-
companions: [NOW]
|
|
18564
|
+
companions: [NOW$2]
|
|
18334
18565
|
}),
|
|
18335
18566
|
numeric({
|
|
18336
18567
|
id: "power",
|
|
@@ -18341,7 +18572,7 @@ var GROUP_TEMPLATES = [
|
|
|
18341
18572
|
quantity: "power",
|
|
18342
18573
|
defaultAggregate: "sum",
|
|
18343
18574
|
empty: "omit",
|
|
18344
|
-
companions: [NOW]
|
|
18575
|
+
companions: [NOW$2]
|
|
18345
18576
|
}),
|
|
18346
18577
|
numeric({
|
|
18347
18578
|
id: "energy",
|
|
@@ -18352,7 +18583,7 @@ var GROUP_TEMPLATES = [
|
|
|
18352
18583
|
quantity: "energy",
|
|
18353
18584
|
defaultAggregate: "sum",
|
|
18354
18585
|
empty: "omit",
|
|
18355
|
-
companions: [NOW]
|
|
18586
|
+
companions: [NOW$2]
|
|
18356
18587
|
}),
|
|
18357
18588
|
numeric({
|
|
18358
18589
|
id: "battery",
|
|
@@ -18387,7 +18618,7 @@ var GROUP_TEMPLATES = [
|
|
|
18387
18618
|
quantity: "device",
|
|
18388
18619
|
defaultAggregate: "mean",
|
|
18389
18620
|
empty: "null",
|
|
18390
|
-
companions: [NOW]
|
|
18621
|
+
companions: [NOW$2]
|
|
18391
18622
|
}),
|
|
18392
18623
|
binary({
|
|
18393
18624
|
id: "motion",
|
|
@@ -18481,6 +18712,11 @@ var GROUP_TEMPLATES = [
|
|
|
18481
18712
|
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.",
|
|
18482
18713
|
deviceType: DeviceType.Switch,
|
|
18483
18714
|
outputCap: "switch",
|
|
18715
|
+
outputField: "on",
|
|
18716
|
+
member: {
|
|
18717
|
+
cap: "switch",
|
|
18718
|
+
fieldPath: "on"
|
|
18719
|
+
},
|
|
18484
18720
|
commandCaps: ["switch"]
|
|
18485
18721
|
}),
|
|
18486
18722
|
actuator({
|
|
@@ -18488,34 +18724,136 @@ var GROUP_TEMPLATES = [
|
|
|
18488
18724
|
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.",
|
|
18489
18725
|
deviceType: DeviceType.Light,
|
|
18490
18726
|
outputCap: "switch",
|
|
18727
|
+
outputField: "on",
|
|
18728
|
+
member: {
|
|
18729
|
+
cap: "switch",
|
|
18730
|
+
fieldPath: "on"
|
|
18731
|
+
},
|
|
18491
18732
|
commandCaps: [
|
|
18492
18733
|
"switch",
|
|
18493
18734
|
"brightness",
|
|
18494
18735
|
"color"
|
|
18495
18736
|
]
|
|
18737
|
+
}),
|
|
18738
|
+
actuator({
|
|
18739
|
+
id: "fan",
|
|
18740
|
+
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.",
|
|
18741
|
+
deviceType: DeviceType.Fan,
|
|
18742
|
+
outputCap: "switch",
|
|
18743
|
+
outputField: "on",
|
|
18744
|
+
member: {
|
|
18745
|
+
cap: "switch",
|
|
18746
|
+
fieldPath: "on"
|
|
18747
|
+
},
|
|
18748
|
+
commandCaps: ["switch", "fan-control"]
|
|
18749
|
+
}),
|
|
18750
|
+
actuator({
|
|
18751
|
+
id: "cover",
|
|
18752
|
+
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.",
|
|
18753
|
+
deviceType: DeviceType.Cover,
|
|
18754
|
+
outputCap: "group-active",
|
|
18755
|
+
outputField: "active",
|
|
18756
|
+
member: {
|
|
18757
|
+
cap: "cover",
|
|
18758
|
+
fieldPath: "state"
|
|
18759
|
+
},
|
|
18760
|
+
activeWhen: [
|
|
18761
|
+
"open",
|
|
18762
|
+
"opening",
|
|
18763
|
+
"stopped"
|
|
18764
|
+
],
|
|
18765
|
+
commandCaps: ["cover"]
|
|
18766
|
+
}),
|
|
18767
|
+
actuator({
|
|
18768
|
+
id: "valve",
|
|
18769
|
+
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.",
|
|
18770
|
+
deviceType: DeviceType.Valve,
|
|
18771
|
+
outputCap: "group-active",
|
|
18772
|
+
outputField: "active",
|
|
18773
|
+
member: {
|
|
18774
|
+
cap: "valve",
|
|
18775
|
+
fieldPath: "state"
|
|
18776
|
+
},
|
|
18777
|
+
activeWhen: [
|
|
18778
|
+
"open",
|
|
18779
|
+
"opening",
|
|
18780
|
+
"stopped"
|
|
18781
|
+
],
|
|
18782
|
+
commandCaps: ["valve"]
|
|
18783
|
+
}),
|
|
18784
|
+
actuator({
|
|
18785
|
+
id: "lock",
|
|
18786
|
+
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.",
|
|
18787
|
+
deviceType: DeviceType.Lock,
|
|
18788
|
+
outputCap: "group-active",
|
|
18789
|
+
outputField: "active",
|
|
18790
|
+
member: {
|
|
18791
|
+
cap: "lock-control",
|
|
18792
|
+
fieldPath: "state"
|
|
18793
|
+
},
|
|
18794
|
+
activeWhen: ["locked"],
|
|
18795
|
+
commandCaps: ["lock-control"]
|
|
18796
|
+
}),
|
|
18797
|
+
actuator({
|
|
18798
|
+
id: "media-player",
|
|
18799
|
+
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.",
|
|
18800
|
+
deviceType: DeviceType.MediaPlayer,
|
|
18801
|
+
outputCap: "group-active",
|
|
18802
|
+
outputField: "active",
|
|
18803
|
+
member: {
|
|
18804
|
+
cap: "media-player",
|
|
18805
|
+
fieldPath: "state"
|
|
18806
|
+
},
|
|
18807
|
+
activeWhen: ["playing", "buffering"],
|
|
18808
|
+
commandCaps: ["media-player"]
|
|
18809
|
+
}),
|
|
18810
|
+
actuator({
|
|
18811
|
+
id: "climate",
|
|
18812
|
+
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.",
|
|
18813
|
+
deviceType: DeviceType.Thermostat,
|
|
18814
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
18815
|
+
outputCap: "group-active",
|
|
18816
|
+
outputField: "active",
|
|
18817
|
+
member: {
|
|
18818
|
+
cap: "climate-control",
|
|
18819
|
+
fieldPath: "mode"
|
|
18820
|
+
},
|
|
18821
|
+
activeWhen: [
|
|
18822
|
+
"heat",
|
|
18823
|
+
"cool",
|
|
18824
|
+
"auto",
|
|
18825
|
+
"heat_cool",
|
|
18826
|
+
"fan_only",
|
|
18827
|
+
"dry"
|
|
18828
|
+
],
|
|
18829
|
+
commandCaps: ["climate-control"]
|
|
18496
18830
|
})
|
|
18497
18831
|
];
|
|
18498
18832
|
function actuator(input) {
|
|
18499
18833
|
return {
|
|
18500
|
-
|
|
18834
|
+
id: input.id,
|
|
18835
|
+
summary: input.summary,
|
|
18836
|
+
deviceType: input.deviceType,
|
|
18837
|
+
outputCap: input.outputCap,
|
|
18838
|
+
outputField: input.outputField,
|
|
18839
|
+
commandCaps: input.commandCaps,
|
|
18501
18840
|
family: "actuator",
|
|
18502
18841
|
role: void 0,
|
|
18503
18842
|
memberDeviceType: input.deviceType,
|
|
18504
|
-
|
|
18843
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
18844
|
+
activeWhen: input.activeWhen,
|
|
18505
18845
|
quantity: "none",
|
|
18506
18846
|
baseUnit: void 0,
|
|
18507
18847
|
aggregates: BINARY_AGGREGATES,
|
|
18508
18848
|
defaultAggregate: "any",
|
|
18509
18849
|
empty: "offline",
|
|
18510
|
-
accept: [
|
|
18511
|
-
cap: "switch",
|
|
18512
|
-
fieldPath: "on"
|
|
18513
|
-
}],
|
|
18850
|
+
accept: [input.member],
|
|
18514
18851
|
companions: [CHANGED]
|
|
18515
18852
|
};
|
|
18516
18853
|
}
|
|
18517
18854
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18518
18855
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18856
|
+
DeviceType.Camera;
|
|
18519
18857
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18520
18858
|
/**
|
|
18521
18859
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -43739,7 +44077,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
43739
44077
|
});
|
|
43740
44078
|
/**
|
|
43741
44079
|
* Optional, richer endpoint shape returned by providers that expose
|
|
43742
|
-
* MORE than one ingress concurrently (Tailscale
|
|
44080
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
43743
44081
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
43744
44082
|
* the originating provider config (mode + sourcePort) so the
|
|
43745
44083
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -46426,7 +46764,20 @@ var NcRuleInputSchema = object({
|
|
|
46426
46764
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
46427
46765
|
* path does not run Zod defaults.
|
|
46428
46766
|
*/
|
|
46429
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46767
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46768
|
+
/**
|
|
46769
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46770
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46771
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46772
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46773
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46774
|
+
*
|
|
46775
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46776
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46777
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46778
|
+
* `false`, so it needs no `clear` key.
|
|
46779
|
+
*/
|
|
46780
|
+
askVerdict: boolean().optional()
|
|
46430
46781
|
});
|
|
46431
46782
|
/**
|
|
46432
46783
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -57250,7 +57601,8 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57250
57601
|
DeviceType.Switch,
|
|
57251
57602
|
DeviceType.PetFeeder,
|
|
57252
57603
|
DeviceType.Container,
|
|
57253
|
-
DeviceType.Thermostat
|
|
57604
|
+
DeviceType.Thermostat,
|
|
57605
|
+
DeviceType.EventEmitter
|
|
57254
57606
|
];
|
|
57255
57607
|
/** Generic Customize target for the percentage reading (D936). */
|
|
57256
57608
|
var batteryCustomize = {
|
|
@@ -60118,7 +60470,17 @@ var groupCommandsCapability = {
|
|
|
60118
60470
|
scope: "device",
|
|
60119
60471
|
deviceNative: true,
|
|
60120
60472
|
mode: "singleton",
|
|
60121
|
-
deviceTypes: [
|
|
60473
|
+
deviceTypes: [
|
|
60474
|
+
DeviceType.Switch,
|
|
60475
|
+
DeviceType.Light,
|
|
60476
|
+
DeviceType.Fan,
|
|
60477
|
+
DeviceType.Cover,
|
|
60478
|
+
DeviceType.Valve,
|
|
60479
|
+
DeviceType.Lock,
|
|
60480
|
+
DeviceType.MediaPlayer,
|
|
60481
|
+
DeviceType.Thermostat,
|
|
60482
|
+
DeviceType.Climate
|
|
60483
|
+
],
|
|
60122
60484
|
methods: {},
|
|
60123
60485
|
status: {
|
|
60124
60486
|
schema: GroupCommandsSchema,
|
|
@@ -60136,6 +60498,49 @@ var groupCommandsCapability = {
|
|
|
60136
60498
|
history: "none"
|
|
60137
60499
|
};
|
|
60138
60500
|
/**
|
|
60501
|
+
* Whether a helper actuator group counts as active (D944): at least one
|
|
60502
|
+
* included member is, or every included member is. What "active" means is the
|
|
60503
|
+
* type's: a cover is open, a lock is locked, a media player is playing, a
|
|
60504
|
+
* climate device is not off. A group of lights, switches and fans reports
|
|
60505
|
+
* `switch.on` instead; this cap is for the types whose own state is not a
|
|
60506
|
+
* yes/no. Unknown members are left out (`group-status` counts them) and an
|
|
60507
|
+
* empty included set takes the device offline, never `active: false`.
|
|
60508
|
+
*/
|
|
60509
|
+
var GroupActiveSchema = object({
|
|
60510
|
+
active: boolean().meta({ label: "Active" }),
|
|
60511
|
+
/** Ms epoch when the slice was last updated. */
|
|
60512
|
+
lastChangedAt: number()
|
|
60513
|
+
});
|
|
60514
|
+
var groupActiveCapability = {
|
|
60515
|
+
name: "group-active",
|
|
60516
|
+
scope: "device",
|
|
60517
|
+
deviceNative: true,
|
|
60518
|
+
mode: "singleton",
|
|
60519
|
+
deviceTypes: [
|
|
60520
|
+
DeviceType.Cover,
|
|
60521
|
+
DeviceType.Valve,
|
|
60522
|
+
DeviceType.Lock,
|
|
60523
|
+
DeviceType.MediaPlayer,
|
|
60524
|
+
DeviceType.Climate,
|
|
60525
|
+
DeviceType.Thermostat
|
|
60526
|
+
],
|
|
60527
|
+
methods: {},
|
|
60528
|
+
status: {
|
|
60529
|
+
schema: GroupActiveSchema,
|
|
60530
|
+
kind: "push"
|
|
60531
|
+
},
|
|
60532
|
+
runtimeState: GroupActiveSchema,
|
|
60533
|
+
/**
|
|
60534
|
+
* Runtime-state durability: **session** — recomputed from the members on the
|
|
60535
|
+
* next source event; a restored value would outlive the members it named.
|
|
60536
|
+
*
|
|
60537
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60538
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60539
|
+
*/
|
|
60540
|
+
durability: "session",
|
|
60541
|
+
history: "none"
|
|
60542
|
+
};
|
|
60543
|
+
/**
|
|
60139
60544
|
* How many members of a helper group answered (D944). Counts are integers,
|
|
60140
60545
|
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60141
60546
|
* The reading itself stays on the output capability. History is none — the
|
|
@@ -60166,7 +60571,14 @@ var groupStatusCapability = {
|
|
|
60166
60571
|
deviceTypes: [
|
|
60167
60572
|
DeviceType.Sensor,
|
|
60168
60573
|
DeviceType.Switch,
|
|
60169
|
-
DeviceType.Light
|
|
60574
|
+
DeviceType.Light,
|
|
60575
|
+
DeviceType.Fan,
|
|
60576
|
+
DeviceType.Cover,
|
|
60577
|
+
DeviceType.Valve,
|
|
60578
|
+
DeviceType.Lock,
|
|
60579
|
+
DeviceType.MediaPlayer,
|
|
60580
|
+
DeviceType.Thermostat,
|
|
60581
|
+
DeviceType.Climate
|
|
60170
60582
|
],
|
|
60171
60583
|
methods: {},
|
|
60172
60584
|
status: {
|
|
@@ -61439,7 +61851,14 @@ var lockControlCapability = {
|
|
|
61439
61851
|
}),
|
|
61440
61852
|
unlock: method(object({
|
|
61441
61853
|
deviceId: number().int().nonnegative(),
|
|
61442
|
-
code: string().min(1).optional()
|
|
61854
|
+
code: string().min(1).optional(),
|
|
61855
|
+
/**
|
|
61856
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
61857
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
61858
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
61859
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
61860
|
+
*/
|
|
61861
|
+
confirm: boolean().optional()
|
|
61443
61862
|
}), _void(), {
|
|
61444
61863
|
kind: "mutation",
|
|
61445
61864
|
auth: "protected"
|
|
@@ -61476,6 +61895,44 @@ var lockControlCapability = {
|
|
|
61476
61895
|
volatileStateFields: ["lastChangedAt"]
|
|
61477
61896
|
};
|
|
61478
61897
|
/**
|
|
61898
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.kwhTotal`
|
|
61899
|
+
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
61900
|
+
* `value` is the time integral in the source quantity's accumulated base
|
|
61901
|
+
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
61902
|
+
*/
|
|
61903
|
+
var MeterStatusSchema = object({
|
|
61904
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
61905
|
+
lastFetchedAt: number()
|
|
61906
|
+
});
|
|
61907
|
+
var meterCapability = {
|
|
61908
|
+
name: "meter",
|
|
61909
|
+
scope: "device",
|
|
61910
|
+
deviceNative: true,
|
|
61911
|
+
mode: "singleton",
|
|
61912
|
+
deviceTypes: [DeviceType.Sensor],
|
|
61913
|
+
methods: {},
|
|
61914
|
+
status: {
|
|
61915
|
+
schema: MeterStatusSchema,
|
|
61916
|
+
kind: "push"
|
|
61917
|
+
},
|
|
61918
|
+
runtimeState: MeterStatusSchema,
|
|
61919
|
+
/**
|
|
61920
|
+
* Runtime-state durability: **restored** — the total is a cache of the
|
|
61921
|
+
* history integral. A restart shows it only until the history pass
|
|
61922
|
+
* recomputes the open period; it is not an in-memory buffer.
|
|
61923
|
+
*
|
|
61924
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61925
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61926
|
+
*/
|
|
61927
|
+
durability: "restored",
|
|
61928
|
+
history: { fields: { value: {
|
|
61929
|
+
kind: "counter",
|
|
61930
|
+
deadband: .001,
|
|
61931
|
+
minIntervalMs: 6e4
|
|
61932
|
+
} } },
|
|
61933
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
61934
|
+
};
|
|
61935
|
+
/**
|
|
61479
61936
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
61480
61937
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
61481
61938
|
* `DeviceType.MediaPlayer`. Disjoint from the camera streaming
|
|
@@ -63987,9 +64444,9 @@ var PowerMeterStatusSchema = object({
|
|
|
63987
64444
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63988
64445
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63989
64446
|
/** Voltage in volts. */
|
|
63990
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
64447
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
63991
64448
|
/** Current in amperes. */
|
|
63992
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
64449
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
63993
64450
|
/** Apparent power in volt-amperes. */
|
|
63994
64451
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63995
64452
|
/** Power factor (0..1) if reported. */
|
|
@@ -63997,12 +64454,74 @@ var PowerMeterStatusSchema = object({
|
|
|
63997
64454
|
/** Ms epoch when the slice was last updated. */
|
|
63998
64455
|
lastFetchedAt: number()
|
|
63999
64456
|
});
|
|
64457
|
+
/**
|
|
64458
|
+
* Loads that draw metered mains power (D951). The reading is a feature of the
|
|
64459
|
+
* device itself — a plug, a lamp, a fan, an air conditioner, a boiler, a
|
|
64460
|
+
* vacuum dock — not a separate sensor beside it. A `Sensor` stays: a clamp
|
|
64461
|
+
* meter or a standalone energy monitor IS the device. Cover, lock, valve,
|
|
64462
|
+
* camera and the like are left out: their draw is not what anyone meters.
|
|
64463
|
+
*/
|
|
64464
|
+
var POWER_METER_DEVICE_TYPES = [
|
|
64465
|
+
DeviceType.Sensor,
|
|
64466
|
+
DeviceType.Switch,
|
|
64467
|
+
DeviceType.Light,
|
|
64468
|
+
DeviceType.Fan,
|
|
64469
|
+
DeviceType.Climate,
|
|
64470
|
+
DeviceType.Thermostat,
|
|
64471
|
+
DeviceType.Humidifier,
|
|
64472
|
+
DeviceType.WaterHeater,
|
|
64473
|
+
DeviceType.MediaPlayer,
|
|
64474
|
+
DeviceType.Washer,
|
|
64475
|
+
DeviceType.Dryer,
|
|
64476
|
+
DeviceType.Dishwasher,
|
|
64477
|
+
DeviceType.Vacuum,
|
|
64478
|
+
DeviceType.LawnMower,
|
|
64479
|
+
DeviceType.PetFeeder
|
|
64480
|
+
];
|
|
64481
|
+
/** Everything but a bare `Sensor`: a sensor that takes its reading from another sensor adds nothing. */
|
|
64482
|
+
var POWER_METER_CUSTOMIZE_DEVICE_TYPES = POWER_METER_DEVICE_TYPES.filter((type) => type !== DeviceType.Sensor);
|
|
64483
|
+
/** One scalar target per reading; each is sourced from a device of its own (D951). */
|
|
64484
|
+
function powerTarget(id, unit) {
|
|
64485
|
+
return {
|
|
64486
|
+
id,
|
|
64487
|
+
cardinality: "scalar",
|
|
64488
|
+
vocabulary: {
|
|
64489
|
+
cap: "power-meter",
|
|
64490
|
+
stateField: id
|
|
64491
|
+
},
|
|
64492
|
+
deviceTypes: POWER_METER_CUSTOMIZE_DEVICE_TYPES,
|
|
64493
|
+
apply: "add",
|
|
64494
|
+
path: id,
|
|
64495
|
+
sources: [{
|
|
64496
|
+
kind: "numeric",
|
|
64497
|
+
requiredUnit: unit,
|
|
64498
|
+
transforms: [{ kind: "identity" }]
|
|
64499
|
+
}],
|
|
64500
|
+
companions: [{
|
|
64501
|
+
kind: "clock",
|
|
64502
|
+
path: "lastFetchedAt",
|
|
64503
|
+
when: "always"
|
|
64504
|
+
}],
|
|
64505
|
+
sourceReport: { status: "assignment-status" },
|
|
64506
|
+
advancedExpression: true
|
|
64507
|
+
};
|
|
64508
|
+
}
|
|
64509
|
+
/** "Power and energy" extension: watts, energy, voltage and current from other devices (D951). */
|
|
64510
|
+
var powerMeterCustomize = {
|
|
64511
|
+
version: 1,
|
|
64512
|
+
targets: [
|
|
64513
|
+
powerTarget("watts", "W"),
|
|
64514
|
+
powerTarget("kwhTotal", "kWh"),
|
|
64515
|
+
powerTarget("volts", "V"),
|
|
64516
|
+
powerTarget("amps", "A")
|
|
64517
|
+
]
|
|
64518
|
+
};
|
|
64000
64519
|
var powerMeterCapability = {
|
|
64001
64520
|
name: "power-meter",
|
|
64002
64521
|
scope: "device",
|
|
64003
64522
|
deviceNative: true,
|
|
64004
64523
|
mode: "singleton",
|
|
64005
|
-
deviceTypes:
|
|
64524
|
+
deviceTypes: POWER_METER_DEVICE_TYPES,
|
|
64006
64525
|
methods: {},
|
|
64007
64526
|
status: {
|
|
64008
64527
|
schema: PowerMeterStatusSchema,
|
|
@@ -64059,7 +64578,8 @@ var powerMeterCapability = {
|
|
|
64059
64578
|
} },
|
|
64060
64579
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64061
64580
|
* whether persisting is worth a SQLite commit. */
|
|
64062
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64581
|
+
volatileStateFields: ["lastFetchedAt"],
|
|
64582
|
+
customize: powerMeterCustomize
|
|
64063
64583
|
};
|
|
64064
64584
|
/**
|
|
64065
64585
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -64740,6 +65260,8 @@ var runningCustomize = {
|
|
|
64740
65260
|
stateField: "running"
|
|
64741
65261
|
},
|
|
64742
65262
|
deviceTypes: [
|
|
65263
|
+
DeviceType.Washer,
|
|
65264
|
+
DeviceType.Dryer,
|
|
64743
65265
|
DeviceType.Dishwasher,
|
|
64744
65266
|
DeviceType.Vacuum,
|
|
64745
65267
|
DeviceType.LawnMower,
|
|
@@ -67229,7 +67751,8 @@ var switchCapability = {
|
|
|
67229
67751
|
deviceTypes: [
|
|
67230
67752
|
DeviceType.Switch,
|
|
67231
67753
|
DeviceType.Siren,
|
|
67232
|
-
DeviceType.Light
|
|
67754
|
+
DeviceType.Light,
|
|
67755
|
+
DeviceType.Fan
|
|
67233
67756
|
],
|
|
67234
67757
|
methods: { setState: method(object({
|
|
67235
67758
|
deviceId: number(),
|
|
@@ -69442,8 +69965,9 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
69442
69965
|
kind: "mutation",
|
|
69443
69966
|
auth: "admin"
|
|
69444
69967
|
});
|
|
69968
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
69445
69969
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
69446
|
-
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;
|
|
69970
|
+
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;
|
|
69447
69971
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
69448
69972
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
69449
69973
|
new Set(CAP_NAMES);
|
|
@@ -69772,6 +70296,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69772
70296
|
featureProbe: featureProbeCapability,
|
|
69773
70297
|
flood: floodCapability,
|
|
69774
70298
|
gas: gasCapability,
|
|
70299
|
+
groupActive: groupActiveCapability,
|
|
69775
70300
|
groupCommands: groupCommandsCapability,
|
|
69776
70301
|
groupStatus: groupStatusCapability,
|
|
69777
70302
|
heatingValve: heatingValveCapability,
|
|
@@ -69783,6 +70308,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69783
70308
|
lawnMowerControl: lawnMowerControlCapability,
|
|
69784
70309
|
lockControl: lockControlCapability,
|
|
69785
70310
|
mediaPlayer: mediaPlayerCapability,
|
|
70311
|
+
meter: meterCapability,
|
|
69786
70312
|
motion: motionCapability,
|
|
69787
70313
|
motionTrigger: motionTriggerCapability,
|
|
69788
70314
|
motionZones: motionZonesCapability,
|
|
@@ -71042,7 +71568,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
71042
71568
|
return toDeviceSummary(device, this.addonId);
|
|
71043
71569
|
}
|
|
71044
71570
|
};
|
|
71045
|
-
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;
|
|
71571
|
+
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;
|
|
71046
71572
|
new Set(Object.values(DeviceType));
|
|
71047
71573
|
Object.freeze({
|
|
71048
71574
|
"accessories.getStatus": {
|
|
@@ -74265,6 +74791,13 @@ Object.freeze({
|
|
|
74265
74791
|
access: "view",
|
|
74266
74792
|
role: "viewer"
|
|
74267
74793
|
},
|
|
74794
|
+
"groupActive.getStatus": {
|
|
74795
|
+
capName: "group-active",
|
|
74796
|
+
capScope: "device",
|
|
74797
|
+
addonId: null,
|
|
74798
|
+
access: "view",
|
|
74799
|
+
role: "viewer"
|
|
74800
|
+
},
|
|
74268
74801
|
"groupCommands.getStatus": {
|
|
74269
74802
|
capName: "group-commands",
|
|
74270
74803
|
capScope: "device",
|
|
@@ -75231,6 +75764,13 @@ Object.freeze({
|
|
|
75231
75764
|
access: "create",
|
|
75232
75765
|
role: "admin"
|
|
75233
75766
|
},
|
|
75767
|
+
"meter.getStatus": {
|
|
75768
|
+
capName: "meter",
|
|
75769
|
+
capScope: "device",
|
|
75770
|
+
addonId: null,
|
|
75771
|
+
access: "view",
|
|
75772
|
+
role: "viewer"
|
|
75773
|
+
},
|
|
75234
75774
|
"metricsProvider.collectSnapshot": {
|
|
75235
75775
|
capName: "metrics-provider",
|
|
75236
75776
|
capScope: "system",
|
|
@@ -83329,7 +83869,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83329
83869
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
83330
83870
|
icon: "square"
|
|
83331
83871
|
}
|
|
83332
|
-
}
|
|
83872
|
+
},
|
|
83873
|
+
overrides: { byType: {
|
|
83874
|
+
[DeviceType.Washer]: {
|
|
83875
|
+
state: { running: {
|
|
83876
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
83877
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
83878
|
+
} },
|
|
83879
|
+
events: {
|
|
83880
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
83881
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
83882
|
+
}
|
|
83883
|
+
},
|
|
83884
|
+
[DeviceType.Dryer]: {
|
|
83885
|
+
state: { running: {
|
|
83886
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
83887
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
83888
|
+
} },
|
|
83889
|
+
events: {
|
|
83890
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
83891
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
83892
|
+
}
|
|
83893
|
+
},
|
|
83894
|
+
[DeviceType.Dishwasher]: {
|
|
83895
|
+
state: { running: {
|
|
83896
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
83897
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
83898
|
+
} },
|
|
83899
|
+
events: {
|
|
83900
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
83901
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
83902
|
+
}
|
|
83903
|
+
}
|
|
83904
|
+
} }
|
|
83333
83905
|
},
|
|
83334
83906
|
update: {
|
|
83335
83907
|
scope: "device",
|
|
@@ -84101,6 +84673,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84101
84673
|
icon: "flame"
|
|
84102
84674
|
}]
|
|
84103
84675
|
},
|
|
84676
|
+
"group-active": {
|
|
84677
|
+
scope: "device",
|
|
84678
|
+
noun: t("Group state", "Stato del gruppo")
|
|
84679
|
+
},
|
|
84104
84680
|
"group-commands": {
|
|
84105
84681
|
scope: "device",
|
|
84106
84682
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -84157,6 +84733,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84157
84733
|
}],
|
|
84158
84734
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
84159
84735
|
},
|
|
84736
|
+
meter: {
|
|
84737
|
+
scope: "device",
|
|
84738
|
+
noun: t("Meter", "Contatore"),
|
|
84739
|
+
state: [{
|
|
84740
|
+
kind: "numeric",
|
|
84741
|
+
field: "value",
|
|
84742
|
+
quantity: t("the total", "il totale"),
|
|
84743
|
+
label: t("Total", "Totale"),
|
|
84744
|
+
icon: "gauge"
|
|
84745
|
+
}]
|
|
84746
|
+
},
|
|
84160
84747
|
"numeric-sensor": {
|
|
84161
84748
|
scope: "device",
|
|
84162
84749
|
noun: t("Sensor", "Sensore"),
|
|
@@ -84629,8 +85216,47 @@ function projectAction(cap, action) {
|
|
|
84629
85216
|
};
|
|
84630
85217
|
}
|
|
84631
85218
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
84632
|
-
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;
|
|
85219
|
+
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;
|
|
84633
85220
|
DeviceFeature.BatteryOperated;
|
|
85221
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
85222
|
+
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.";
|
|
85223
|
+
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.";
|
|
85224
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
85225
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
85226
|
+
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.";
|
|
85227
|
+
function withheld(reason) {
|
|
85228
|
+
return {
|
|
85229
|
+
[DeviceType.Washer]: {
|
|
85230
|
+
exported: false,
|
|
85231
|
+
reason
|
|
85232
|
+
},
|
|
85233
|
+
[DeviceType.Dryer]: {
|
|
85234
|
+
exported: false,
|
|
85235
|
+
reason
|
|
85236
|
+
},
|
|
85237
|
+
[DeviceType.Dishwasher]: {
|
|
85238
|
+
exported: false,
|
|
85239
|
+
reason
|
|
85240
|
+
}
|
|
85241
|
+
};
|
|
85242
|
+
}
|
|
85243
|
+
function offered(received) {
|
|
85244
|
+
return {
|
|
85245
|
+
[DeviceType.Washer]: {
|
|
85246
|
+
exported: true,
|
|
85247
|
+
as: received
|
|
85248
|
+
},
|
|
85249
|
+
[DeviceType.Dryer]: {
|
|
85250
|
+
exported: true,
|
|
85251
|
+
as: received
|
|
85252
|
+
},
|
|
85253
|
+
[DeviceType.Dishwasher]: {
|
|
85254
|
+
exported: true,
|
|
85255
|
+
as: received
|
|
85256
|
+
}
|
|
85257
|
+
};
|
|
85258
|
+
}
|
|
85259
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
84634
85260
|
Object.freeze({
|
|
84635
85261
|
"accessories.getStatus": [{
|
|
84636
85262
|
name: "deviceId",
|
|
@@ -85597,6 +86223,11 @@ Object.freeze({
|
|
|
85597
86223
|
form: "single",
|
|
85598
86224
|
optional: false
|
|
85599
86225
|
}],
|
|
86226
|
+
"groupActive.getStatus": [{
|
|
86227
|
+
name: "deviceId",
|
|
86228
|
+
form: "single",
|
|
86229
|
+
optional: false
|
|
86230
|
+
}],
|
|
85600
86231
|
"groupCommands.getStatus": [{
|
|
85601
86232
|
name: "deviceId",
|
|
85602
86233
|
form: "single",
|
|
@@ -85807,6 +86438,11 @@ Object.freeze({
|
|
|
85807
86438
|
form: "single",
|
|
85808
86439
|
optional: false
|
|
85809
86440
|
}],
|
|
86441
|
+
"meter.getStatus": [{
|
|
86442
|
+
name: "deviceId",
|
|
86443
|
+
form: "single",
|
|
86444
|
+
optional: false
|
|
86445
|
+
}],
|
|
85810
86446
|
"motion.getStatus": [{
|
|
85811
86447
|
name: "deviceId",
|
|
85812
86448
|
form: "single",
|
|
@@ -87414,7 +88050,6 @@ Object.freeze({
|
|
|
87414
88050
|
"network-access": "ingress",
|
|
87415
88051
|
"smtp-provider": "email"
|
|
87416
88052
|
});
|
|
87417
|
-
DeviceType.Camera;
|
|
87418
88053
|
/**
|
|
87419
88054
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
87420
88055
|
* `z.infer`, they do not restate the shape.
|