@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.js
CHANGED
|
@@ -5478,7 +5478,7 @@ var ZodIssueCode = {
|
|
|
5478
5478
|
var ZodFirstPartyTypeKind;
|
|
5479
5479
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5480
5480
|
//#endregion
|
|
5481
|
-
//#region ../types/dist/sleep
|
|
5481
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5482
5482
|
/**
|
|
5483
5483
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5484
5484
|
* window to float samples (D455).
|
|
@@ -8671,6 +8671,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8671
8671
|
"filesystem-browse",
|
|
8672
8672
|
"flood",
|
|
8673
8673
|
"gas",
|
|
8674
|
+
"group-active",
|
|
8674
8675
|
"group-commands",
|
|
8675
8676
|
"group-status",
|
|
8676
8677
|
"heating-valve",
|
|
@@ -8693,6 +8694,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8693
8694
|
"login-method",
|
|
8694
8695
|
"media-player",
|
|
8695
8696
|
"mesh-network",
|
|
8697
|
+
"meter",
|
|
8696
8698
|
"metrics-provider",
|
|
8697
8699
|
"model-convert",
|
|
8698
8700
|
"model-distributor",
|
|
@@ -9491,6 +9493,10 @@ Object.freeze({
|
|
|
9491
9493
|
"path": "detected",
|
|
9492
9494
|
"valueType": "boolean"
|
|
9493
9495
|
}],
|
|
9496
|
+
"group-active": [{
|
|
9497
|
+
"path": "active",
|
|
9498
|
+
"valueType": "boolean"
|
|
9499
|
+
}],
|
|
9494
9500
|
"group-status": [
|
|
9495
9501
|
{
|
|
9496
9502
|
"path": "included",
|
|
@@ -9750,6 +9756,10 @@ Object.freeze({
|
|
|
9750
9756
|
]
|
|
9751
9757
|
}
|
|
9752
9758
|
],
|
|
9759
|
+
"meter": [{
|
|
9760
|
+
"path": "value",
|
|
9761
|
+
"valueType": "number"
|
|
9762
|
+
}],
|
|
9753
9763
|
"motion": [
|
|
9754
9764
|
{
|
|
9755
9765
|
"path": "detected",
|
|
@@ -10507,7 +10517,7 @@ function userError(code, params, englishFallback) {
|
|
|
10507
10517
|
return new CamstackError(code, params, englishFallback);
|
|
10508
10518
|
}
|
|
10509
10519
|
//#endregion
|
|
10510
|
-
//#region ../types/dist/err-msg-
|
|
10520
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
10511
10521
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
10512
10522
|
DeviceType["Camera"] = "camera";
|
|
10513
10523
|
DeviceType["Hub"] = "hub";
|
|
@@ -10601,8 +10611,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
10601
10611
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
10602
10612
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
10603
10613
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
10604
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10614
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10615
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
10605
10616
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
10617
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
10618
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
10619
|
+
DeviceType["Washer"] = "washer";
|
|
10620
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
10621
|
+
DeviceType["Dryer"] = "dryer";
|
|
10606
10622
|
return DeviceType;
|
|
10607
10623
|
}({});
|
|
10608
10624
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -10850,7 +10866,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10850
10866
|
return DeviceRole;
|
|
10851
10867
|
}({});
|
|
10852
10868
|
//#endregion
|
|
10853
|
-
//#region ../types/dist/composition-
|
|
10869
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
10854
10870
|
/**
|
|
10855
10871
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10856
10872
|
*
|
|
@@ -11165,6 +11181,13 @@ var table = {
|
|
|
11165
11181
|
apply: () => {
|
|
11166
11182
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11167
11183
|
}
|
|
11184
|
+
},
|
|
11185
|
+
schmitt: {
|
|
11186
|
+
minArgs: 3,
|
|
11187
|
+
maxArgs: 5,
|
|
11188
|
+
apply: () => {
|
|
11189
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11190
|
+
}
|
|
11168
11191
|
}
|
|
11169
11192
|
};
|
|
11170
11193
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11606,6 +11629,99 @@ function validateExpressionSource(src) {
|
|
|
11606
11629
|
return null;
|
|
11607
11630
|
}
|
|
11608
11631
|
/**
|
|
11632
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
11633
|
+
*
|
|
11634
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
11635
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
11636
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
11637
|
+
*
|
|
11638
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
11639
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
11640
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
11641
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
11642
|
+
* can move later without moving the others.
|
|
11643
|
+
*/
|
|
11644
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
11645
|
+
var APPLIANCE_KINDS = [
|
|
11646
|
+
"washer",
|
|
11647
|
+
"dryer",
|
|
11648
|
+
"dishwasher"
|
|
11649
|
+
];
|
|
11650
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11651
|
+
/**
|
|
11652
|
+
* Statistics and integrals over a history read (D944).
|
|
11653
|
+
*
|
|
11654
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11655
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11656
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11657
|
+
* as zero. A truncated read is not published.
|
|
11658
|
+
*/
|
|
11659
|
+
var STATISTIC_STATS = [
|
|
11660
|
+
"min",
|
|
11661
|
+
"max",
|
|
11662
|
+
"mean",
|
|
11663
|
+
"sum",
|
|
11664
|
+
"count",
|
|
11665
|
+
"change"
|
|
11666
|
+
];
|
|
11667
|
+
/**
|
|
11668
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11669
|
+
*
|
|
11670
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11671
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11672
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11673
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11674
|
+
*/
|
|
11675
|
+
var MINUTE_MS = 6e4;
|
|
11676
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11677
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11678
|
+
var ROLLING_SPANS = [
|
|
11679
|
+
"1h",
|
|
11680
|
+
"24h",
|
|
11681
|
+
"2d",
|
|
11682
|
+
"7d",
|
|
11683
|
+
"30d",
|
|
11684
|
+
"custom"
|
|
11685
|
+
];
|
|
11686
|
+
var CALENDAR_PERIODS = [
|
|
11687
|
+
"today",
|
|
11688
|
+
"yesterday",
|
|
11689
|
+
"this-week",
|
|
11690
|
+
"this-month"
|
|
11691
|
+
];
|
|
11692
|
+
var RESET_PERIODS = [
|
|
11693
|
+
"never",
|
|
11694
|
+
"daily",
|
|
11695
|
+
"weekly",
|
|
11696
|
+
"monthly"
|
|
11697
|
+
];
|
|
11698
|
+
5 * MINUTE_MS;
|
|
11699
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11700
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11701
|
+
var rollingWindowObject = object({
|
|
11702
|
+
kind: literal("rolling"),
|
|
11703
|
+
span: _enum(ROLLING_SPANS),
|
|
11704
|
+
customMinutes: number().int().min(5).optional()
|
|
11705
|
+
}).check((payload) => {
|
|
11706
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11707
|
+
code: "custom",
|
|
11708
|
+
message: "a custom range needs a duration in minutes",
|
|
11709
|
+
path: ["customMinutes"],
|
|
11710
|
+
input: payload.value
|
|
11711
|
+
});
|
|
11712
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11713
|
+
code: "custom",
|
|
11714
|
+
message: "only a custom range carries a duration",
|
|
11715
|
+
path: ["customMinutes"],
|
|
11716
|
+
input: payload.value
|
|
11717
|
+
});
|
|
11718
|
+
});
|
|
11719
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
11720
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
11721
|
+
kind: literal("calendar"),
|
|
11722
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11723
|
+
})]);
|
|
11724
|
+
/**
|
|
11609
11725
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11610
11726
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11611
11727
|
* `composition.ts` (D659).
|
|
@@ -11631,7 +11747,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11631
11747
|
"occupancy",
|
|
11632
11748
|
"binary",
|
|
11633
11749
|
"switch",
|
|
11634
|
-
"light"
|
|
11750
|
+
"light",
|
|
11751
|
+
"fan",
|
|
11752
|
+
"cover",
|
|
11753
|
+
"valve",
|
|
11754
|
+
"lock",
|
|
11755
|
+
"media-player",
|
|
11756
|
+
"climate"
|
|
11635
11757
|
];
|
|
11636
11758
|
var NUMERIC_AGGREGATES = [
|
|
11637
11759
|
"mean",
|
|
@@ -11661,14 +11783,73 @@ var HelperMemberSchema = object({
|
|
|
11661
11783
|
cap: string().min(1),
|
|
11662
11784
|
fieldPath: string().min(1)
|
|
11663
11785
|
});
|
|
11664
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11665
|
-
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
|
|
11670
|
-
|
|
11671
|
-
|
|
11786
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11787
|
+
object({
|
|
11788
|
+
kind: literal("group"),
|
|
11789
|
+
templateId: GroupTemplateIdSchema,
|
|
11790
|
+
aggregate: AggregateReducerSchema,
|
|
11791
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11792
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11793
|
+
active: ActiveCriterionSchema.optional()
|
|
11794
|
+
}),
|
|
11795
|
+
object({
|
|
11796
|
+
kind: literal("appliance"),
|
|
11797
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
11798
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
11799
|
+
thresholdWatts: number().positive(),
|
|
11800
|
+
startDwellMs: number().int().nonnegative(),
|
|
11801
|
+
stopDwellMs: number().int().nonnegative(),
|
|
11802
|
+
member: HelperMemberSchema
|
|
11803
|
+
}),
|
|
11804
|
+
object({
|
|
11805
|
+
kind: literal("statistic"),
|
|
11806
|
+
stat: _enum(STATISTIC_STATS),
|
|
11807
|
+
window: StatisticWindowSchema,
|
|
11808
|
+
source: HelperMemberSchema
|
|
11809
|
+
}),
|
|
11810
|
+
object({
|
|
11811
|
+
kind: literal("integral"),
|
|
11812
|
+
reset: _enum(RESET_PERIODS),
|
|
11813
|
+
output: _enum(["energy", "meter"]),
|
|
11814
|
+
source: HelperMemberSchema
|
|
11815
|
+
}),
|
|
11816
|
+
object({
|
|
11817
|
+
kind: literal("threshold"),
|
|
11818
|
+
source: HelperMemberSchema,
|
|
11819
|
+
high: number(),
|
|
11820
|
+
low: number(),
|
|
11821
|
+
onForMs: number().int().nonnegative(),
|
|
11822
|
+
offForMs: number().int().nonnegative()
|
|
11823
|
+
}),
|
|
11824
|
+
object({
|
|
11825
|
+
kind: literal("arithmetic"),
|
|
11826
|
+
op: _enum([
|
|
11827
|
+
"sum",
|
|
11828
|
+
"difference",
|
|
11829
|
+
"ratio"
|
|
11830
|
+
]),
|
|
11831
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
11832
|
+
}),
|
|
11833
|
+
object({
|
|
11834
|
+
kind: literal("expression"),
|
|
11835
|
+
expr: string().min(1),
|
|
11836
|
+
inputs: array(object({
|
|
11837
|
+
name: string().min(1),
|
|
11838
|
+
member: HelperMemberSchema
|
|
11839
|
+
})).min(1).max(64),
|
|
11840
|
+
output: _enum(["number", "boolean"])
|
|
11841
|
+
}),
|
|
11842
|
+
object({
|
|
11843
|
+
kind: literal("derivative"),
|
|
11844
|
+
window: RollingWindowSchema,
|
|
11845
|
+
per: _enum([
|
|
11846
|
+
"second",
|
|
11847
|
+
"minute",
|
|
11848
|
+
"hour"
|
|
11849
|
+
]),
|
|
11850
|
+
source: HelperMemberSchema
|
|
11851
|
+
})
|
|
11852
|
+
]);
|
|
11672
11853
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11673
11854
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11674
11855
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -11729,6 +11910,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11729
11910
|
"all"
|
|
11730
11911
|
]),
|
|
11731
11912
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11913
|
+
/**
|
|
11914
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
11915
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
11916
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
11917
|
+
*/
|
|
11918
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
11732
11919
|
/** `value` is the reading; the others are the member counts. */
|
|
11733
11920
|
publish: _enum([
|
|
11734
11921
|
"value",
|
|
@@ -11742,6 +11929,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11742
11929
|
"omit",
|
|
11743
11930
|
"offline"
|
|
11744
11931
|
])
|
|
11932
|
+
}),
|
|
11933
|
+
object({
|
|
11934
|
+
kind: literal("series"),
|
|
11935
|
+
read: CompositionFieldReadSchema,
|
|
11936
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
11937
|
+
publish: _enum([
|
|
11938
|
+
"value",
|
|
11939
|
+
"included",
|
|
11940
|
+
"excluded",
|
|
11941
|
+
"total"
|
|
11942
|
+
]),
|
|
11943
|
+
/**
|
|
11944
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
11945
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
11946
|
+
*/
|
|
11947
|
+
empty: _enum([
|
|
11948
|
+
"null",
|
|
11949
|
+
"omit",
|
|
11950
|
+
"offline"
|
|
11951
|
+
])
|
|
11745
11952
|
})
|
|
11746
11953
|
]);
|
|
11747
11954
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -16939,7 +17146,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
16939
17146
|
*/
|
|
16940
17147
|
interactiveConnectPath: string().min(1).optional(),
|
|
16941
17148
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
16942
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
17149
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
17150
|
+
/**
|
|
17151
|
+
* The kind signs in through a server-held interactive session instead of
|
|
17152
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
17153
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
17154
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
17155
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
17156
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
17157
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
17158
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
17159
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
17160
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
17161
|
+
* offers it as the default path; the fields the session fills are
|
|
17162
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
17163
|
+
*/
|
|
17164
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
16943
17165
|
}))
|
|
16944
17166
|
});
|
|
16945
17167
|
var ListInputSchema = object({
|
|
@@ -18044,7 +18266,8 @@ var CompositionProblemSchema = object({
|
|
|
18044
18266
|
"native-capability-replace",
|
|
18045
18267
|
"mixed-quantity",
|
|
18046
18268
|
"helper-mismatch",
|
|
18047
|
-
"member-constraint"
|
|
18269
|
+
"member-constraint",
|
|
18270
|
+
"retention"
|
|
18048
18271
|
]),
|
|
18049
18272
|
path: string(),
|
|
18050
18273
|
message: string()
|
|
@@ -18278,13 +18501,17 @@ Object.freeze({
|
|
|
18278
18501
|
latchedAt: {
|
|
18279
18502
|
kind: "fixed",
|
|
18280
18503
|
result: ["number", "null"]
|
|
18504
|
+
},
|
|
18505
|
+
schmitt: {
|
|
18506
|
+
kind: "fixed",
|
|
18507
|
+
result: ["boolean", "null"]
|
|
18281
18508
|
}
|
|
18282
18509
|
});
|
|
18283
18510
|
/**
|
|
18284
18511
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18285
18512
|
* Data, not a form default written into the block.
|
|
18286
18513
|
*/
|
|
18287
|
-
var NOW = {
|
|
18514
|
+
var NOW$2 = {
|
|
18288
18515
|
fieldPath: "lastFetchedAt",
|
|
18289
18516
|
expr: "now"
|
|
18290
18517
|
};
|
|
@@ -18298,6 +18525,8 @@ function numeric(input) {
|
|
|
18298
18525
|
family: "numeric",
|
|
18299
18526
|
deviceType: DeviceType.Sensor,
|
|
18300
18527
|
memberDeviceType: DeviceType.Sensor,
|
|
18528
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18529
|
+
activeWhen: void 0,
|
|
18301
18530
|
commandCaps: [],
|
|
18302
18531
|
baseUnit: baseUnitOf(input.quantity),
|
|
18303
18532
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18313,6 +18542,8 @@ function binary(input) {
|
|
|
18313
18542
|
family: "binary",
|
|
18314
18543
|
deviceType: DeviceType.Sensor,
|
|
18315
18544
|
memberDeviceType: DeviceType.Sensor,
|
|
18545
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18546
|
+
activeWhen: void 0,
|
|
18316
18547
|
commandCaps: [],
|
|
18317
18548
|
quantity: "none",
|
|
18318
18549
|
baseUnit: void 0,
|
|
@@ -18330,7 +18561,7 @@ var GROUP_TEMPLATES = [
|
|
|
18330
18561
|
quantity: "temperature",
|
|
18331
18562
|
defaultAggregate: "mean",
|
|
18332
18563
|
empty: "null",
|
|
18333
|
-
companions: [NOW]
|
|
18564
|
+
companions: [NOW$2]
|
|
18334
18565
|
}),
|
|
18335
18566
|
numeric({
|
|
18336
18567
|
id: "humidity",
|
|
@@ -18341,7 +18572,7 @@ var GROUP_TEMPLATES = [
|
|
|
18341
18572
|
quantity: "humidity",
|
|
18342
18573
|
defaultAggregate: "mean",
|
|
18343
18574
|
empty: "null",
|
|
18344
|
-
companions: [NOW]
|
|
18575
|
+
companions: [NOW$2]
|
|
18345
18576
|
}),
|
|
18346
18577
|
numeric({
|
|
18347
18578
|
id: "pressure",
|
|
@@ -18352,7 +18583,7 @@ var GROUP_TEMPLATES = [
|
|
|
18352
18583
|
quantity: "pressure",
|
|
18353
18584
|
defaultAggregate: "mean",
|
|
18354
18585
|
empty: "null",
|
|
18355
|
-
companions: [NOW]
|
|
18586
|
+
companions: [NOW$2]
|
|
18356
18587
|
}),
|
|
18357
18588
|
numeric({
|
|
18358
18589
|
id: "illuminance",
|
|
@@ -18363,7 +18594,7 @@ var GROUP_TEMPLATES = [
|
|
|
18363
18594
|
quantity: "illuminance",
|
|
18364
18595
|
defaultAggregate: "mean",
|
|
18365
18596
|
empty: "null",
|
|
18366
|
-
companions: [NOW]
|
|
18597
|
+
companions: [NOW$2]
|
|
18367
18598
|
}),
|
|
18368
18599
|
numeric({
|
|
18369
18600
|
id: "power",
|
|
@@ -18374,7 +18605,7 @@ var GROUP_TEMPLATES = [
|
|
|
18374
18605
|
quantity: "power",
|
|
18375
18606
|
defaultAggregate: "sum",
|
|
18376
18607
|
empty: "omit",
|
|
18377
|
-
companions: [NOW]
|
|
18608
|
+
companions: [NOW$2]
|
|
18378
18609
|
}),
|
|
18379
18610
|
numeric({
|
|
18380
18611
|
id: "energy",
|
|
@@ -18385,7 +18616,7 @@ var GROUP_TEMPLATES = [
|
|
|
18385
18616
|
quantity: "energy",
|
|
18386
18617
|
defaultAggregate: "sum",
|
|
18387
18618
|
empty: "omit",
|
|
18388
|
-
companions: [NOW]
|
|
18619
|
+
companions: [NOW$2]
|
|
18389
18620
|
}),
|
|
18390
18621
|
numeric({
|
|
18391
18622
|
id: "battery",
|
|
@@ -18420,7 +18651,7 @@ var GROUP_TEMPLATES = [
|
|
|
18420
18651
|
quantity: "device",
|
|
18421
18652
|
defaultAggregate: "mean",
|
|
18422
18653
|
empty: "null",
|
|
18423
|
-
companions: [NOW]
|
|
18654
|
+
companions: [NOW$2]
|
|
18424
18655
|
}),
|
|
18425
18656
|
binary({
|
|
18426
18657
|
id: "motion",
|
|
@@ -18514,6 +18745,11 @@ var GROUP_TEMPLATES = [
|
|
|
18514
18745
|
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.",
|
|
18515
18746
|
deviceType: DeviceType.Switch,
|
|
18516
18747
|
outputCap: "switch",
|
|
18748
|
+
outputField: "on",
|
|
18749
|
+
member: {
|
|
18750
|
+
cap: "switch",
|
|
18751
|
+
fieldPath: "on"
|
|
18752
|
+
},
|
|
18517
18753
|
commandCaps: ["switch"]
|
|
18518
18754
|
}),
|
|
18519
18755
|
actuator({
|
|
@@ -18521,34 +18757,136 @@ var GROUP_TEMPLATES = [
|
|
|
18521
18757
|
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.",
|
|
18522
18758
|
deviceType: DeviceType.Light,
|
|
18523
18759
|
outputCap: "switch",
|
|
18760
|
+
outputField: "on",
|
|
18761
|
+
member: {
|
|
18762
|
+
cap: "switch",
|
|
18763
|
+
fieldPath: "on"
|
|
18764
|
+
},
|
|
18524
18765
|
commandCaps: [
|
|
18525
18766
|
"switch",
|
|
18526
18767
|
"brightness",
|
|
18527
18768
|
"color"
|
|
18528
18769
|
]
|
|
18770
|
+
}),
|
|
18771
|
+
actuator({
|
|
18772
|
+
id: "fan",
|
|
18773
|
+
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.",
|
|
18774
|
+
deviceType: DeviceType.Fan,
|
|
18775
|
+
outputCap: "switch",
|
|
18776
|
+
outputField: "on",
|
|
18777
|
+
member: {
|
|
18778
|
+
cap: "switch",
|
|
18779
|
+
fieldPath: "on"
|
|
18780
|
+
},
|
|
18781
|
+
commandCaps: ["switch", "fan-control"]
|
|
18782
|
+
}),
|
|
18783
|
+
actuator({
|
|
18784
|
+
id: "cover",
|
|
18785
|
+
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.",
|
|
18786
|
+
deviceType: DeviceType.Cover,
|
|
18787
|
+
outputCap: "group-active",
|
|
18788
|
+
outputField: "active",
|
|
18789
|
+
member: {
|
|
18790
|
+
cap: "cover",
|
|
18791
|
+
fieldPath: "state"
|
|
18792
|
+
},
|
|
18793
|
+
activeWhen: [
|
|
18794
|
+
"open",
|
|
18795
|
+
"opening",
|
|
18796
|
+
"stopped"
|
|
18797
|
+
],
|
|
18798
|
+
commandCaps: ["cover"]
|
|
18799
|
+
}),
|
|
18800
|
+
actuator({
|
|
18801
|
+
id: "valve",
|
|
18802
|
+
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.",
|
|
18803
|
+
deviceType: DeviceType.Valve,
|
|
18804
|
+
outputCap: "group-active",
|
|
18805
|
+
outputField: "active",
|
|
18806
|
+
member: {
|
|
18807
|
+
cap: "valve",
|
|
18808
|
+
fieldPath: "state"
|
|
18809
|
+
},
|
|
18810
|
+
activeWhen: [
|
|
18811
|
+
"open",
|
|
18812
|
+
"opening",
|
|
18813
|
+
"stopped"
|
|
18814
|
+
],
|
|
18815
|
+
commandCaps: ["valve"]
|
|
18816
|
+
}),
|
|
18817
|
+
actuator({
|
|
18818
|
+
id: "lock",
|
|
18819
|
+
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.",
|
|
18820
|
+
deviceType: DeviceType.Lock,
|
|
18821
|
+
outputCap: "group-active",
|
|
18822
|
+
outputField: "active",
|
|
18823
|
+
member: {
|
|
18824
|
+
cap: "lock-control",
|
|
18825
|
+
fieldPath: "state"
|
|
18826
|
+
},
|
|
18827
|
+
activeWhen: ["locked"],
|
|
18828
|
+
commandCaps: ["lock-control"]
|
|
18829
|
+
}),
|
|
18830
|
+
actuator({
|
|
18831
|
+
id: "media-player",
|
|
18832
|
+
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.",
|
|
18833
|
+
deviceType: DeviceType.MediaPlayer,
|
|
18834
|
+
outputCap: "group-active",
|
|
18835
|
+
outputField: "active",
|
|
18836
|
+
member: {
|
|
18837
|
+
cap: "media-player",
|
|
18838
|
+
fieldPath: "state"
|
|
18839
|
+
},
|
|
18840
|
+
activeWhen: ["playing", "buffering"],
|
|
18841
|
+
commandCaps: ["media-player"]
|
|
18842
|
+
}),
|
|
18843
|
+
actuator({
|
|
18844
|
+
id: "climate",
|
|
18845
|
+
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.",
|
|
18846
|
+
deviceType: DeviceType.Thermostat,
|
|
18847
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
18848
|
+
outputCap: "group-active",
|
|
18849
|
+
outputField: "active",
|
|
18850
|
+
member: {
|
|
18851
|
+
cap: "climate-control",
|
|
18852
|
+
fieldPath: "mode"
|
|
18853
|
+
},
|
|
18854
|
+
activeWhen: [
|
|
18855
|
+
"heat",
|
|
18856
|
+
"cool",
|
|
18857
|
+
"auto",
|
|
18858
|
+
"heat_cool",
|
|
18859
|
+
"fan_only",
|
|
18860
|
+
"dry"
|
|
18861
|
+
],
|
|
18862
|
+
commandCaps: ["climate-control"]
|
|
18529
18863
|
})
|
|
18530
18864
|
];
|
|
18531
18865
|
function actuator(input) {
|
|
18532
18866
|
return {
|
|
18533
|
-
|
|
18867
|
+
id: input.id,
|
|
18868
|
+
summary: input.summary,
|
|
18869
|
+
deviceType: input.deviceType,
|
|
18870
|
+
outputCap: input.outputCap,
|
|
18871
|
+
outputField: input.outputField,
|
|
18872
|
+
commandCaps: input.commandCaps,
|
|
18534
18873
|
family: "actuator",
|
|
18535
18874
|
role: void 0,
|
|
18536
18875
|
memberDeviceType: input.deviceType,
|
|
18537
|
-
|
|
18876
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
18877
|
+
activeWhen: input.activeWhen,
|
|
18538
18878
|
quantity: "none",
|
|
18539
18879
|
baseUnit: void 0,
|
|
18540
18880
|
aggregates: BINARY_AGGREGATES,
|
|
18541
18881
|
defaultAggregate: "any",
|
|
18542
18882
|
empty: "offline",
|
|
18543
|
-
accept: [
|
|
18544
|
-
cap: "switch",
|
|
18545
|
-
fieldPath: "on"
|
|
18546
|
-
}],
|
|
18883
|
+
accept: [input.member],
|
|
18547
18884
|
companions: [CHANGED]
|
|
18548
18885
|
};
|
|
18549
18886
|
}
|
|
18550
18887
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18551
18888
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18889
|
+
DeviceType.Camera;
|
|
18552
18890
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18553
18891
|
/**
|
|
18554
18892
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -43868,7 +44206,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
43868
44206
|
});
|
|
43869
44207
|
/**
|
|
43870
44208
|
* Optional, richer endpoint shape returned by providers that expose
|
|
43871
|
-
* MORE than one ingress concurrently (Tailscale
|
|
44209
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
43872
44210
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
43873
44211
|
* the originating provider config (mode + sourcePort) so the
|
|
43874
44212
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -46555,7 +46893,20 @@ var NcRuleInputSchema = object({
|
|
|
46555
46893
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
46556
46894
|
* path does not run Zod defaults.
|
|
46557
46895
|
*/
|
|
46558
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46896
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46897
|
+
/**
|
|
46898
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46899
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46900
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46901
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46902
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46903
|
+
*
|
|
46904
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46905
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46906
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46907
|
+
* `false`, so it needs no `clear` key.
|
|
46908
|
+
*/
|
|
46909
|
+
askVerdict: boolean().optional()
|
|
46559
46910
|
});
|
|
46560
46911
|
/**
|
|
46561
46912
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -57788,7 +58139,8 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57788
58139
|
DeviceType.Switch,
|
|
57789
58140
|
DeviceType.PetFeeder,
|
|
57790
58141
|
DeviceType.Container,
|
|
57791
|
-
DeviceType.Thermostat
|
|
58142
|
+
DeviceType.Thermostat,
|
|
58143
|
+
DeviceType.EventEmitter
|
|
57792
58144
|
];
|
|
57793
58145
|
/** Generic Customize target for the percentage reading (D936). */
|
|
57794
58146
|
var batteryCustomize = {
|
|
@@ -60648,7 +61000,17 @@ var groupCommandsCapability = {
|
|
|
60648
61000
|
scope: "device",
|
|
60649
61001
|
deviceNative: true,
|
|
60650
61002
|
mode: "singleton",
|
|
60651
|
-
deviceTypes: [
|
|
61003
|
+
deviceTypes: [
|
|
61004
|
+
DeviceType.Switch,
|
|
61005
|
+
DeviceType.Light,
|
|
61006
|
+
DeviceType.Fan,
|
|
61007
|
+
DeviceType.Cover,
|
|
61008
|
+
DeviceType.Valve,
|
|
61009
|
+
DeviceType.Lock,
|
|
61010
|
+
DeviceType.MediaPlayer,
|
|
61011
|
+
DeviceType.Thermostat,
|
|
61012
|
+
DeviceType.Climate
|
|
61013
|
+
],
|
|
60652
61014
|
methods: {},
|
|
60653
61015
|
status: {
|
|
60654
61016
|
schema: GroupCommandsSchema,
|
|
@@ -60666,6 +61028,49 @@ var groupCommandsCapability = {
|
|
|
60666
61028
|
history: "none"
|
|
60667
61029
|
};
|
|
60668
61030
|
/**
|
|
61031
|
+
* Whether a helper actuator group counts as active (D944): at least one
|
|
61032
|
+
* included member is, or every included member is. What "active" means is the
|
|
61033
|
+
* type's: a cover is open, a lock is locked, a media player is playing, a
|
|
61034
|
+
* climate device is not off. A group of lights, switches and fans reports
|
|
61035
|
+
* `switch.on` instead; this cap is for the types whose own state is not a
|
|
61036
|
+
* yes/no. Unknown members are left out (`group-status` counts them) and an
|
|
61037
|
+
* empty included set takes the device offline, never `active: false`.
|
|
61038
|
+
*/
|
|
61039
|
+
var GroupActiveSchema = object({
|
|
61040
|
+
active: boolean().meta({ label: "Active" }),
|
|
61041
|
+
/** Ms epoch when the slice was last updated. */
|
|
61042
|
+
lastChangedAt: number()
|
|
61043
|
+
});
|
|
61044
|
+
var groupActiveCapability = {
|
|
61045
|
+
name: "group-active",
|
|
61046
|
+
scope: "device",
|
|
61047
|
+
deviceNative: true,
|
|
61048
|
+
mode: "singleton",
|
|
61049
|
+
deviceTypes: [
|
|
61050
|
+
DeviceType.Cover,
|
|
61051
|
+
DeviceType.Valve,
|
|
61052
|
+
DeviceType.Lock,
|
|
61053
|
+
DeviceType.MediaPlayer,
|
|
61054
|
+
DeviceType.Climate,
|
|
61055
|
+
DeviceType.Thermostat
|
|
61056
|
+
],
|
|
61057
|
+
methods: {},
|
|
61058
|
+
status: {
|
|
61059
|
+
schema: GroupActiveSchema,
|
|
61060
|
+
kind: "push"
|
|
61061
|
+
},
|
|
61062
|
+
runtimeState: GroupActiveSchema,
|
|
61063
|
+
/**
|
|
61064
|
+
* Runtime-state durability: **session** — recomputed from the members on the
|
|
61065
|
+
* next source event; a restored value would outlive the members it named.
|
|
61066
|
+
*
|
|
61067
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61068
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61069
|
+
*/
|
|
61070
|
+
durability: "session",
|
|
61071
|
+
history: "none"
|
|
61072
|
+
};
|
|
61073
|
+
/**
|
|
60669
61074
|
* How many members of a helper group answered (D944). Counts are integers,
|
|
60670
61075
|
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60671
61076
|
* The reading itself stays on the output capability. History is none — the
|
|
@@ -60696,7 +61101,14 @@ var groupStatusCapability = {
|
|
|
60696
61101
|
deviceTypes: [
|
|
60697
61102
|
DeviceType.Sensor,
|
|
60698
61103
|
DeviceType.Switch,
|
|
60699
|
-
DeviceType.Light
|
|
61104
|
+
DeviceType.Light,
|
|
61105
|
+
DeviceType.Fan,
|
|
61106
|
+
DeviceType.Cover,
|
|
61107
|
+
DeviceType.Valve,
|
|
61108
|
+
DeviceType.Lock,
|
|
61109
|
+
DeviceType.MediaPlayer,
|
|
61110
|
+
DeviceType.Thermostat,
|
|
61111
|
+
DeviceType.Climate
|
|
60700
61112
|
],
|
|
60701
61113
|
methods: {},
|
|
60702
61114
|
status: {
|
|
@@ -61969,7 +62381,14 @@ var lockControlCapability = {
|
|
|
61969
62381
|
}),
|
|
61970
62382
|
unlock: method(object({
|
|
61971
62383
|
deviceId: number().int().nonnegative(),
|
|
61972
|
-
code: string().min(1).optional()
|
|
62384
|
+
code: string().min(1).optional(),
|
|
62385
|
+
/**
|
|
62386
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
62387
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
62388
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
62389
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
62390
|
+
*/
|
|
62391
|
+
confirm: boolean().optional()
|
|
61973
62392
|
}), _void(), {
|
|
61974
62393
|
kind: "mutation",
|
|
61975
62394
|
auth: "protected"
|
|
@@ -62006,6 +62425,44 @@ var lockControlCapability = {
|
|
|
62006
62425
|
volatileStateFields: ["lastChangedAt"]
|
|
62007
62426
|
};
|
|
62008
62427
|
/**
|
|
62428
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.kwhTotal`
|
|
62429
|
+
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
62430
|
+
* `value` is the time integral in the source quantity's accumulated base
|
|
62431
|
+
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
62432
|
+
*/
|
|
62433
|
+
var MeterStatusSchema = object({
|
|
62434
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
62435
|
+
lastFetchedAt: number()
|
|
62436
|
+
});
|
|
62437
|
+
var meterCapability = {
|
|
62438
|
+
name: "meter",
|
|
62439
|
+
scope: "device",
|
|
62440
|
+
deviceNative: true,
|
|
62441
|
+
mode: "singleton",
|
|
62442
|
+
deviceTypes: [DeviceType.Sensor],
|
|
62443
|
+
methods: {},
|
|
62444
|
+
status: {
|
|
62445
|
+
schema: MeterStatusSchema,
|
|
62446
|
+
kind: "push"
|
|
62447
|
+
},
|
|
62448
|
+
runtimeState: MeterStatusSchema,
|
|
62449
|
+
/**
|
|
62450
|
+
* Runtime-state durability: **restored** — the total is a cache of the
|
|
62451
|
+
* history integral. A restart shows it only until the history pass
|
|
62452
|
+
* recomputes the open period; it is not an in-memory buffer.
|
|
62453
|
+
*
|
|
62454
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
62455
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
62456
|
+
*/
|
|
62457
|
+
durability: "restored",
|
|
62458
|
+
history: { fields: { value: {
|
|
62459
|
+
kind: "counter",
|
|
62460
|
+
deadband: .001,
|
|
62461
|
+
minIntervalMs: 6e4
|
|
62462
|
+
} } },
|
|
62463
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
62464
|
+
};
|
|
62465
|
+
/**
|
|
62009
62466
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
62010
62467
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
62011
62468
|
* `DeviceType.MediaPlayer`. Disjoint from the camera streaming
|
|
@@ -64563,9 +65020,9 @@ var PowerMeterStatusSchema = object({
|
|
|
64563
65020
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64564
65021
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64565
65022
|
/** Voltage in volts. */
|
|
64566
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
65023
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
64567
65024
|
/** Current in amperes. */
|
|
64568
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
65025
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
64569
65026
|
/** Apparent power in volt-amperes. */
|
|
64570
65027
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64571
65028
|
/** Power factor (0..1) if reported. */
|
|
@@ -64573,12 +65030,74 @@ var PowerMeterStatusSchema = object({
|
|
|
64573
65030
|
/** Ms epoch when the slice was last updated. */
|
|
64574
65031
|
lastFetchedAt: number()
|
|
64575
65032
|
});
|
|
65033
|
+
/**
|
|
65034
|
+
* Loads that draw metered mains power (D951). The reading is a feature of the
|
|
65035
|
+
* device itself — a plug, a lamp, a fan, an air conditioner, a boiler, a
|
|
65036
|
+
* vacuum dock — not a separate sensor beside it. A `Sensor` stays: a clamp
|
|
65037
|
+
* meter or a standalone energy monitor IS the device. Cover, lock, valve,
|
|
65038
|
+
* camera and the like are left out: their draw is not what anyone meters.
|
|
65039
|
+
*/
|
|
65040
|
+
var POWER_METER_DEVICE_TYPES = [
|
|
65041
|
+
DeviceType.Sensor,
|
|
65042
|
+
DeviceType.Switch,
|
|
65043
|
+
DeviceType.Light,
|
|
65044
|
+
DeviceType.Fan,
|
|
65045
|
+
DeviceType.Climate,
|
|
65046
|
+
DeviceType.Thermostat,
|
|
65047
|
+
DeviceType.Humidifier,
|
|
65048
|
+
DeviceType.WaterHeater,
|
|
65049
|
+
DeviceType.MediaPlayer,
|
|
65050
|
+
DeviceType.Washer,
|
|
65051
|
+
DeviceType.Dryer,
|
|
65052
|
+
DeviceType.Dishwasher,
|
|
65053
|
+
DeviceType.Vacuum,
|
|
65054
|
+
DeviceType.LawnMower,
|
|
65055
|
+
DeviceType.PetFeeder
|
|
65056
|
+
];
|
|
65057
|
+
/** Everything but a bare `Sensor`: a sensor that takes its reading from another sensor adds nothing. */
|
|
65058
|
+
var POWER_METER_CUSTOMIZE_DEVICE_TYPES = POWER_METER_DEVICE_TYPES.filter((type) => type !== DeviceType.Sensor);
|
|
65059
|
+
/** One scalar target per reading; each is sourced from a device of its own (D951). */
|
|
65060
|
+
function powerTarget(id, unit) {
|
|
65061
|
+
return {
|
|
65062
|
+
id,
|
|
65063
|
+
cardinality: "scalar",
|
|
65064
|
+
vocabulary: {
|
|
65065
|
+
cap: "power-meter",
|
|
65066
|
+
stateField: id
|
|
65067
|
+
},
|
|
65068
|
+
deviceTypes: POWER_METER_CUSTOMIZE_DEVICE_TYPES,
|
|
65069
|
+
apply: "add",
|
|
65070
|
+
path: id,
|
|
65071
|
+
sources: [{
|
|
65072
|
+
kind: "numeric",
|
|
65073
|
+
requiredUnit: unit,
|
|
65074
|
+
transforms: [{ kind: "identity" }]
|
|
65075
|
+
}],
|
|
65076
|
+
companions: [{
|
|
65077
|
+
kind: "clock",
|
|
65078
|
+
path: "lastFetchedAt",
|
|
65079
|
+
when: "always"
|
|
65080
|
+
}],
|
|
65081
|
+
sourceReport: { status: "assignment-status" },
|
|
65082
|
+
advancedExpression: true
|
|
65083
|
+
};
|
|
65084
|
+
}
|
|
65085
|
+
/** "Power and energy" extension: watts, energy, voltage and current from other devices (D951). */
|
|
65086
|
+
var powerMeterCustomize = {
|
|
65087
|
+
version: 1,
|
|
65088
|
+
targets: [
|
|
65089
|
+
powerTarget("watts", "W"),
|
|
65090
|
+
powerTarget("kwhTotal", "kWh"),
|
|
65091
|
+
powerTarget("volts", "V"),
|
|
65092
|
+
powerTarget("amps", "A")
|
|
65093
|
+
]
|
|
65094
|
+
};
|
|
64576
65095
|
var powerMeterCapability = {
|
|
64577
65096
|
name: "power-meter",
|
|
64578
65097
|
scope: "device",
|
|
64579
65098
|
deviceNative: true,
|
|
64580
65099
|
mode: "singleton",
|
|
64581
|
-
deviceTypes:
|
|
65100
|
+
deviceTypes: POWER_METER_DEVICE_TYPES,
|
|
64582
65101
|
methods: {},
|
|
64583
65102
|
status: {
|
|
64584
65103
|
schema: PowerMeterStatusSchema,
|
|
@@ -64635,7 +65154,8 @@ var powerMeterCapability = {
|
|
|
64635
65154
|
} },
|
|
64636
65155
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64637
65156
|
* whether persisting is worth a SQLite commit. */
|
|
64638
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
65157
|
+
volatileStateFields: ["lastFetchedAt"],
|
|
65158
|
+
customize: powerMeterCustomize
|
|
64639
65159
|
};
|
|
64640
65160
|
/**
|
|
64641
65161
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -65428,6 +65948,8 @@ var runningCustomize = {
|
|
|
65428
65948
|
stateField: "running"
|
|
65429
65949
|
},
|
|
65430
65950
|
deviceTypes: [
|
|
65951
|
+
DeviceType.Washer,
|
|
65952
|
+
DeviceType.Dryer,
|
|
65431
65953
|
DeviceType.Dishwasher,
|
|
65432
65954
|
DeviceType.Vacuum,
|
|
65433
65955
|
DeviceType.LawnMower,
|
|
@@ -68221,7 +68743,8 @@ var switchCapability = {
|
|
|
68221
68743
|
deviceTypes: [
|
|
68222
68744
|
DeviceType.Switch,
|
|
68223
68745
|
DeviceType.Siren,
|
|
68224
|
-
DeviceType.Light
|
|
68746
|
+
DeviceType.Light,
|
|
68747
|
+
DeviceType.Fan
|
|
68225
68748
|
],
|
|
68226
68749
|
methods: { setState: method(object({
|
|
68227
68750
|
deviceId: number(),
|
|
@@ -70567,8 +71090,9 @@ function withClipEventLabels(provider, deps) {
|
|
|
70567
71090
|
listClips
|
|
70568
71091
|
};
|
|
70569
71092
|
}
|
|
71093
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
70570
71094
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
70571
|
-
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;
|
|
71095
|
+
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;
|
|
70572
71096
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
70573
71097
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
70574
71098
|
new Set(CAP_NAMES);
|
|
@@ -70897,6 +71421,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70897
71421
|
featureProbe: featureProbeCapability,
|
|
70898
71422
|
flood: floodCapability,
|
|
70899
71423
|
gas: gasCapability,
|
|
71424
|
+
groupActive: groupActiveCapability,
|
|
70900
71425
|
groupCommands: groupCommandsCapability,
|
|
70901
71426
|
groupStatus: groupStatusCapability,
|
|
70902
71427
|
heatingValve: heatingValveCapability,
|
|
@@ -70908,6 +71433,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70908
71433
|
lawnMowerControl: lawnMowerControlCapability,
|
|
70909
71434
|
lockControl: lockControlCapability,
|
|
70910
71435
|
mediaPlayer: mediaPlayerCapability,
|
|
71436
|
+
meter: meterCapability,
|
|
70911
71437
|
motion: motionCapability,
|
|
70912
71438
|
motionTrigger: motionTriggerCapability,
|
|
70913
71439
|
motionZones: motionZonesCapability,
|
|
@@ -72171,7 +72697,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
72171
72697
|
function widenDeviceConstructor(ctor) {
|
|
72172
72698
|
return ctor;
|
|
72173
72699
|
}
|
|
72174
|
-
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;
|
|
72700
|
+
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;
|
|
72175
72701
|
new Set(Object.values(DeviceType));
|
|
72176
72702
|
Object.freeze({
|
|
72177
72703
|
"accessories.getStatus": {
|
|
@@ -75394,6 +75920,13 @@ Object.freeze({
|
|
|
75394
75920
|
access: "view",
|
|
75395
75921
|
role: "viewer"
|
|
75396
75922
|
},
|
|
75923
|
+
"groupActive.getStatus": {
|
|
75924
|
+
capName: "group-active",
|
|
75925
|
+
capScope: "device",
|
|
75926
|
+
addonId: null,
|
|
75927
|
+
access: "view",
|
|
75928
|
+
role: "viewer"
|
|
75929
|
+
},
|
|
75397
75930
|
"groupCommands.getStatus": {
|
|
75398
75931
|
capName: "group-commands",
|
|
75399
75932
|
capScope: "device",
|
|
@@ -76360,6 +76893,13 @@ Object.freeze({
|
|
|
76360
76893
|
access: "create",
|
|
76361
76894
|
role: "admin"
|
|
76362
76895
|
},
|
|
76896
|
+
"meter.getStatus": {
|
|
76897
|
+
capName: "meter",
|
|
76898
|
+
capScope: "device",
|
|
76899
|
+
addonId: null,
|
|
76900
|
+
access: "view",
|
|
76901
|
+
role: "viewer"
|
|
76902
|
+
},
|
|
76363
76903
|
"metricsProvider.collectSnapshot": {
|
|
76364
76904
|
capName: "metrics-provider",
|
|
76365
76905
|
capScope: "system",
|
|
@@ -84458,7 +84998,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84458
84998
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
84459
84999
|
icon: "square"
|
|
84460
85000
|
}
|
|
84461
|
-
}
|
|
85001
|
+
},
|
|
85002
|
+
overrides: { byType: {
|
|
85003
|
+
[DeviceType.Washer]: {
|
|
85004
|
+
state: { running: {
|
|
85005
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
85006
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
85007
|
+
} },
|
|
85008
|
+
events: {
|
|
85009
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
85010
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
85011
|
+
}
|
|
85012
|
+
},
|
|
85013
|
+
[DeviceType.Dryer]: {
|
|
85014
|
+
state: { running: {
|
|
85015
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
85016
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
85017
|
+
} },
|
|
85018
|
+
events: {
|
|
85019
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
85020
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
85021
|
+
}
|
|
85022
|
+
},
|
|
85023
|
+
[DeviceType.Dishwasher]: {
|
|
85024
|
+
state: { running: {
|
|
85025
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
85026
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
85027
|
+
} },
|
|
85028
|
+
events: {
|
|
85029
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
85030
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
85031
|
+
}
|
|
85032
|
+
}
|
|
85033
|
+
} }
|
|
84462
85034
|
},
|
|
84463
85035
|
update: {
|
|
84464
85036
|
scope: "device",
|
|
@@ -85230,6 +85802,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85230
85802
|
icon: "flame"
|
|
85231
85803
|
}]
|
|
85232
85804
|
},
|
|
85805
|
+
"group-active": {
|
|
85806
|
+
scope: "device",
|
|
85807
|
+
noun: t("Group state", "Stato del gruppo")
|
|
85808
|
+
},
|
|
85233
85809
|
"group-commands": {
|
|
85234
85810
|
scope: "device",
|
|
85235
85811
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -85286,6 +85862,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85286
85862
|
}],
|
|
85287
85863
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
85288
85864
|
},
|
|
85865
|
+
meter: {
|
|
85866
|
+
scope: "device",
|
|
85867
|
+
noun: t("Meter", "Contatore"),
|
|
85868
|
+
state: [{
|
|
85869
|
+
kind: "numeric",
|
|
85870
|
+
field: "value",
|
|
85871
|
+
quantity: t("the total", "il totale"),
|
|
85872
|
+
label: t("Total", "Totale"),
|
|
85873
|
+
icon: "gauge"
|
|
85874
|
+
}]
|
|
85875
|
+
},
|
|
85289
85876
|
"numeric-sensor": {
|
|
85290
85877
|
scope: "device",
|
|
85291
85878
|
noun: t("Sensor", "Sensore"),
|
|
@@ -85758,8 +86345,47 @@ function projectAction(cap, action) {
|
|
|
85758
86345
|
};
|
|
85759
86346
|
}
|
|
85760
86347
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
85761
|
-
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;
|
|
86348
|
+
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;
|
|
85762
86349
|
DeviceFeature.BatteryOperated;
|
|
86350
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
86351
|
+
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.";
|
|
86352
|
+
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.";
|
|
86353
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
86354
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
86355
|
+
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.";
|
|
86356
|
+
function withheld(reason) {
|
|
86357
|
+
return {
|
|
86358
|
+
[DeviceType.Washer]: {
|
|
86359
|
+
exported: false,
|
|
86360
|
+
reason
|
|
86361
|
+
},
|
|
86362
|
+
[DeviceType.Dryer]: {
|
|
86363
|
+
exported: false,
|
|
86364
|
+
reason
|
|
86365
|
+
},
|
|
86366
|
+
[DeviceType.Dishwasher]: {
|
|
86367
|
+
exported: false,
|
|
86368
|
+
reason
|
|
86369
|
+
}
|
|
86370
|
+
};
|
|
86371
|
+
}
|
|
86372
|
+
function offered(received) {
|
|
86373
|
+
return {
|
|
86374
|
+
[DeviceType.Washer]: {
|
|
86375
|
+
exported: true,
|
|
86376
|
+
as: received
|
|
86377
|
+
},
|
|
86378
|
+
[DeviceType.Dryer]: {
|
|
86379
|
+
exported: true,
|
|
86380
|
+
as: received
|
|
86381
|
+
},
|
|
86382
|
+
[DeviceType.Dishwasher]: {
|
|
86383
|
+
exported: true,
|
|
86384
|
+
as: received
|
|
86385
|
+
}
|
|
86386
|
+
};
|
|
86387
|
+
}
|
|
86388
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
85763
86389
|
/** Reject after `ms`; always clears its own timer. */
|
|
85764
86390
|
async function withTimeout$1(promise, ms, label) {
|
|
85765
86391
|
let timer;
|
|
@@ -86932,6 +87558,11 @@ Object.freeze({
|
|
|
86932
87558
|
form: "single",
|
|
86933
87559
|
optional: false
|
|
86934
87560
|
}],
|
|
87561
|
+
"groupActive.getStatus": [{
|
|
87562
|
+
name: "deviceId",
|
|
87563
|
+
form: "single",
|
|
87564
|
+
optional: false
|
|
87565
|
+
}],
|
|
86935
87566
|
"groupCommands.getStatus": [{
|
|
86936
87567
|
name: "deviceId",
|
|
86937
87568
|
form: "single",
|
|
@@ -87142,6 +87773,11 @@ Object.freeze({
|
|
|
87142
87773
|
form: "single",
|
|
87143
87774
|
optional: false
|
|
87144
87775
|
}],
|
|
87776
|
+
"meter.getStatus": [{
|
|
87777
|
+
name: "deviceId",
|
|
87778
|
+
form: "single",
|
|
87779
|
+
optional: false
|
|
87780
|
+
}],
|
|
87145
87781
|
"motion.getStatus": [{
|
|
87146
87782
|
name: "deviceId",
|
|
87147
87783
|
form: "single",
|
|
@@ -88749,7 +89385,6 @@ Object.freeze({
|
|
|
88749
89385
|
"network-access": "ingress",
|
|
88750
89386
|
"smtp-provider": "email"
|
|
88751
89387
|
});
|
|
88752
|
-
DeviceType.Camera;
|
|
88753
89388
|
/**
|
|
88754
89389
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
88755
89390
|
* `z.infer`, they do not restate the shape.
|