@camstack/addon-provider-amcrest 0.2.161 → 0.2.162
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 +30 -10
- package/dist/addon.js +680 -45
- package/dist/addon.mjs +680 -45
- package/package.json +1 -1
package/dist/addon.mjs
CHANGED
|
@@ -5457,7 +5457,7 @@ var ZodIssueCode = {
|
|
|
5457
5457
|
var ZodFirstPartyTypeKind;
|
|
5458
5458
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5459
5459
|
//#endregion
|
|
5460
|
-
//#region ../types/dist/sleep
|
|
5460
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5461
5461
|
/**
|
|
5462
5462
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5463
5463
|
* window to float samples (D455).
|
|
@@ -8650,6 +8650,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8650
8650
|
"filesystem-browse",
|
|
8651
8651
|
"flood",
|
|
8652
8652
|
"gas",
|
|
8653
|
+
"group-active",
|
|
8653
8654
|
"group-commands",
|
|
8654
8655
|
"group-status",
|
|
8655
8656
|
"heating-valve",
|
|
@@ -8672,6 +8673,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8672
8673
|
"login-method",
|
|
8673
8674
|
"media-player",
|
|
8674
8675
|
"mesh-network",
|
|
8676
|
+
"meter",
|
|
8675
8677
|
"metrics-provider",
|
|
8676
8678
|
"model-convert",
|
|
8677
8679
|
"model-distributor",
|
|
@@ -9470,6 +9472,10 @@ Object.freeze({
|
|
|
9470
9472
|
"path": "detected",
|
|
9471
9473
|
"valueType": "boolean"
|
|
9472
9474
|
}],
|
|
9475
|
+
"group-active": [{
|
|
9476
|
+
"path": "active",
|
|
9477
|
+
"valueType": "boolean"
|
|
9478
|
+
}],
|
|
9473
9479
|
"group-status": [
|
|
9474
9480
|
{
|
|
9475
9481
|
"path": "included",
|
|
@@ -9729,6 +9735,10 @@ Object.freeze({
|
|
|
9729
9735
|
]
|
|
9730
9736
|
}
|
|
9731
9737
|
],
|
|
9738
|
+
"meter": [{
|
|
9739
|
+
"path": "value",
|
|
9740
|
+
"valueType": "number"
|
|
9741
|
+
}],
|
|
9732
9742
|
"motion": [
|
|
9733
9743
|
{
|
|
9734
9744
|
"path": "detected",
|
|
@@ -10486,7 +10496,7 @@ function userError(code, params, englishFallback) {
|
|
|
10486
10496
|
return new CamstackError(code, params, englishFallback);
|
|
10487
10497
|
}
|
|
10488
10498
|
//#endregion
|
|
10489
|
-
//#region ../types/dist/err-msg-
|
|
10499
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
10490
10500
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
10491
10501
|
DeviceType["Camera"] = "camera";
|
|
10492
10502
|
DeviceType["Hub"] = "hub";
|
|
@@ -10580,8 +10590,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
10580
10590
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
10581
10591
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
10582
10592
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
10583
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10593
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10594
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
10584
10595
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
10596
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
10597
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
10598
|
+
DeviceType["Washer"] = "washer";
|
|
10599
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
10600
|
+
DeviceType["Dryer"] = "dryer";
|
|
10585
10601
|
return DeviceType;
|
|
10586
10602
|
}({});
|
|
10587
10603
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -10829,7 +10845,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10829
10845
|
return DeviceRole;
|
|
10830
10846
|
}({});
|
|
10831
10847
|
//#endregion
|
|
10832
|
-
//#region ../types/dist/composition-
|
|
10848
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
10833
10849
|
/**
|
|
10834
10850
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10835
10851
|
*
|
|
@@ -11144,6 +11160,13 @@ var table = {
|
|
|
11144
11160
|
apply: () => {
|
|
11145
11161
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11146
11162
|
}
|
|
11163
|
+
},
|
|
11164
|
+
schmitt: {
|
|
11165
|
+
minArgs: 3,
|
|
11166
|
+
maxArgs: 5,
|
|
11167
|
+
apply: () => {
|
|
11168
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11169
|
+
}
|
|
11147
11170
|
}
|
|
11148
11171
|
};
|
|
11149
11172
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11585,6 +11608,99 @@ function validateExpressionSource(src) {
|
|
|
11585
11608
|
return null;
|
|
11586
11609
|
}
|
|
11587
11610
|
/**
|
|
11611
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
11612
|
+
*
|
|
11613
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
11614
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
11615
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
11616
|
+
*
|
|
11617
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
11618
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
11619
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
11620
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
11621
|
+
* can move later without moving the others.
|
|
11622
|
+
*/
|
|
11623
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
11624
|
+
var APPLIANCE_KINDS = [
|
|
11625
|
+
"washer",
|
|
11626
|
+
"dryer",
|
|
11627
|
+
"dishwasher"
|
|
11628
|
+
];
|
|
11629
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11630
|
+
/**
|
|
11631
|
+
* Statistics and integrals over a history read (D944).
|
|
11632
|
+
*
|
|
11633
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11634
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11635
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11636
|
+
* as zero. A truncated read is not published.
|
|
11637
|
+
*/
|
|
11638
|
+
var STATISTIC_STATS = [
|
|
11639
|
+
"min",
|
|
11640
|
+
"max",
|
|
11641
|
+
"mean",
|
|
11642
|
+
"sum",
|
|
11643
|
+
"count",
|
|
11644
|
+
"change"
|
|
11645
|
+
];
|
|
11646
|
+
/**
|
|
11647
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11648
|
+
*
|
|
11649
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11650
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11651
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11652
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11653
|
+
*/
|
|
11654
|
+
var MINUTE_MS = 6e4;
|
|
11655
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11656
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11657
|
+
var ROLLING_SPANS = [
|
|
11658
|
+
"1h",
|
|
11659
|
+
"24h",
|
|
11660
|
+
"2d",
|
|
11661
|
+
"7d",
|
|
11662
|
+
"30d",
|
|
11663
|
+
"custom"
|
|
11664
|
+
];
|
|
11665
|
+
var CALENDAR_PERIODS = [
|
|
11666
|
+
"today",
|
|
11667
|
+
"yesterday",
|
|
11668
|
+
"this-week",
|
|
11669
|
+
"this-month"
|
|
11670
|
+
];
|
|
11671
|
+
var RESET_PERIODS = [
|
|
11672
|
+
"never",
|
|
11673
|
+
"daily",
|
|
11674
|
+
"weekly",
|
|
11675
|
+
"monthly"
|
|
11676
|
+
];
|
|
11677
|
+
5 * MINUTE_MS;
|
|
11678
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11679
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11680
|
+
var rollingWindowObject = object({
|
|
11681
|
+
kind: literal("rolling"),
|
|
11682
|
+
span: _enum(ROLLING_SPANS),
|
|
11683
|
+
customMinutes: number().int().min(5).optional()
|
|
11684
|
+
}).check((payload) => {
|
|
11685
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11686
|
+
code: "custom",
|
|
11687
|
+
message: "a custom range needs a duration in minutes",
|
|
11688
|
+
path: ["customMinutes"],
|
|
11689
|
+
input: payload.value
|
|
11690
|
+
});
|
|
11691
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11692
|
+
code: "custom",
|
|
11693
|
+
message: "only a custom range carries a duration",
|
|
11694
|
+
path: ["customMinutes"],
|
|
11695
|
+
input: payload.value
|
|
11696
|
+
});
|
|
11697
|
+
});
|
|
11698
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
11699
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
11700
|
+
kind: literal("calendar"),
|
|
11701
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11702
|
+
})]);
|
|
11703
|
+
/**
|
|
11588
11704
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11589
11705
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11590
11706
|
* `composition.ts` (D659).
|
|
@@ -11610,7 +11726,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11610
11726
|
"occupancy",
|
|
11611
11727
|
"binary",
|
|
11612
11728
|
"switch",
|
|
11613
|
-
"light"
|
|
11729
|
+
"light",
|
|
11730
|
+
"fan",
|
|
11731
|
+
"cover",
|
|
11732
|
+
"valve",
|
|
11733
|
+
"lock",
|
|
11734
|
+
"media-player",
|
|
11735
|
+
"climate"
|
|
11614
11736
|
];
|
|
11615
11737
|
var NUMERIC_AGGREGATES = [
|
|
11616
11738
|
"mean",
|
|
@@ -11640,14 +11762,73 @@ var HelperMemberSchema = object({
|
|
|
11640
11762
|
cap: string().min(1),
|
|
11641
11763
|
fieldPath: string().min(1)
|
|
11642
11764
|
});
|
|
11643
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11644
|
-
|
|
11645
|
-
|
|
11646
|
-
|
|
11647
|
-
|
|
11648
|
-
|
|
11649
|
-
|
|
11650
|
-
|
|
11765
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11766
|
+
object({
|
|
11767
|
+
kind: literal("group"),
|
|
11768
|
+
templateId: GroupTemplateIdSchema,
|
|
11769
|
+
aggregate: AggregateReducerSchema,
|
|
11770
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11771
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11772
|
+
active: ActiveCriterionSchema.optional()
|
|
11773
|
+
}),
|
|
11774
|
+
object({
|
|
11775
|
+
kind: literal("appliance"),
|
|
11776
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
11777
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
11778
|
+
thresholdWatts: number().positive(),
|
|
11779
|
+
startDwellMs: number().int().nonnegative(),
|
|
11780
|
+
stopDwellMs: number().int().nonnegative(),
|
|
11781
|
+
member: HelperMemberSchema
|
|
11782
|
+
}),
|
|
11783
|
+
object({
|
|
11784
|
+
kind: literal("statistic"),
|
|
11785
|
+
stat: _enum(STATISTIC_STATS),
|
|
11786
|
+
window: StatisticWindowSchema,
|
|
11787
|
+
source: HelperMemberSchema
|
|
11788
|
+
}),
|
|
11789
|
+
object({
|
|
11790
|
+
kind: literal("integral"),
|
|
11791
|
+
reset: _enum(RESET_PERIODS),
|
|
11792
|
+
output: _enum(["energy", "meter"]),
|
|
11793
|
+
source: HelperMemberSchema
|
|
11794
|
+
}),
|
|
11795
|
+
object({
|
|
11796
|
+
kind: literal("threshold"),
|
|
11797
|
+
source: HelperMemberSchema,
|
|
11798
|
+
high: number(),
|
|
11799
|
+
low: number(),
|
|
11800
|
+
onForMs: number().int().nonnegative(),
|
|
11801
|
+
offForMs: number().int().nonnegative()
|
|
11802
|
+
}),
|
|
11803
|
+
object({
|
|
11804
|
+
kind: literal("arithmetic"),
|
|
11805
|
+
op: _enum([
|
|
11806
|
+
"sum",
|
|
11807
|
+
"difference",
|
|
11808
|
+
"ratio"
|
|
11809
|
+
]),
|
|
11810
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
11811
|
+
}),
|
|
11812
|
+
object({
|
|
11813
|
+
kind: literal("expression"),
|
|
11814
|
+
expr: string().min(1),
|
|
11815
|
+
inputs: array(object({
|
|
11816
|
+
name: string().min(1),
|
|
11817
|
+
member: HelperMemberSchema
|
|
11818
|
+
})).min(1).max(64),
|
|
11819
|
+
output: _enum(["number", "boolean"])
|
|
11820
|
+
}),
|
|
11821
|
+
object({
|
|
11822
|
+
kind: literal("derivative"),
|
|
11823
|
+
window: RollingWindowSchema,
|
|
11824
|
+
per: _enum([
|
|
11825
|
+
"second",
|
|
11826
|
+
"minute",
|
|
11827
|
+
"hour"
|
|
11828
|
+
]),
|
|
11829
|
+
source: HelperMemberSchema
|
|
11830
|
+
})
|
|
11831
|
+
]);
|
|
11651
11832
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11652
11833
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11653
11834
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -11708,6 +11889,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11708
11889
|
"all"
|
|
11709
11890
|
]),
|
|
11710
11891
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11892
|
+
/**
|
|
11893
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
11894
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
11895
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
11896
|
+
*/
|
|
11897
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
11711
11898
|
/** `value` is the reading; the others are the member counts. */
|
|
11712
11899
|
publish: _enum([
|
|
11713
11900
|
"value",
|
|
@@ -11721,6 +11908,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11721
11908
|
"omit",
|
|
11722
11909
|
"offline"
|
|
11723
11910
|
])
|
|
11911
|
+
}),
|
|
11912
|
+
object({
|
|
11913
|
+
kind: literal("series"),
|
|
11914
|
+
read: CompositionFieldReadSchema,
|
|
11915
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
11916
|
+
publish: _enum([
|
|
11917
|
+
"value",
|
|
11918
|
+
"included",
|
|
11919
|
+
"excluded",
|
|
11920
|
+
"total"
|
|
11921
|
+
]),
|
|
11922
|
+
/**
|
|
11923
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
11924
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
11925
|
+
*/
|
|
11926
|
+
empty: _enum([
|
|
11927
|
+
"null",
|
|
11928
|
+
"omit",
|
|
11929
|
+
"offline"
|
|
11930
|
+
])
|
|
11724
11931
|
})
|
|
11725
11932
|
]);
|
|
11726
11933
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -16918,7 +17125,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
16918
17125
|
*/
|
|
16919
17126
|
interactiveConnectPath: string().min(1).optional(),
|
|
16920
17127
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
16921
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
17128
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
17129
|
+
/**
|
|
17130
|
+
* The kind signs in through a server-held interactive session instead of
|
|
17131
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
17132
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
17133
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
17134
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
17135
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
17136
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
17137
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
17138
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
17139
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
17140
|
+
* offers it as the default path; the fields the session fills are
|
|
17141
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
17142
|
+
*/
|
|
17143
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
16922
17144
|
}))
|
|
16923
17145
|
});
|
|
16924
17146
|
var ListInputSchema = object({
|
|
@@ -18023,7 +18245,8 @@ var CompositionProblemSchema = object({
|
|
|
18023
18245
|
"native-capability-replace",
|
|
18024
18246
|
"mixed-quantity",
|
|
18025
18247
|
"helper-mismatch",
|
|
18026
|
-
"member-constraint"
|
|
18248
|
+
"member-constraint",
|
|
18249
|
+
"retention"
|
|
18027
18250
|
]),
|
|
18028
18251
|
path: string(),
|
|
18029
18252
|
message: string()
|
|
@@ -18257,13 +18480,17 @@ Object.freeze({
|
|
|
18257
18480
|
latchedAt: {
|
|
18258
18481
|
kind: "fixed",
|
|
18259
18482
|
result: ["number", "null"]
|
|
18483
|
+
},
|
|
18484
|
+
schmitt: {
|
|
18485
|
+
kind: "fixed",
|
|
18486
|
+
result: ["boolean", "null"]
|
|
18260
18487
|
}
|
|
18261
18488
|
});
|
|
18262
18489
|
/**
|
|
18263
18490
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18264
18491
|
* Data, not a form default written into the block.
|
|
18265
18492
|
*/
|
|
18266
|
-
var NOW = {
|
|
18493
|
+
var NOW$2 = {
|
|
18267
18494
|
fieldPath: "lastFetchedAt",
|
|
18268
18495
|
expr: "now"
|
|
18269
18496
|
};
|
|
@@ -18277,6 +18504,8 @@ function numeric(input) {
|
|
|
18277
18504
|
family: "numeric",
|
|
18278
18505
|
deviceType: DeviceType.Sensor,
|
|
18279
18506
|
memberDeviceType: DeviceType.Sensor,
|
|
18507
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18508
|
+
activeWhen: void 0,
|
|
18280
18509
|
commandCaps: [],
|
|
18281
18510
|
baseUnit: baseUnitOf(input.quantity),
|
|
18282
18511
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18292,6 +18521,8 @@ function binary(input) {
|
|
|
18292
18521
|
family: "binary",
|
|
18293
18522
|
deviceType: DeviceType.Sensor,
|
|
18294
18523
|
memberDeviceType: DeviceType.Sensor,
|
|
18524
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18525
|
+
activeWhen: void 0,
|
|
18295
18526
|
commandCaps: [],
|
|
18296
18527
|
quantity: "none",
|
|
18297
18528
|
baseUnit: void 0,
|
|
@@ -18309,7 +18540,7 @@ var GROUP_TEMPLATES = [
|
|
|
18309
18540
|
quantity: "temperature",
|
|
18310
18541
|
defaultAggregate: "mean",
|
|
18311
18542
|
empty: "null",
|
|
18312
|
-
companions: [NOW]
|
|
18543
|
+
companions: [NOW$2]
|
|
18313
18544
|
}),
|
|
18314
18545
|
numeric({
|
|
18315
18546
|
id: "humidity",
|
|
@@ -18320,7 +18551,7 @@ var GROUP_TEMPLATES = [
|
|
|
18320
18551
|
quantity: "humidity",
|
|
18321
18552
|
defaultAggregate: "mean",
|
|
18322
18553
|
empty: "null",
|
|
18323
|
-
companions: [NOW]
|
|
18554
|
+
companions: [NOW$2]
|
|
18324
18555
|
}),
|
|
18325
18556
|
numeric({
|
|
18326
18557
|
id: "pressure",
|
|
@@ -18331,7 +18562,7 @@ var GROUP_TEMPLATES = [
|
|
|
18331
18562
|
quantity: "pressure",
|
|
18332
18563
|
defaultAggregate: "mean",
|
|
18333
18564
|
empty: "null",
|
|
18334
|
-
companions: [NOW]
|
|
18565
|
+
companions: [NOW$2]
|
|
18335
18566
|
}),
|
|
18336
18567
|
numeric({
|
|
18337
18568
|
id: "illuminance",
|
|
@@ -18342,7 +18573,7 @@ var GROUP_TEMPLATES = [
|
|
|
18342
18573
|
quantity: "illuminance",
|
|
18343
18574
|
defaultAggregate: "mean",
|
|
18344
18575
|
empty: "null",
|
|
18345
|
-
companions: [NOW]
|
|
18576
|
+
companions: [NOW$2]
|
|
18346
18577
|
}),
|
|
18347
18578
|
numeric({
|
|
18348
18579
|
id: "power",
|
|
@@ -18353,7 +18584,7 @@ var GROUP_TEMPLATES = [
|
|
|
18353
18584
|
quantity: "power",
|
|
18354
18585
|
defaultAggregate: "sum",
|
|
18355
18586
|
empty: "omit",
|
|
18356
|
-
companions: [NOW]
|
|
18587
|
+
companions: [NOW$2]
|
|
18357
18588
|
}),
|
|
18358
18589
|
numeric({
|
|
18359
18590
|
id: "energy",
|
|
@@ -18364,7 +18595,7 @@ var GROUP_TEMPLATES = [
|
|
|
18364
18595
|
quantity: "energy",
|
|
18365
18596
|
defaultAggregate: "sum",
|
|
18366
18597
|
empty: "omit",
|
|
18367
|
-
companions: [NOW]
|
|
18598
|
+
companions: [NOW$2]
|
|
18368
18599
|
}),
|
|
18369
18600
|
numeric({
|
|
18370
18601
|
id: "battery",
|
|
@@ -18399,7 +18630,7 @@ var GROUP_TEMPLATES = [
|
|
|
18399
18630
|
quantity: "device",
|
|
18400
18631
|
defaultAggregate: "mean",
|
|
18401
18632
|
empty: "null",
|
|
18402
|
-
companions: [NOW]
|
|
18633
|
+
companions: [NOW$2]
|
|
18403
18634
|
}),
|
|
18404
18635
|
binary({
|
|
18405
18636
|
id: "motion",
|
|
@@ -18493,6 +18724,11 @@ var GROUP_TEMPLATES = [
|
|
|
18493
18724
|
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.",
|
|
18494
18725
|
deviceType: DeviceType.Switch,
|
|
18495
18726
|
outputCap: "switch",
|
|
18727
|
+
outputField: "on",
|
|
18728
|
+
member: {
|
|
18729
|
+
cap: "switch",
|
|
18730
|
+
fieldPath: "on"
|
|
18731
|
+
},
|
|
18496
18732
|
commandCaps: ["switch"]
|
|
18497
18733
|
}),
|
|
18498
18734
|
actuator({
|
|
@@ -18500,34 +18736,136 @@ var GROUP_TEMPLATES = [
|
|
|
18500
18736
|
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.",
|
|
18501
18737
|
deviceType: DeviceType.Light,
|
|
18502
18738
|
outputCap: "switch",
|
|
18739
|
+
outputField: "on",
|
|
18740
|
+
member: {
|
|
18741
|
+
cap: "switch",
|
|
18742
|
+
fieldPath: "on"
|
|
18743
|
+
},
|
|
18503
18744
|
commandCaps: [
|
|
18504
18745
|
"switch",
|
|
18505
18746
|
"brightness",
|
|
18506
18747
|
"color"
|
|
18507
18748
|
]
|
|
18749
|
+
}),
|
|
18750
|
+
actuator({
|
|
18751
|
+
id: "fan",
|
|
18752
|
+
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.",
|
|
18753
|
+
deviceType: DeviceType.Fan,
|
|
18754
|
+
outputCap: "switch",
|
|
18755
|
+
outputField: "on",
|
|
18756
|
+
member: {
|
|
18757
|
+
cap: "switch",
|
|
18758
|
+
fieldPath: "on"
|
|
18759
|
+
},
|
|
18760
|
+
commandCaps: ["switch", "fan-control"]
|
|
18761
|
+
}),
|
|
18762
|
+
actuator({
|
|
18763
|
+
id: "cover",
|
|
18764
|
+
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.",
|
|
18765
|
+
deviceType: DeviceType.Cover,
|
|
18766
|
+
outputCap: "group-active",
|
|
18767
|
+
outputField: "active",
|
|
18768
|
+
member: {
|
|
18769
|
+
cap: "cover",
|
|
18770
|
+
fieldPath: "state"
|
|
18771
|
+
},
|
|
18772
|
+
activeWhen: [
|
|
18773
|
+
"open",
|
|
18774
|
+
"opening",
|
|
18775
|
+
"stopped"
|
|
18776
|
+
],
|
|
18777
|
+
commandCaps: ["cover"]
|
|
18778
|
+
}),
|
|
18779
|
+
actuator({
|
|
18780
|
+
id: "valve",
|
|
18781
|
+
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.",
|
|
18782
|
+
deviceType: DeviceType.Valve,
|
|
18783
|
+
outputCap: "group-active",
|
|
18784
|
+
outputField: "active",
|
|
18785
|
+
member: {
|
|
18786
|
+
cap: "valve",
|
|
18787
|
+
fieldPath: "state"
|
|
18788
|
+
},
|
|
18789
|
+
activeWhen: [
|
|
18790
|
+
"open",
|
|
18791
|
+
"opening",
|
|
18792
|
+
"stopped"
|
|
18793
|
+
],
|
|
18794
|
+
commandCaps: ["valve"]
|
|
18795
|
+
}),
|
|
18796
|
+
actuator({
|
|
18797
|
+
id: "lock",
|
|
18798
|
+
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.",
|
|
18799
|
+
deviceType: DeviceType.Lock,
|
|
18800
|
+
outputCap: "group-active",
|
|
18801
|
+
outputField: "active",
|
|
18802
|
+
member: {
|
|
18803
|
+
cap: "lock-control",
|
|
18804
|
+
fieldPath: "state"
|
|
18805
|
+
},
|
|
18806
|
+
activeWhen: ["locked"],
|
|
18807
|
+
commandCaps: ["lock-control"]
|
|
18808
|
+
}),
|
|
18809
|
+
actuator({
|
|
18810
|
+
id: "media-player",
|
|
18811
|
+
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.",
|
|
18812
|
+
deviceType: DeviceType.MediaPlayer,
|
|
18813
|
+
outputCap: "group-active",
|
|
18814
|
+
outputField: "active",
|
|
18815
|
+
member: {
|
|
18816
|
+
cap: "media-player",
|
|
18817
|
+
fieldPath: "state"
|
|
18818
|
+
},
|
|
18819
|
+
activeWhen: ["playing", "buffering"],
|
|
18820
|
+
commandCaps: ["media-player"]
|
|
18821
|
+
}),
|
|
18822
|
+
actuator({
|
|
18823
|
+
id: "climate",
|
|
18824
|
+
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.",
|
|
18825
|
+
deviceType: DeviceType.Thermostat,
|
|
18826
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
18827
|
+
outputCap: "group-active",
|
|
18828
|
+
outputField: "active",
|
|
18829
|
+
member: {
|
|
18830
|
+
cap: "climate-control",
|
|
18831
|
+
fieldPath: "mode"
|
|
18832
|
+
},
|
|
18833
|
+
activeWhen: [
|
|
18834
|
+
"heat",
|
|
18835
|
+
"cool",
|
|
18836
|
+
"auto",
|
|
18837
|
+
"heat_cool",
|
|
18838
|
+
"fan_only",
|
|
18839
|
+
"dry"
|
|
18840
|
+
],
|
|
18841
|
+
commandCaps: ["climate-control"]
|
|
18508
18842
|
})
|
|
18509
18843
|
];
|
|
18510
18844
|
function actuator(input) {
|
|
18511
18845
|
return {
|
|
18512
|
-
|
|
18846
|
+
id: input.id,
|
|
18847
|
+
summary: input.summary,
|
|
18848
|
+
deviceType: input.deviceType,
|
|
18849
|
+
outputCap: input.outputCap,
|
|
18850
|
+
outputField: input.outputField,
|
|
18851
|
+
commandCaps: input.commandCaps,
|
|
18513
18852
|
family: "actuator",
|
|
18514
18853
|
role: void 0,
|
|
18515
18854
|
memberDeviceType: input.deviceType,
|
|
18516
|
-
|
|
18855
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
18856
|
+
activeWhen: input.activeWhen,
|
|
18517
18857
|
quantity: "none",
|
|
18518
18858
|
baseUnit: void 0,
|
|
18519
18859
|
aggregates: BINARY_AGGREGATES,
|
|
18520
18860
|
defaultAggregate: "any",
|
|
18521
18861
|
empty: "offline",
|
|
18522
|
-
accept: [
|
|
18523
|
-
cap: "switch",
|
|
18524
|
-
fieldPath: "on"
|
|
18525
|
-
}],
|
|
18862
|
+
accept: [input.member],
|
|
18526
18863
|
companions: [CHANGED]
|
|
18527
18864
|
};
|
|
18528
18865
|
}
|
|
18529
18866
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18530
18867
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18868
|
+
DeviceType.Camera;
|
|
18531
18869
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18532
18870
|
/**
|
|
18533
18871
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -43847,7 +44185,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
43847
44185
|
});
|
|
43848
44186
|
/**
|
|
43849
44187
|
* Optional, richer endpoint shape returned by providers that expose
|
|
43850
|
-
* MORE than one ingress concurrently (Tailscale
|
|
44188
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
43851
44189
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
43852
44190
|
* the originating provider config (mode + sourcePort) so the
|
|
43853
44191
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -46534,7 +46872,20 @@ var NcRuleInputSchema = object({
|
|
|
46534
46872
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
46535
46873
|
* path does not run Zod defaults.
|
|
46536
46874
|
*/
|
|
46537
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46875
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46876
|
+
/**
|
|
46877
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46878
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46879
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46880
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46881
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46882
|
+
*
|
|
46883
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46884
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46885
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46886
|
+
* `false`, so it needs no `clear` key.
|
|
46887
|
+
*/
|
|
46888
|
+
askVerdict: boolean().optional()
|
|
46538
46889
|
});
|
|
46539
46890
|
/**
|
|
46540
46891
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -57767,7 +58118,8 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57767
58118
|
DeviceType.Switch,
|
|
57768
58119
|
DeviceType.PetFeeder,
|
|
57769
58120
|
DeviceType.Container,
|
|
57770
|
-
DeviceType.Thermostat
|
|
58121
|
+
DeviceType.Thermostat,
|
|
58122
|
+
DeviceType.EventEmitter
|
|
57771
58123
|
];
|
|
57772
58124
|
/** Generic Customize target for the percentage reading (D936). */
|
|
57773
58125
|
var batteryCustomize = {
|
|
@@ -60627,7 +60979,17 @@ var groupCommandsCapability = {
|
|
|
60627
60979
|
scope: "device",
|
|
60628
60980
|
deviceNative: true,
|
|
60629
60981
|
mode: "singleton",
|
|
60630
|
-
deviceTypes: [
|
|
60982
|
+
deviceTypes: [
|
|
60983
|
+
DeviceType.Switch,
|
|
60984
|
+
DeviceType.Light,
|
|
60985
|
+
DeviceType.Fan,
|
|
60986
|
+
DeviceType.Cover,
|
|
60987
|
+
DeviceType.Valve,
|
|
60988
|
+
DeviceType.Lock,
|
|
60989
|
+
DeviceType.MediaPlayer,
|
|
60990
|
+
DeviceType.Thermostat,
|
|
60991
|
+
DeviceType.Climate
|
|
60992
|
+
],
|
|
60631
60993
|
methods: {},
|
|
60632
60994
|
status: {
|
|
60633
60995
|
schema: GroupCommandsSchema,
|
|
@@ -60645,6 +61007,49 @@ var groupCommandsCapability = {
|
|
|
60645
61007
|
history: "none"
|
|
60646
61008
|
};
|
|
60647
61009
|
/**
|
|
61010
|
+
* Whether a helper actuator group counts as active (D944): at least one
|
|
61011
|
+
* included member is, or every included member is. What "active" means is the
|
|
61012
|
+
* type's: a cover is open, a lock is locked, a media player is playing, a
|
|
61013
|
+
* climate device is not off. A group of lights, switches and fans reports
|
|
61014
|
+
* `switch.on` instead; this cap is for the types whose own state is not a
|
|
61015
|
+
* yes/no. Unknown members are left out (`group-status` counts them) and an
|
|
61016
|
+
* empty included set takes the device offline, never `active: false`.
|
|
61017
|
+
*/
|
|
61018
|
+
var GroupActiveSchema = object({
|
|
61019
|
+
active: boolean().meta({ label: "Active" }),
|
|
61020
|
+
/** Ms epoch when the slice was last updated. */
|
|
61021
|
+
lastChangedAt: number()
|
|
61022
|
+
});
|
|
61023
|
+
var groupActiveCapability = {
|
|
61024
|
+
name: "group-active",
|
|
61025
|
+
scope: "device",
|
|
61026
|
+
deviceNative: true,
|
|
61027
|
+
mode: "singleton",
|
|
61028
|
+
deviceTypes: [
|
|
61029
|
+
DeviceType.Cover,
|
|
61030
|
+
DeviceType.Valve,
|
|
61031
|
+
DeviceType.Lock,
|
|
61032
|
+
DeviceType.MediaPlayer,
|
|
61033
|
+
DeviceType.Climate,
|
|
61034
|
+
DeviceType.Thermostat
|
|
61035
|
+
],
|
|
61036
|
+
methods: {},
|
|
61037
|
+
status: {
|
|
61038
|
+
schema: GroupActiveSchema,
|
|
61039
|
+
kind: "push"
|
|
61040
|
+
},
|
|
61041
|
+
runtimeState: GroupActiveSchema,
|
|
61042
|
+
/**
|
|
61043
|
+
* Runtime-state durability: **session** — recomputed from the members on the
|
|
61044
|
+
* next source event; a restored value would outlive the members it named.
|
|
61045
|
+
*
|
|
61046
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61047
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61048
|
+
*/
|
|
61049
|
+
durability: "session",
|
|
61050
|
+
history: "none"
|
|
61051
|
+
};
|
|
61052
|
+
/**
|
|
60648
61053
|
* How many members of a helper group answered (D944). Counts are integers,
|
|
60649
61054
|
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60650
61055
|
* The reading itself stays on the output capability. History is none — the
|
|
@@ -60675,7 +61080,14 @@ var groupStatusCapability = {
|
|
|
60675
61080
|
deviceTypes: [
|
|
60676
61081
|
DeviceType.Sensor,
|
|
60677
61082
|
DeviceType.Switch,
|
|
60678
|
-
DeviceType.Light
|
|
61083
|
+
DeviceType.Light,
|
|
61084
|
+
DeviceType.Fan,
|
|
61085
|
+
DeviceType.Cover,
|
|
61086
|
+
DeviceType.Valve,
|
|
61087
|
+
DeviceType.Lock,
|
|
61088
|
+
DeviceType.MediaPlayer,
|
|
61089
|
+
DeviceType.Thermostat,
|
|
61090
|
+
DeviceType.Climate
|
|
60679
61091
|
],
|
|
60680
61092
|
methods: {},
|
|
60681
61093
|
status: {
|
|
@@ -61948,7 +62360,14 @@ var lockControlCapability = {
|
|
|
61948
62360
|
}),
|
|
61949
62361
|
unlock: method(object({
|
|
61950
62362
|
deviceId: number().int().nonnegative(),
|
|
61951
|
-
code: string().min(1).optional()
|
|
62363
|
+
code: string().min(1).optional(),
|
|
62364
|
+
/**
|
|
62365
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
62366
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
62367
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
62368
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
62369
|
+
*/
|
|
62370
|
+
confirm: boolean().optional()
|
|
61952
62371
|
}), _void(), {
|
|
61953
62372
|
kind: "mutation",
|
|
61954
62373
|
auth: "protected"
|
|
@@ -61985,6 +62404,44 @@ var lockControlCapability = {
|
|
|
61985
62404
|
volatileStateFields: ["lastChangedAt"]
|
|
61986
62405
|
};
|
|
61987
62406
|
/**
|
|
62407
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.kwhTotal`
|
|
62408
|
+
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
62409
|
+
* `value` is the time integral in the source quantity's accumulated base
|
|
62410
|
+
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
62411
|
+
*/
|
|
62412
|
+
var MeterStatusSchema = object({
|
|
62413
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
62414
|
+
lastFetchedAt: number()
|
|
62415
|
+
});
|
|
62416
|
+
var meterCapability = {
|
|
62417
|
+
name: "meter",
|
|
62418
|
+
scope: "device",
|
|
62419
|
+
deviceNative: true,
|
|
62420
|
+
mode: "singleton",
|
|
62421
|
+
deviceTypes: [DeviceType.Sensor],
|
|
62422
|
+
methods: {},
|
|
62423
|
+
status: {
|
|
62424
|
+
schema: MeterStatusSchema,
|
|
62425
|
+
kind: "push"
|
|
62426
|
+
},
|
|
62427
|
+
runtimeState: MeterStatusSchema,
|
|
62428
|
+
/**
|
|
62429
|
+
* Runtime-state durability: **restored** — the total is a cache of the
|
|
62430
|
+
* history integral. A restart shows it only until the history pass
|
|
62431
|
+
* recomputes the open period; it is not an in-memory buffer.
|
|
62432
|
+
*
|
|
62433
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
62434
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
62435
|
+
*/
|
|
62436
|
+
durability: "restored",
|
|
62437
|
+
history: { fields: { value: {
|
|
62438
|
+
kind: "counter",
|
|
62439
|
+
deadband: .001,
|
|
62440
|
+
minIntervalMs: 6e4
|
|
62441
|
+
} } },
|
|
62442
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
62443
|
+
};
|
|
62444
|
+
/**
|
|
61988
62445
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
61989
62446
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
61990
62447
|
* `DeviceType.MediaPlayer`. Disjoint from the camera streaming
|
|
@@ -64542,9 +64999,9 @@ var PowerMeterStatusSchema = object({
|
|
|
64542
64999
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64543
65000
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64544
65001
|
/** Voltage in volts. */
|
|
64545
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
65002
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
64546
65003
|
/** Current in amperes. */
|
|
64547
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
65004
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
64548
65005
|
/** Apparent power in volt-amperes. */
|
|
64549
65006
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64550
65007
|
/** Power factor (0..1) if reported. */
|
|
@@ -64552,12 +65009,74 @@ var PowerMeterStatusSchema = object({
|
|
|
64552
65009
|
/** Ms epoch when the slice was last updated. */
|
|
64553
65010
|
lastFetchedAt: number()
|
|
64554
65011
|
});
|
|
65012
|
+
/**
|
|
65013
|
+
* Loads that draw metered mains power (D951). The reading is a feature of the
|
|
65014
|
+
* device itself — a plug, a lamp, a fan, an air conditioner, a boiler, a
|
|
65015
|
+
* vacuum dock — not a separate sensor beside it. A `Sensor` stays: a clamp
|
|
65016
|
+
* meter or a standalone energy monitor IS the device. Cover, lock, valve,
|
|
65017
|
+
* camera and the like are left out: their draw is not what anyone meters.
|
|
65018
|
+
*/
|
|
65019
|
+
var POWER_METER_DEVICE_TYPES = [
|
|
65020
|
+
DeviceType.Sensor,
|
|
65021
|
+
DeviceType.Switch,
|
|
65022
|
+
DeviceType.Light,
|
|
65023
|
+
DeviceType.Fan,
|
|
65024
|
+
DeviceType.Climate,
|
|
65025
|
+
DeviceType.Thermostat,
|
|
65026
|
+
DeviceType.Humidifier,
|
|
65027
|
+
DeviceType.WaterHeater,
|
|
65028
|
+
DeviceType.MediaPlayer,
|
|
65029
|
+
DeviceType.Washer,
|
|
65030
|
+
DeviceType.Dryer,
|
|
65031
|
+
DeviceType.Dishwasher,
|
|
65032
|
+
DeviceType.Vacuum,
|
|
65033
|
+
DeviceType.LawnMower,
|
|
65034
|
+
DeviceType.PetFeeder
|
|
65035
|
+
];
|
|
65036
|
+
/** Everything but a bare `Sensor`: a sensor that takes its reading from another sensor adds nothing. */
|
|
65037
|
+
var POWER_METER_CUSTOMIZE_DEVICE_TYPES = POWER_METER_DEVICE_TYPES.filter((type) => type !== DeviceType.Sensor);
|
|
65038
|
+
/** One scalar target per reading; each is sourced from a device of its own (D951). */
|
|
65039
|
+
function powerTarget(id, unit) {
|
|
65040
|
+
return {
|
|
65041
|
+
id,
|
|
65042
|
+
cardinality: "scalar",
|
|
65043
|
+
vocabulary: {
|
|
65044
|
+
cap: "power-meter",
|
|
65045
|
+
stateField: id
|
|
65046
|
+
},
|
|
65047
|
+
deviceTypes: POWER_METER_CUSTOMIZE_DEVICE_TYPES,
|
|
65048
|
+
apply: "add",
|
|
65049
|
+
path: id,
|
|
65050
|
+
sources: [{
|
|
65051
|
+
kind: "numeric",
|
|
65052
|
+
requiredUnit: unit,
|
|
65053
|
+
transforms: [{ kind: "identity" }]
|
|
65054
|
+
}],
|
|
65055
|
+
companions: [{
|
|
65056
|
+
kind: "clock",
|
|
65057
|
+
path: "lastFetchedAt",
|
|
65058
|
+
when: "always"
|
|
65059
|
+
}],
|
|
65060
|
+
sourceReport: { status: "assignment-status" },
|
|
65061
|
+
advancedExpression: true
|
|
65062
|
+
};
|
|
65063
|
+
}
|
|
65064
|
+
/** "Power and energy" extension: watts, energy, voltage and current from other devices (D951). */
|
|
65065
|
+
var powerMeterCustomize = {
|
|
65066
|
+
version: 1,
|
|
65067
|
+
targets: [
|
|
65068
|
+
powerTarget("watts", "W"),
|
|
65069
|
+
powerTarget("kwhTotal", "kWh"),
|
|
65070
|
+
powerTarget("volts", "V"),
|
|
65071
|
+
powerTarget("amps", "A")
|
|
65072
|
+
]
|
|
65073
|
+
};
|
|
64555
65074
|
var powerMeterCapability = {
|
|
64556
65075
|
name: "power-meter",
|
|
64557
65076
|
scope: "device",
|
|
64558
65077
|
deviceNative: true,
|
|
64559
65078
|
mode: "singleton",
|
|
64560
|
-
deviceTypes:
|
|
65079
|
+
deviceTypes: POWER_METER_DEVICE_TYPES,
|
|
64561
65080
|
methods: {},
|
|
64562
65081
|
status: {
|
|
64563
65082
|
schema: PowerMeterStatusSchema,
|
|
@@ -64614,7 +65133,8 @@ var powerMeterCapability = {
|
|
|
64614
65133
|
} },
|
|
64615
65134
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64616
65135
|
* whether persisting is worth a SQLite commit. */
|
|
64617
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
65136
|
+
volatileStateFields: ["lastFetchedAt"],
|
|
65137
|
+
customize: powerMeterCustomize
|
|
64618
65138
|
};
|
|
64619
65139
|
/**
|
|
64620
65140
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -65407,6 +65927,8 @@ var runningCustomize = {
|
|
|
65407
65927
|
stateField: "running"
|
|
65408
65928
|
},
|
|
65409
65929
|
deviceTypes: [
|
|
65930
|
+
DeviceType.Washer,
|
|
65931
|
+
DeviceType.Dryer,
|
|
65410
65932
|
DeviceType.Dishwasher,
|
|
65411
65933
|
DeviceType.Vacuum,
|
|
65412
65934
|
DeviceType.LawnMower,
|
|
@@ -68200,7 +68722,8 @@ var switchCapability = {
|
|
|
68200
68722
|
deviceTypes: [
|
|
68201
68723
|
DeviceType.Switch,
|
|
68202
68724
|
DeviceType.Siren,
|
|
68203
|
-
DeviceType.Light
|
|
68725
|
+
DeviceType.Light,
|
|
68726
|
+
DeviceType.Fan
|
|
68204
68727
|
],
|
|
68205
68728
|
methods: { setState: method(object({
|
|
68206
68729
|
deviceId: number(),
|
|
@@ -70546,8 +71069,9 @@ function withClipEventLabels(provider, deps) {
|
|
|
70546
71069
|
listClips
|
|
70547
71070
|
};
|
|
70548
71071
|
}
|
|
71072
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
70549
71073
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
70550
|
-
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;
|
|
71074
|
+
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;
|
|
70551
71075
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
70552
71076
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
70553
71077
|
new Set(CAP_NAMES);
|
|
@@ -70876,6 +71400,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70876
71400
|
featureProbe: featureProbeCapability,
|
|
70877
71401
|
flood: floodCapability,
|
|
70878
71402
|
gas: gasCapability,
|
|
71403
|
+
groupActive: groupActiveCapability,
|
|
70879
71404
|
groupCommands: groupCommandsCapability,
|
|
70880
71405
|
groupStatus: groupStatusCapability,
|
|
70881
71406
|
heatingValve: heatingValveCapability,
|
|
@@ -70887,6 +71412,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70887
71412
|
lawnMowerControl: lawnMowerControlCapability,
|
|
70888
71413
|
lockControl: lockControlCapability,
|
|
70889
71414
|
mediaPlayer: mediaPlayerCapability,
|
|
71415
|
+
meter: meterCapability,
|
|
70890
71416
|
motion: motionCapability,
|
|
70891
71417
|
motionTrigger: motionTriggerCapability,
|
|
70892
71418
|
motionZones: motionZonesCapability,
|
|
@@ -72150,7 +72676,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
72150
72676
|
function widenDeviceConstructor(ctor) {
|
|
72151
72677
|
return ctor;
|
|
72152
72678
|
}
|
|
72153
|
-
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;
|
|
72679
|
+
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;
|
|
72154
72680
|
new Set(Object.values(DeviceType));
|
|
72155
72681
|
Object.freeze({
|
|
72156
72682
|
"accessories.getStatus": {
|
|
@@ -75373,6 +75899,13 @@ Object.freeze({
|
|
|
75373
75899
|
access: "view",
|
|
75374
75900
|
role: "viewer"
|
|
75375
75901
|
},
|
|
75902
|
+
"groupActive.getStatus": {
|
|
75903
|
+
capName: "group-active",
|
|
75904
|
+
capScope: "device",
|
|
75905
|
+
addonId: null,
|
|
75906
|
+
access: "view",
|
|
75907
|
+
role: "viewer"
|
|
75908
|
+
},
|
|
75376
75909
|
"groupCommands.getStatus": {
|
|
75377
75910
|
capName: "group-commands",
|
|
75378
75911
|
capScope: "device",
|
|
@@ -76339,6 +76872,13 @@ Object.freeze({
|
|
|
76339
76872
|
access: "create",
|
|
76340
76873
|
role: "admin"
|
|
76341
76874
|
},
|
|
76875
|
+
"meter.getStatus": {
|
|
76876
|
+
capName: "meter",
|
|
76877
|
+
capScope: "device",
|
|
76878
|
+
addonId: null,
|
|
76879
|
+
access: "view",
|
|
76880
|
+
role: "viewer"
|
|
76881
|
+
},
|
|
76342
76882
|
"metricsProvider.collectSnapshot": {
|
|
76343
76883
|
capName: "metrics-provider",
|
|
76344
76884
|
capScope: "system",
|
|
@@ -84437,7 +84977,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84437
84977
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
84438
84978
|
icon: "square"
|
|
84439
84979
|
}
|
|
84440
|
-
}
|
|
84980
|
+
},
|
|
84981
|
+
overrides: { byType: {
|
|
84982
|
+
[DeviceType.Washer]: {
|
|
84983
|
+
state: { running: {
|
|
84984
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
84985
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
84986
|
+
} },
|
|
84987
|
+
events: {
|
|
84988
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
84989
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
84990
|
+
}
|
|
84991
|
+
},
|
|
84992
|
+
[DeviceType.Dryer]: {
|
|
84993
|
+
state: { running: {
|
|
84994
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
84995
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
84996
|
+
} },
|
|
84997
|
+
events: {
|
|
84998
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
84999
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
85000
|
+
}
|
|
85001
|
+
},
|
|
85002
|
+
[DeviceType.Dishwasher]: {
|
|
85003
|
+
state: { running: {
|
|
85004
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
85005
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
85006
|
+
} },
|
|
85007
|
+
events: {
|
|
85008
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
85009
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
85010
|
+
}
|
|
85011
|
+
}
|
|
85012
|
+
} }
|
|
84441
85013
|
},
|
|
84442
85014
|
update: {
|
|
84443
85015
|
scope: "device",
|
|
@@ -85209,6 +85781,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85209
85781
|
icon: "flame"
|
|
85210
85782
|
}]
|
|
85211
85783
|
},
|
|
85784
|
+
"group-active": {
|
|
85785
|
+
scope: "device",
|
|
85786
|
+
noun: t("Group state", "Stato del gruppo")
|
|
85787
|
+
},
|
|
85212
85788
|
"group-commands": {
|
|
85213
85789
|
scope: "device",
|
|
85214
85790
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -85265,6 +85841,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85265
85841
|
}],
|
|
85266
85842
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
85267
85843
|
},
|
|
85844
|
+
meter: {
|
|
85845
|
+
scope: "device",
|
|
85846
|
+
noun: t("Meter", "Contatore"),
|
|
85847
|
+
state: [{
|
|
85848
|
+
kind: "numeric",
|
|
85849
|
+
field: "value",
|
|
85850
|
+
quantity: t("the total", "il totale"),
|
|
85851
|
+
label: t("Total", "Totale"),
|
|
85852
|
+
icon: "gauge"
|
|
85853
|
+
}]
|
|
85854
|
+
},
|
|
85268
85855
|
"numeric-sensor": {
|
|
85269
85856
|
scope: "device",
|
|
85270
85857
|
noun: t("Sensor", "Sensore"),
|
|
@@ -85737,8 +86324,47 @@ function projectAction(cap, action) {
|
|
|
85737
86324
|
};
|
|
85738
86325
|
}
|
|
85739
86326
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
85740
|
-
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;
|
|
86327
|
+
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;
|
|
85741
86328
|
DeviceFeature.BatteryOperated;
|
|
86329
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
86330
|
+
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.";
|
|
86331
|
+
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.";
|
|
86332
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
86333
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
86334
|
+
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.";
|
|
86335
|
+
function withheld(reason) {
|
|
86336
|
+
return {
|
|
86337
|
+
[DeviceType.Washer]: {
|
|
86338
|
+
exported: false,
|
|
86339
|
+
reason
|
|
86340
|
+
},
|
|
86341
|
+
[DeviceType.Dryer]: {
|
|
86342
|
+
exported: false,
|
|
86343
|
+
reason
|
|
86344
|
+
},
|
|
86345
|
+
[DeviceType.Dishwasher]: {
|
|
86346
|
+
exported: false,
|
|
86347
|
+
reason
|
|
86348
|
+
}
|
|
86349
|
+
};
|
|
86350
|
+
}
|
|
86351
|
+
function offered(received) {
|
|
86352
|
+
return {
|
|
86353
|
+
[DeviceType.Washer]: {
|
|
86354
|
+
exported: true,
|
|
86355
|
+
as: received
|
|
86356
|
+
},
|
|
86357
|
+
[DeviceType.Dryer]: {
|
|
86358
|
+
exported: true,
|
|
86359
|
+
as: received
|
|
86360
|
+
},
|
|
86361
|
+
[DeviceType.Dishwasher]: {
|
|
86362
|
+
exported: true,
|
|
86363
|
+
as: received
|
|
86364
|
+
}
|
|
86365
|
+
};
|
|
86366
|
+
}
|
|
86367
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
85742
86368
|
/** Reject after `ms`; always clears its own timer. */
|
|
85743
86369
|
async function withTimeout$1(promise, ms, label) {
|
|
85744
86370
|
let timer;
|
|
@@ -86911,6 +87537,11 @@ Object.freeze({
|
|
|
86911
87537
|
form: "single",
|
|
86912
87538
|
optional: false
|
|
86913
87539
|
}],
|
|
87540
|
+
"groupActive.getStatus": [{
|
|
87541
|
+
name: "deviceId",
|
|
87542
|
+
form: "single",
|
|
87543
|
+
optional: false
|
|
87544
|
+
}],
|
|
86914
87545
|
"groupCommands.getStatus": [{
|
|
86915
87546
|
name: "deviceId",
|
|
86916
87547
|
form: "single",
|
|
@@ -87121,6 +87752,11 @@ Object.freeze({
|
|
|
87121
87752
|
form: "single",
|
|
87122
87753
|
optional: false
|
|
87123
87754
|
}],
|
|
87755
|
+
"meter.getStatus": [{
|
|
87756
|
+
name: "deviceId",
|
|
87757
|
+
form: "single",
|
|
87758
|
+
optional: false
|
|
87759
|
+
}],
|
|
87124
87760
|
"motion.getStatus": [{
|
|
87125
87761
|
name: "deviceId",
|
|
87126
87762
|
form: "single",
|
|
@@ -88728,7 +89364,6 @@ Object.freeze({
|
|
|
88728
89364
|
"network-access": "ingress",
|
|
88729
89365
|
"smtp-provider": "email"
|
|
88730
89366
|
});
|
|
88731
|
-
DeviceType.Camera;
|
|
88732
89367
|
/**
|
|
88733
89368
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
88734
89369
|
* `z.infer`, they do not restate the shape.
|