@camstack/addon-provider-reolink 1.2.211 → 1.2.212
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 +47 -10
- package/dist/addon.js +680 -45
- package/dist/addon.mjs +680 -45
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -5479,7 +5479,7 @@ var ZodIssueCode = {
|
|
|
5479
5479
|
var ZodFirstPartyTypeKind;
|
|
5480
5480
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5481
5481
|
//#endregion
|
|
5482
|
-
//#region ../types/dist/sleep
|
|
5482
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5483
5483
|
/**
|
|
5484
5484
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5485
5485
|
* window to float samples (D455).
|
|
@@ -8710,6 +8710,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8710
8710
|
"filesystem-browse",
|
|
8711
8711
|
"flood",
|
|
8712
8712
|
"gas",
|
|
8713
|
+
"group-active",
|
|
8713
8714
|
"group-commands",
|
|
8714
8715
|
"group-status",
|
|
8715
8716
|
"heating-valve",
|
|
@@ -8732,6 +8733,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8732
8733
|
"login-method",
|
|
8733
8734
|
"media-player",
|
|
8734
8735
|
"mesh-network",
|
|
8736
|
+
"meter",
|
|
8735
8737
|
"metrics-provider",
|
|
8736
8738
|
"model-convert",
|
|
8737
8739
|
"model-distributor",
|
|
@@ -9530,6 +9532,10 @@ Object.freeze({
|
|
|
9530
9532
|
"path": "detected",
|
|
9531
9533
|
"valueType": "boolean"
|
|
9532
9534
|
}],
|
|
9535
|
+
"group-active": [{
|
|
9536
|
+
"path": "active",
|
|
9537
|
+
"valueType": "boolean"
|
|
9538
|
+
}],
|
|
9533
9539
|
"group-status": [
|
|
9534
9540
|
{
|
|
9535
9541
|
"path": "included",
|
|
@@ -9789,6 +9795,10 @@ Object.freeze({
|
|
|
9789
9795
|
]
|
|
9790
9796
|
}
|
|
9791
9797
|
],
|
|
9798
|
+
"meter": [{
|
|
9799
|
+
"path": "value",
|
|
9800
|
+
"valueType": "number"
|
|
9801
|
+
}],
|
|
9792
9802
|
"motion": [
|
|
9793
9803
|
{
|
|
9794
9804
|
"path": "detected",
|
|
@@ -10570,7 +10580,7 @@ function sleep$2(ms) {
|
|
|
10570
10580
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
10571
10581
|
}
|
|
10572
10582
|
//#endregion
|
|
10573
|
-
//#region ../types/dist/err-msg-
|
|
10583
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
10574
10584
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
10575
10585
|
DeviceType["Camera"] = "camera";
|
|
10576
10586
|
DeviceType["Hub"] = "hub";
|
|
@@ -10664,8 +10674,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
10664
10674
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
10665
10675
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
10666
10676
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
10667
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10677
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10678
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
10668
10679
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
10680
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
10681
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
10682
|
+
DeviceType["Washer"] = "washer";
|
|
10683
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
10684
|
+
DeviceType["Dryer"] = "dryer";
|
|
10669
10685
|
return DeviceType;
|
|
10670
10686
|
}({});
|
|
10671
10687
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -10913,7 +10929,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10913
10929
|
return DeviceRole;
|
|
10914
10930
|
}({});
|
|
10915
10931
|
//#endregion
|
|
10916
|
-
//#region ../types/dist/composition-
|
|
10932
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
10917
10933
|
/**
|
|
10918
10934
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10919
10935
|
*
|
|
@@ -11228,6 +11244,13 @@ var table$1 = {
|
|
|
11228
11244
|
apply: () => {
|
|
11229
11245
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11230
11246
|
}
|
|
11247
|
+
},
|
|
11248
|
+
schmitt: {
|
|
11249
|
+
minArgs: 3,
|
|
11250
|
+
maxArgs: 5,
|
|
11251
|
+
apply: () => {
|
|
11252
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11253
|
+
}
|
|
11231
11254
|
}
|
|
11232
11255
|
};
|
|
11233
11256
|
Object.freeze(Object.assign(Object.create(null), table$1));
|
|
@@ -11669,6 +11692,99 @@ function validateExpressionSource(src) {
|
|
|
11669
11692
|
return null;
|
|
11670
11693
|
}
|
|
11671
11694
|
/**
|
|
11695
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
11696
|
+
*
|
|
11697
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
11698
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
11699
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
11700
|
+
*
|
|
11701
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
11702
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
11703
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
11704
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
11705
|
+
* can move later without moving the others.
|
|
11706
|
+
*/
|
|
11707
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
11708
|
+
var APPLIANCE_KINDS = [
|
|
11709
|
+
"washer",
|
|
11710
|
+
"dryer",
|
|
11711
|
+
"dishwasher"
|
|
11712
|
+
];
|
|
11713
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11714
|
+
/**
|
|
11715
|
+
* Statistics and integrals over a history read (D944).
|
|
11716
|
+
*
|
|
11717
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11718
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11719
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11720
|
+
* as zero. A truncated read is not published.
|
|
11721
|
+
*/
|
|
11722
|
+
var STATISTIC_STATS = [
|
|
11723
|
+
"min",
|
|
11724
|
+
"max",
|
|
11725
|
+
"mean",
|
|
11726
|
+
"sum",
|
|
11727
|
+
"count",
|
|
11728
|
+
"change"
|
|
11729
|
+
];
|
|
11730
|
+
/**
|
|
11731
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11732
|
+
*
|
|
11733
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11734
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11735
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11736
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11737
|
+
*/
|
|
11738
|
+
var MINUTE_MS = 6e4;
|
|
11739
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11740
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11741
|
+
var ROLLING_SPANS = [
|
|
11742
|
+
"1h",
|
|
11743
|
+
"24h",
|
|
11744
|
+
"2d",
|
|
11745
|
+
"7d",
|
|
11746
|
+
"30d",
|
|
11747
|
+
"custom"
|
|
11748
|
+
];
|
|
11749
|
+
var CALENDAR_PERIODS = [
|
|
11750
|
+
"today",
|
|
11751
|
+
"yesterday",
|
|
11752
|
+
"this-week",
|
|
11753
|
+
"this-month"
|
|
11754
|
+
];
|
|
11755
|
+
var RESET_PERIODS = [
|
|
11756
|
+
"never",
|
|
11757
|
+
"daily",
|
|
11758
|
+
"weekly",
|
|
11759
|
+
"monthly"
|
|
11760
|
+
];
|
|
11761
|
+
5 * MINUTE_MS;
|
|
11762
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11763
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11764
|
+
var rollingWindowObject = object({
|
|
11765
|
+
kind: literal("rolling"),
|
|
11766
|
+
span: _enum(ROLLING_SPANS),
|
|
11767
|
+
customMinutes: number().int().min(5).optional()
|
|
11768
|
+
}).check((payload) => {
|
|
11769
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11770
|
+
code: "custom",
|
|
11771
|
+
message: "a custom range needs a duration in minutes",
|
|
11772
|
+
path: ["customMinutes"],
|
|
11773
|
+
input: payload.value
|
|
11774
|
+
});
|
|
11775
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11776
|
+
code: "custom",
|
|
11777
|
+
message: "only a custom range carries a duration",
|
|
11778
|
+
path: ["customMinutes"],
|
|
11779
|
+
input: payload.value
|
|
11780
|
+
});
|
|
11781
|
+
});
|
|
11782
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
11783
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
11784
|
+
kind: literal("calendar"),
|
|
11785
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11786
|
+
})]);
|
|
11787
|
+
/**
|
|
11672
11788
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11673
11789
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11674
11790
|
* `composition.ts` (D659).
|
|
@@ -11694,7 +11810,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11694
11810
|
"occupancy",
|
|
11695
11811
|
"binary",
|
|
11696
11812
|
"switch",
|
|
11697
|
-
"light"
|
|
11813
|
+
"light",
|
|
11814
|
+
"fan",
|
|
11815
|
+
"cover",
|
|
11816
|
+
"valve",
|
|
11817
|
+
"lock",
|
|
11818
|
+
"media-player",
|
|
11819
|
+
"climate"
|
|
11698
11820
|
];
|
|
11699
11821
|
var NUMERIC_AGGREGATES = [
|
|
11700
11822
|
"mean",
|
|
@@ -11724,14 +11846,73 @@ var HelperMemberSchema = object({
|
|
|
11724
11846
|
cap: string().min(1),
|
|
11725
11847
|
fieldPath: string().min(1)
|
|
11726
11848
|
});
|
|
11727
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11728
|
-
|
|
11729
|
-
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11849
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11850
|
+
object({
|
|
11851
|
+
kind: literal("group"),
|
|
11852
|
+
templateId: GroupTemplateIdSchema,
|
|
11853
|
+
aggregate: AggregateReducerSchema,
|
|
11854
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11855
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11856
|
+
active: ActiveCriterionSchema.optional()
|
|
11857
|
+
}),
|
|
11858
|
+
object({
|
|
11859
|
+
kind: literal("appliance"),
|
|
11860
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
11861
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
11862
|
+
thresholdWatts: number().positive(),
|
|
11863
|
+
startDwellMs: number().int().nonnegative(),
|
|
11864
|
+
stopDwellMs: number().int().nonnegative(),
|
|
11865
|
+
member: HelperMemberSchema
|
|
11866
|
+
}),
|
|
11867
|
+
object({
|
|
11868
|
+
kind: literal("statistic"),
|
|
11869
|
+
stat: _enum(STATISTIC_STATS),
|
|
11870
|
+
window: StatisticWindowSchema,
|
|
11871
|
+
source: HelperMemberSchema
|
|
11872
|
+
}),
|
|
11873
|
+
object({
|
|
11874
|
+
kind: literal("integral"),
|
|
11875
|
+
reset: _enum(RESET_PERIODS),
|
|
11876
|
+
output: _enum(["energy", "meter"]),
|
|
11877
|
+
source: HelperMemberSchema
|
|
11878
|
+
}),
|
|
11879
|
+
object({
|
|
11880
|
+
kind: literal("threshold"),
|
|
11881
|
+
source: HelperMemberSchema,
|
|
11882
|
+
high: number(),
|
|
11883
|
+
low: number(),
|
|
11884
|
+
onForMs: number().int().nonnegative(),
|
|
11885
|
+
offForMs: number().int().nonnegative()
|
|
11886
|
+
}),
|
|
11887
|
+
object({
|
|
11888
|
+
kind: literal("arithmetic"),
|
|
11889
|
+
op: _enum([
|
|
11890
|
+
"sum",
|
|
11891
|
+
"difference",
|
|
11892
|
+
"ratio"
|
|
11893
|
+
]),
|
|
11894
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
11895
|
+
}),
|
|
11896
|
+
object({
|
|
11897
|
+
kind: literal("expression"),
|
|
11898
|
+
expr: string().min(1),
|
|
11899
|
+
inputs: array(object({
|
|
11900
|
+
name: string().min(1),
|
|
11901
|
+
member: HelperMemberSchema
|
|
11902
|
+
})).min(1).max(64),
|
|
11903
|
+
output: _enum(["number", "boolean"])
|
|
11904
|
+
}),
|
|
11905
|
+
object({
|
|
11906
|
+
kind: literal("derivative"),
|
|
11907
|
+
window: RollingWindowSchema,
|
|
11908
|
+
per: _enum([
|
|
11909
|
+
"second",
|
|
11910
|
+
"minute",
|
|
11911
|
+
"hour"
|
|
11912
|
+
]),
|
|
11913
|
+
source: HelperMemberSchema
|
|
11914
|
+
})
|
|
11915
|
+
]);
|
|
11735
11916
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11736
11917
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11737
11918
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -11792,6 +11973,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11792
11973
|
"all"
|
|
11793
11974
|
]),
|
|
11794
11975
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11976
|
+
/**
|
|
11977
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
11978
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
11979
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
11980
|
+
*/
|
|
11981
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
11795
11982
|
/** `value` is the reading; the others are the member counts. */
|
|
11796
11983
|
publish: _enum([
|
|
11797
11984
|
"value",
|
|
@@ -11805,6 +11992,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11805
11992
|
"omit",
|
|
11806
11993
|
"offline"
|
|
11807
11994
|
])
|
|
11995
|
+
}),
|
|
11996
|
+
object({
|
|
11997
|
+
kind: literal("series"),
|
|
11998
|
+
read: CompositionFieldReadSchema,
|
|
11999
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
12000
|
+
publish: _enum([
|
|
12001
|
+
"value",
|
|
12002
|
+
"included",
|
|
12003
|
+
"excluded",
|
|
12004
|
+
"total"
|
|
12005
|
+
]),
|
|
12006
|
+
/**
|
|
12007
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12008
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12009
|
+
*/
|
|
12010
|
+
empty: _enum([
|
|
12011
|
+
"null",
|
|
12012
|
+
"omit",
|
|
12013
|
+
"offline"
|
|
12014
|
+
])
|
|
11808
12015
|
})
|
|
11809
12016
|
]);
|
|
11810
12017
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -17534,7 +17741,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
17534
17741
|
*/
|
|
17535
17742
|
interactiveConnectPath: string().min(1).optional(),
|
|
17536
17743
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
17537
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
17744
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
17745
|
+
/**
|
|
17746
|
+
* The kind signs in through a server-held interactive session instead of
|
|
17747
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
17748
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
17749
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
17750
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
17751
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
17752
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
17753
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
17754
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
17755
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
17756
|
+
* offers it as the default path; the fields the session fills are
|
|
17757
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
17758
|
+
*/
|
|
17759
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
17538
17760
|
}))
|
|
17539
17761
|
});
|
|
17540
17762
|
var ListInputSchema = object({
|
|
@@ -18639,7 +18861,8 @@ var CompositionProblemSchema = object({
|
|
|
18639
18861
|
"native-capability-replace",
|
|
18640
18862
|
"mixed-quantity",
|
|
18641
18863
|
"helper-mismatch",
|
|
18642
|
-
"member-constraint"
|
|
18864
|
+
"member-constraint",
|
|
18865
|
+
"retention"
|
|
18643
18866
|
]),
|
|
18644
18867
|
path: string(),
|
|
18645
18868
|
message: string()
|
|
@@ -18873,13 +19096,17 @@ Object.freeze({
|
|
|
18873
19096
|
latchedAt: {
|
|
18874
19097
|
kind: "fixed",
|
|
18875
19098
|
result: ["number", "null"]
|
|
19099
|
+
},
|
|
19100
|
+
schmitt: {
|
|
19101
|
+
kind: "fixed",
|
|
19102
|
+
result: ["boolean", "null"]
|
|
18876
19103
|
}
|
|
18877
19104
|
});
|
|
18878
19105
|
/**
|
|
18879
19106
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18880
19107
|
* Data, not a form default written into the block.
|
|
18881
19108
|
*/
|
|
18882
|
-
var NOW = {
|
|
19109
|
+
var NOW$2 = {
|
|
18883
19110
|
fieldPath: "lastFetchedAt",
|
|
18884
19111
|
expr: "now"
|
|
18885
19112
|
};
|
|
@@ -18893,6 +19120,8 @@ function numeric(input) {
|
|
|
18893
19120
|
family: "numeric",
|
|
18894
19121
|
deviceType: DeviceType.Sensor,
|
|
18895
19122
|
memberDeviceType: DeviceType.Sensor,
|
|
19123
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
19124
|
+
activeWhen: void 0,
|
|
18896
19125
|
commandCaps: [],
|
|
18897
19126
|
baseUnit: baseUnitOf(input.quantity),
|
|
18898
19127
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18908,6 +19137,8 @@ function binary(input) {
|
|
|
18908
19137
|
family: "binary",
|
|
18909
19138
|
deviceType: DeviceType.Sensor,
|
|
18910
19139
|
memberDeviceType: DeviceType.Sensor,
|
|
19140
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
19141
|
+
activeWhen: void 0,
|
|
18911
19142
|
commandCaps: [],
|
|
18912
19143
|
quantity: "none",
|
|
18913
19144
|
baseUnit: void 0,
|
|
@@ -18925,7 +19156,7 @@ var GROUP_TEMPLATES = [
|
|
|
18925
19156
|
quantity: "temperature",
|
|
18926
19157
|
defaultAggregate: "mean",
|
|
18927
19158
|
empty: "null",
|
|
18928
|
-
companions: [NOW]
|
|
19159
|
+
companions: [NOW$2]
|
|
18929
19160
|
}),
|
|
18930
19161
|
numeric({
|
|
18931
19162
|
id: "humidity",
|
|
@@ -18936,7 +19167,7 @@ var GROUP_TEMPLATES = [
|
|
|
18936
19167
|
quantity: "humidity",
|
|
18937
19168
|
defaultAggregate: "mean",
|
|
18938
19169
|
empty: "null",
|
|
18939
|
-
companions: [NOW]
|
|
19170
|
+
companions: [NOW$2]
|
|
18940
19171
|
}),
|
|
18941
19172
|
numeric({
|
|
18942
19173
|
id: "pressure",
|
|
@@ -18947,7 +19178,7 @@ var GROUP_TEMPLATES = [
|
|
|
18947
19178
|
quantity: "pressure",
|
|
18948
19179
|
defaultAggregate: "mean",
|
|
18949
19180
|
empty: "null",
|
|
18950
|
-
companions: [NOW]
|
|
19181
|
+
companions: [NOW$2]
|
|
18951
19182
|
}),
|
|
18952
19183
|
numeric({
|
|
18953
19184
|
id: "illuminance",
|
|
@@ -18958,7 +19189,7 @@ var GROUP_TEMPLATES = [
|
|
|
18958
19189
|
quantity: "illuminance",
|
|
18959
19190
|
defaultAggregate: "mean",
|
|
18960
19191
|
empty: "null",
|
|
18961
|
-
companions: [NOW]
|
|
19192
|
+
companions: [NOW$2]
|
|
18962
19193
|
}),
|
|
18963
19194
|
numeric({
|
|
18964
19195
|
id: "power",
|
|
@@ -18969,7 +19200,7 @@ var GROUP_TEMPLATES = [
|
|
|
18969
19200
|
quantity: "power",
|
|
18970
19201
|
defaultAggregate: "sum",
|
|
18971
19202
|
empty: "omit",
|
|
18972
|
-
companions: [NOW]
|
|
19203
|
+
companions: [NOW$2]
|
|
18973
19204
|
}),
|
|
18974
19205
|
numeric({
|
|
18975
19206
|
id: "energy",
|
|
@@ -18980,7 +19211,7 @@ var GROUP_TEMPLATES = [
|
|
|
18980
19211
|
quantity: "energy",
|
|
18981
19212
|
defaultAggregate: "sum",
|
|
18982
19213
|
empty: "omit",
|
|
18983
|
-
companions: [NOW]
|
|
19214
|
+
companions: [NOW$2]
|
|
18984
19215
|
}),
|
|
18985
19216
|
numeric({
|
|
18986
19217
|
id: "battery",
|
|
@@ -19015,7 +19246,7 @@ var GROUP_TEMPLATES = [
|
|
|
19015
19246
|
quantity: "device",
|
|
19016
19247
|
defaultAggregate: "mean",
|
|
19017
19248
|
empty: "null",
|
|
19018
|
-
companions: [NOW]
|
|
19249
|
+
companions: [NOW$2]
|
|
19019
19250
|
}),
|
|
19020
19251
|
binary({
|
|
19021
19252
|
id: "motion",
|
|
@@ -19109,6 +19340,11 @@ var GROUP_TEMPLATES = [
|
|
|
19109
19340
|
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.",
|
|
19110
19341
|
deviceType: DeviceType.Switch,
|
|
19111
19342
|
outputCap: "switch",
|
|
19343
|
+
outputField: "on",
|
|
19344
|
+
member: {
|
|
19345
|
+
cap: "switch",
|
|
19346
|
+
fieldPath: "on"
|
|
19347
|
+
},
|
|
19112
19348
|
commandCaps: ["switch"]
|
|
19113
19349
|
}),
|
|
19114
19350
|
actuator({
|
|
@@ -19116,34 +19352,136 @@ var GROUP_TEMPLATES = [
|
|
|
19116
19352
|
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.",
|
|
19117
19353
|
deviceType: DeviceType.Light,
|
|
19118
19354
|
outputCap: "switch",
|
|
19355
|
+
outputField: "on",
|
|
19356
|
+
member: {
|
|
19357
|
+
cap: "switch",
|
|
19358
|
+
fieldPath: "on"
|
|
19359
|
+
},
|
|
19119
19360
|
commandCaps: [
|
|
19120
19361
|
"switch",
|
|
19121
19362
|
"brightness",
|
|
19122
19363
|
"color"
|
|
19123
19364
|
]
|
|
19365
|
+
}),
|
|
19366
|
+
actuator({
|
|
19367
|
+
id: "fan",
|
|
19368
|
+
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.",
|
|
19369
|
+
deviceType: DeviceType.Fan,
|
|
19370
|
+
outputCap: "switch",
|
|
19371
|
+
outputField: "on",
|
|
19372
|
+
member: {
|
|
19373
|
+
cap: "switch",
|
|
19374
|
+
fieldPath: "on"
|
|
19375
|
+
},
|
|
19376
|
+
commandCaps: ["switch", "fan-control"]
|
|
19377
|
+
}),
|
|
19378
|
+
actuator({
|
|
19379
|
+
id: "cover",
|
|
19380
|
+
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.",
|
|
19381
|
+
deviceType: DeviceType.Cover,
|
|
19382
|
+
outputCap: "group-active",
|
|
19383
|
+
outputField: "active",
|
|
19384
|
+
member: {
|
|
19385
|
+
cap: "cover",
|
|
19386
|
+
fieldPath: "state"
|
|
19387
|
+
},
|
|
19388
|
+
activeWhen: [
|
|
19389
|
+
"open",
|
|
19390
|
+
"opening",
|
|
19391
|
+
"stopped"
|
|
19392
|
+
],
|
|
19393
|
+
commandCaps: ["cover"]
|
|
19394
|
+
}),
|
|
19395
|
+
actuator({
|
|
19396
|
+
id: "valve",
|
|
19397
|
+
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.",
|
|
19398
|
+
deviceType: DeviceType.Valve,
|
|
19399
|
+
outputCap: "group-active",
|
|
19400
|
+
outputField: "active",
|
|
19401
|
+
member: {
|
|
19402
|
+
cap: "valve",
|
|
19403
|
+
fieldPath: "state"
|
|
19404
|
+
},
|
|
19405
|
+
activeWhen: [
|
|
19406
|
+
"open",
|
|
19407
|
+
"opening",
|
|
19408
|
+
"stopped"
|
|
19409
|
+
],
|
|
19410
|
+
commandCaps: ["valve"]
|
|
19411
|
+
}),
|
|
19412
|
+
actuator({
|
|
19413
|
+
id: "lock",
|
|
19414
|
+
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.",
|
|
19415
|
+
deviceType: DeviceType.Lock,
|
|
19416
|
+
outputCap: "group-active",
|
|
19417
|
+
outputField: "active",
|
|
19418
|
+
member: {
|
|
19419
|
+
cap: "lock-control",
|
|
19420
|
+
fieldPath: "state"
|
|
19421
|
+
},
|
|
19422
|
+
activeWhen: ["locked"],
|
|
19423
|
+
commandCaps: ["lock-control"]
|
|
19424
|
+
}),
|
|
19425
|
+
actuator({
|
|
19426
|
+
id: "media-player",
|
|
19427
|
+
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.",
|
|
19428
|
+
deviceType: DeviceType.MediaPlayer,
|
|
19429
|
+
outputCap: "group-active",
|
|
19430
|
+
outputField: "active",
|
|
19431
|
+
member: {
|
|
19432
|
+
cap: "media-player",
|
|
19433
|
+
fieldPath: "state"
|
|
19434
|
+
},
|
|
19435
|
+
activeWhen: ["playing", "buffering"],
|
|
19436
|
+
commandCaps: ["media-player"]
|
|
19437
|
+
}),
|
|
19438
|
+
actuator({
|
|
19439
|
+
id: "climate",
|
|
19440
|
+
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.",
|
|
19441
|
+
deviceType: DeviceType.Thermostat,
|
|
19442
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
19443
|
+
outputCap: "group-active",
|
|
19444
|
+
outputField: "active",
|
|
19445
|
+
member: {
|
|
19446
|
+
cap: "climate-control",
|
|
19447
|
+
fieldPath: "mode"
|
|
19448
|
+
},
|
|
19449
|
+
activeWhen: [
|
|
19450
|
+
"heat",
|
|
19451
|
+
"cool",
|
|
19452
|
+
"auto",
|
|
19453
|
+
"heat_cool",
|
|
19454
|
+
"fan_only",
|
|
19455
|
+
"dry"
|
|
19456
|
+
],
|
|
19457
|
+
commandCaps: ["climate-control"]
|
|
19124
19458
|
})
|
|
19125
19459
|
];
|
|
19126
19460
|
function actuator(input) {
|
|
19127
19461
|
return {
|
|
19128
|
-
|
|
19462
|
+
id: input.id,
|
|
19463
|
+
summary: input.summary,
|
|
19464
|
+
deviceType: input.deviceType,
|
|
19465
|
+
outputCap: input.outputCap,
|
|
19466
|
+
outputField: input.outputField,
|
|
19467
|
+
commandCaps: input.commandCaps,
|
|
19129
19468
|
family: "actuator",
|
|
19130
19469
|
role: void 0,
|
|
19131
19470
|
memberDeviceType: input.deviceType,
|
|
19132
|
-
|
|
19471
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
19472
|
+
activeWhen: input.activeWhen,
|
|
19133
19473
|
quantity: "none",
|
|
19134
19474
|
baseUnit: void 0,
|
|
19135
19475
|
aggregates: BINARY_AGGREGATES,
|
|
19136
19476
|
defaultAggregate: "any",
|
|
19137
19477
|
empty: "offline",
|
|
19138
|
-
accept: [
|
|
19139
|
-
cap: "switch",
|
|
19140
|
-
fieldPath: "on"
|
|
19141
|
-
}],
|
|
19478
|
+
accept: [input.member],
|
|
19142
19479
|
companions: [CHANGED]
|
|
19143
19480
|
};
|
|
19144
19481
|
}
|
|
19145
19482
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
19146
19483
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
19484
|
+
DeviceType.Camera;
|
|
19147
19485
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
19148
19486
|
/**
|
|
19149
19487
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -44503,7 +44841,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
44503
44841
|
});
|
|
44504
44842
|
/**
|
|
44505
44843
|
* Optional, richer endpoint shape returned by providers that expose
|
|
44506
|
-
* MORE than one ingress concurrently (Tailscale
|
|
44844
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
44507
44845
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
44508
44846
|
* the originating provider config (mode + sourcePort) so the
|
|
44509
44847
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -47190,7 +47528,20 @@ var NcRuleInputSchema = object({
|
|
|
47190
47528
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
47191
47529
|
* path does not run Zod defaults.
|
|
47192
47530
|
*/
|
|
47193
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
47531
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
47532
|
+
/**
|
|
47533
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
47534
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
47535
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
47536
|
+
* same mark the Library writes, and records whose notification it was and
|
|
47537
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
47538
|
+
*
|
|
47539
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
47540
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
47541
|
+
* authored before this field meant. An editor turns it off by writing
|
|
47542
|
+
* `false`, so it needs no `clear` key.
|
|
47543
|
+
*/
|
|
47544
|
+
askVerdict: boolean().optional()
|
|
47194
47545
|
});
|
|
47195
47546
|
/**
|
|
47196
47547
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -58432,7 +58783,8 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58432
58783
|
DeviceType.Switch,
|
|
58433
58784
|
DeviceType.PetFeeder,
|
|
58434
58785
|
DeviceType.Container,
|
|
58435
|
-
DeviceType.Thermostat
|
|
58786
|
+
DeviceType.Thermostat,
|
|
58787
|
+
DeviceType.EventEmitter
|
|
58436
58788
|
];
|
|
58437
58789
|
/** Generic Customize target for the percentage reading (D936). */
|
|
58438
58790
|
var batteryCustomize = {
|
|
@@ -61292,7 +61644,17 @@ var groupCommandsCapability = {
|
|
|
61292
61644
|
scope: "device",
|
|
61293
61645
|
deviceNative: true,
|
|
61294
61646
|
mode: "singleton",
|
|
61295
|
-
deviceTypes: [
|
|
61647
|
+
deviceTypes: [
|
|
61648
|
+
DeviceType.Switch,
|
|
61649
|
+
DeviceType.Light,
|
|
61650
|
+
DeviceType.Fan,
|
|
61651
|
+
DeviceType.Cover,
|
|
61652
|
+
DeviceType.Valve,
|
|
61653
|
+
DeviceType.Lock,
|
|
61654
|
+
DeviceType.MediaPlayer,
|
|
61655
|
+
DeviceType.Thermostat,
|
|
61656
|
+
DeviceType.Climate
|
|
61657
|
+
],
|
|
61296
61658
|
methods: {},
|
|
61297
61659
|
status: {
|
|
61298
61660
|
schema: GroupCommandsSchema,
|
|
@@ -61310,6 +61672,49 @@ var groupCommandsCapability = {
|
|
|
61310
61672
|
history: "none"
|
|
61311
61673
|
};
|
|
61312
61674
|
/**
|
|
61675
|
+
* Whether a helper actuator group counts as active (D944): at least one
|
|
61676
|
+
* included member is, or every included member is. What "active" means is the
|
|
61677
|
+
* type's: a cover is open, a lock is locked, a media player is playing, a
|
|
61678
|
+
* climate device is not off. A group of lights, switches and fans reports
|
|
61679
|
+
* `switch.on` instead; this cap is for the types whose own state is not a
|
|
61680
|
+
* yes/no. Unknown members are left out (`group-status` counts them) and an
|
|
61681
|
+
* empty included set takes the device offline, never `active: false`.
|
|
61682
|
+
*/
|
|
61683
|
+
var GroupActiveSchema = object({
|
|
61684
|
+
active: boolean().meta({ label: "Active" }),
|
|
61685
|
+
/** Ms epoch when the slice was last updated. */
|
|
61686
|
+
lastChangedAt: number()
|
|
61687
|
+
});
|
|
61688
|
+
var groupActiveCapability = {
|
|
61689
|
+
name: "group-active",
|
|
61690
|
+
scope: "device",
|
|
61691
|
+
deviceNative: true,
|
|
61692
|
+
mode: "singleton",
|
|
61693
|
+
deviceTypes: [
|
|
61694
|
+
DeviceType.Cover,
|
|
61695
|
+
DeviceType.Valve,
|
|
61696
|
+
DeviceType.Lock,
|
|
61697
|
+
DeviceType.MediaPlayer,
|
|
61698
|
+
DeviceType.Climate,
|
|
61699
|
+
DeviceType.Thermostat
|
|
61700
|
+
],
|
|
61701
|
+
methods: {},
|
|
61702
|
+
status: {
|
|
61703
|
+
schema: GroupActiveSchema,
|
|
61704
|
+
kind: "push"
|
|
61705
|
+
},
|
|
61706
|
+
runtimeState: GroupActiveSchema,
|
|
61707
|
+
/**
|
|
61708
|
+
* Runtime-state durability: **session** — recomputed from the members on the
|
|
61709
|
+
* next source event; a restored value would outlive the members it named.
|
|
61710
|
+
*
|
|
61711
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61712
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61713
|
+
*/
|
|
61714
|
+
durability: "session",
|
|
61715
|
+
history: "none"
|
|
61716
|
+
};
|
|
61717
|
+
/**
|
|
61313
61718
|
* How many members of a helper group answered (D944). Counts are integers,
|
|
61314
61719
|
* not measurements: zero included is a real count, never a stand-in reading.
|
|
61315
61720
|
* The reading itself stays on the output capability. History is none — the
|
|
@@ -61340,7 +61745,14 @@ var groupStatusCapability = {
|
|
|
61340
61745
|
deviceTypes: [
|
|
61341
61746
|
DeviceType.Sensor,
|
|
61342
61747
|
DeviceType.Switch,
|
|
61343
|
-
DeviceType.Light
|
|
61748
|
+
DeviceType.Light,
|
|
61749
|
+
DeviceType.Fan,
|
|
61750
|
+
DeviceType.Cover,
|
|
61751
|
+
DeviceType.Valve,
|
|
61752
|
+
DeviceType.Lock,
|
|
61753
|
+
DeviceType.MediaPlayer,
|
|
61754
|
+
DeviceType.Thermostat,
|
|
61755
|
+
DeviceType.Climate
|
|
61344
61756
|
],
|
|
61345
61757
|
methods: {},
|
|
61346
61758
|
status: {
|
|
@@ -62613,7 +63025,14 @@ var lockControlCapability = {
|
|
|
62613
63025
|
}),
|
|
62614
63026
|
unlock: method(object({
|
|
62615
63027
|
deviceId: number().int().nonnegative(),
|
|
62616
|
-
code: string().min(1).optional()
|
|
63028
|
+
code: string().min(1).optional(),
|
|
63029
|
+
/**
|
|
63030
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
63031
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
63032
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
63033
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
63034
|
+
*/
|
|
63035
|
+
confirm: boolean().optional()
|
|
62617
63036
|
}), _void(), {
|
|
62618
63037
|
kind: "mutation",
|
|
62619
63038
|
auth: "protected"
|
|
@@ -62650,6 +63069,44 @@ var lockControlCapability = {
|
|
|
62650
63069
|
volatileStateFields: ["lastChangedAt"]
|
|
62651
63070
|
};
|
|
62652
63071
|
/**
|
|
63072
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.kwhTotal`
|
|
63073
|
+
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
63074
|
+
* `value` is the time integral in the source quantity's accumulated base
|
|
63075
|
+
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
63076
|
+
*/
|
|
63077
|
+
var MeterStatusSchema = object({
|
|
63078
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
63079
|
+
lastFetchedAt: number()
|
|
63080
|
+
});
|
|
63081
|
+
var meterCapability = {
|
|
63082
|
+
name: "meter",
|
|
63083
|
+
scope: "device",
|
|
63084
|
+
deviceNative: true,
|
|
63085
|
+
mode: "singleton",
|
|
63086
|
+
deviceTypes: [DeviceType.Sensor],
|
|
63087
|
+
methods: {},
|
|
63088
|
+
status: {
|
|
63089
|
+
schema: MeterStatusSchema,
|
|
63090
|
+
kind: "push"
|
|
63091
|
+
},
|
|
63092
|
+
runtimeState: MeterStatusSchema,
|
|
63093
|
+
/**
|
|
63094
|
+
* Runtime-state durability: **restored** — the total is a cache of the
|
|
63095
|
+
* history integral. A restart shows it only until the history pass
|
|
63096
|
+
* recomputes the open period; it is not an in-memory buffer.
|
|
63097
|
+
*
|
|
63098
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
63099
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
63100
|
+
*/
|
|
63101
|
+
durability: "restored",
|
|
63102
|
+
history: { fields: { value: {
|
|
63103
|
+
kind: "counter",
|
|
63104
|
+
deadband: .001,
|
|
63105
|
+
minIntervalMs: 6e4
|
|
63106
|
+
} } },
|
|
63107
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63108
|
+
};
|
|
63109
|
+
/**
|
|
62653
63110
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
62654
63111
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
62655
63112
|
* `DeviceType.MediaPlayer`. Disjoint from the camera streaming
|
|
@@ -65227,9 +65684,9 @@ var PowerMeterStatusSchema = object({
|
|
|
65227
65684
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
65228
65685
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
65229
65686
|
/** Voltage in volts. */
|
|
65230
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
65687
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
65231
65688
|
/** Current in amperes. */
|
|
65232
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
65689
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
65233
65690
|
/** Apparent power in volt-amperes. */
|
|
65234
65691
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
65235
65692
|
/** Power factor (0..1) if reported. */
|
|
@@ -65237,12 +65694,74 @@ var PowerMeterStatusSchema = object({
|
|
|
65237
65694
|
/** Ms epoch when the slice was last updated. */
|
|
65238
65695
|
lastFetchedAt: number()
|
|
65239
65696
|
});
|
|
65697
|
+
/**
|
|
65698
|
+
* Loads that draw metered mains power (D951). The reading is a feature of the
|
|
65699
|
+
* device itself — a plug, a lamp, a fan, an air conditioner, a boiler, a
|
|
65700
|
+
* vacuum dock — not a separate sensor beside it. A `Sensor` stays: a clamp
|
|
65701
|
+
* meter or a standalone energy monitor IS the device. Cover, lock, valve,
|
|
65702
|
+
* camera and the like are left out: their draw is not what anyone meters.
|
|
65703
|
+
*/
|
|
65704
|
+
var POWER_METER_DEVICE_TYPES = [
|
|
65705
|
+
DeviceType.Sensor,
|
|
65706
|
+
DeviceType.Switch,
|
|
65707
|
+
DeviceType.Light,
|
|
65708
|
+
DeviceType.Fan,
|
|
65709
|
+
DeviceType.Climate,
|
|
65710
|
+
DeviceType.Thermostat,
|
|
65711
|
+
DeviceType.Humidifier,
|
|
65712
|
+
DeviceType.WaterHeater,
|
|
65713
|
+
DeviceType.MediaPlayer,
|
|
65714
|
+
DeviceType.Washer,
|
|
65715
|
+
DeviceType.Dryer,
|
|
65716
|
+
DeviceType.Dishwasher,
|
|
65717
|
+
DeviceType.Vacuum,
|
|
65718
|
+
DeviceType.LawnMower,
|
|
65719
|
+
DeviceType.PetFeeder
|
|
65720
|
+
];
|
|
65721
|
+
/** Everything but a bare `Sensor`: a sensor that takes its reading from another sensor adds nothing. */
|
|
65722
|
+
var POWER_METER_CUSTOMIZE_DEVICE_TYPES = POWER_METER_DEVICE_TYPES.filter((type) => type !== DeviceType.Sensor);
|
|
65723
|
+
/** One scalar target per reading; each is sourced from a device of its own (D951). */
|
|
65724
|
+
function powerTarget(id, unit) {
|
|
65725
|
+
return {
|
|
65726
|
+
id,
|
|
65727
|
+
cardinality: "scalar",
|
|
65728
|
+
vocabulary: {
|
|
65729
|
+
cap: "power-meter",
|
|
65730
|
+
stateField: id
|
|
65731
|
+
},
|
|
65732
|
+
deviceTypes: POWER_METER_CUSTOMIZE_DEVICE_TYPES,
|
|
65733
|
+
apply: "add",
|
|
65734
|
+
path: id,
|
|
65735
|
+
sources: [{
|
|
65736
|
+
kind: "numeric",
|
|
65737
|
+
requiredUnit: unit,
|
|
65738
|
+
transforms: [{ kind: "identity" }]
|
|
65739
|
+
}],
|
|
65740
|
+
companions: [{
|
|
65741
|
+
kind: "clock",
|
|
65742
|
+
path: "lastFetchedAt",
|
|
65743
|
+
when: "always"
|
|
65744
|
+
}],
|
|
65745
|
+
sourceReport: { status: "assignment-status" },
|
|
65746
|
+
advancedExpression: true
|
|
65747
|
+
};
|
|
65748
|
+
}
|
|
65749
|
+
/** "Power and energy" extension: watts, energy, voltage and current from other devices (D951). */
|
|
65750
|
+
var powerMeterCustomize = {
|
|
65751
|
+
version: 1,
|
|
65752
|
+
targets: [
|
|
65753
|
+
powerTarget("watts", "W"),
|
|
65754
|
+
powerTarget("kwhTotal", "kWh"),
|
|
65755
|
+
powerTarget("volts", "V"),
|
|
65756
|
+
powerTarget("amps", "A")
|
|
65757
|
+
]
|
|
65758
|
+
};
|
|
65240
65759
|
var powerMeterCapability = {
|
|
65241
65760
|
name: "power-meter",
|
|
65242
65761
|
scope: "device",
|
|
65243
65762
|
deviceNative: true,
|
|
65244
65763
|
mode: "singleton",
|
|
65245
|
-
deviceTypes:
|
|
65764
|
+
deviceTypes: POWER_METER_DEVICE_TYPES,
|
|
65246
65765
|
methods: {},
|
|
65247
65766
|
status: {
|
|
65248
65767
|
schema: PowerMeterStatusSchema,
|
|
@@ -65299,7 +65818,8 @@ var powerMeterCapability = {
|
|
|
65299
65818
|
} },
|
|
65300
65819
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65301
65820
|
* whether persisting is worth a SQLite commit. */
|
|
65302
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
65821
|
+
volatileStateFields: ["lastFetchedAt"],
|
|
65822
|
+
customize: powerMeterCustomize
|
|
65303
65823
|
};
|
|
65304
65824
|
/**
|
|
65305
65825
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -66092,6 +66612,8 @@ var runningCustomize = {
|
|
|
66092
66612
|
stateField: "running"
|
|
66093
66613
|
},
|
|
66094
66614
|
deviceTypes: [
|
|
66615
|
+
DeviceType.Washer,
|
|
66616
|
+
DeviceType.Dryer,
|
|
66095
66617
|
DeviceType.Dishwasher,
|
|
66096
66618
|
DeviceType.Vacuum,
|
|
66097
66619
|
DeviceType.LawnMower,
|
|
@@ -68973,7 +69495,8 @@ var switchCapability = {
|
|
|
68973
69495
|
deviceTypes: [
|
|
68974
69496
|
DeviceType.Switch,
|
|
68975
69497
|
DeviceType.Siren,
|
|
68976
|
-
DeviceType.Light
|
|
69498
|
+
DeviceType.Light,
|
|
69499
|
+
DeviceType.Fan
|
|
68977
69500
|
],
|
|
68978
69501
|
methods: { setState: method(object({
|
|
68979
69502
|
deviceId: number(),
|
|
@@ -71319,8 +71842,9 @@ function withClipEventLabels(provider, deps) {
|
|
|
71319
71842
|
listClips
|
|
71320
71843
|
};
|
|
71321
71844
|
}
|
|
71845
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
71322
71846
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
71323
|
-
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;
|
|
71847
|
+
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;
|
|
71324
71848
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
71325
71849
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
71326
71850
|
new Set(CAP_NAMES);
|
|
@@ -71664,6 +72188,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
71664
72188
|
featureProbe: featureProbeCapability,
|
|
71665
72189
|
flood: floodCapability,
|
|
71666
72190
|
gas: gasCapability,
|
|
72191
|
+
groupActive: groupActiveCapability,
|
|
71667
72192
|
groupCommands: groupCommandsCapability,
|
|
71668
72193
|
groupStatus: groupStatusCapability,
|
|
71669
72194
|
heatingValve: heatingValveCapability,
|
|
@@ -71675,6 +72200,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
71675
72200
|
lawnMowerControl: lawnMowerControlCapability,
|
|
71676
72201
|
lockControl: lockControlCapability,
|
|
71677
72202
|
mediaPlayer: mediaPlayerCapability,
|
|
72203
|
+
meter: meterCapability,
|
|
71678
72204
|
motion: motionCapability,
|
|
71679
72205
|
motionTrigger: motionTriggerCapability,
|
|
71680
72206
|
motionZones: motionZonesCapability,
|
|
@@ -72934,7 +73460,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
72934
73460
|
return toDeviceSummary(device, this.addonId);
|
|
72935
73461
|
}
|
|
72936
73462
|
};
|
|
72937
|
-
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;
|
|
73463
|
+
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;
|
|
72938
73464
|
new Set(Object.values(DeviceType));
|
|
72939
73465
|
Object.freeze({
|
|
72940
73466
|
"accessories.getStatus": {
|
|
@@ -76157,6 +76683,13 @@ Object.freeze({
|
|
|
76157
76683
|
access: "view",
|
|
76158
76684
|
role: "viewer"
|
|
76159
76685
|
},
|
|
76686
|
+
"groupActive.getStatus": {
|
|
76687
|
+
capName: "group-active",
|
|
76688
|
+
capScope: "device",
|
|
76689
|
+
addonId: null,
|
|
76690
|
+
access: "view",
|
|
76691
|
+
role: "viewer"
|
|
76692
|
+
},
|
|
76160
76693
|
"groupCommands.getStatus": {
|
|
76161
76694
|
capName: "group-commands",
|
|
76162
76695
|
capScope: "device",
|
|
@@ -77123,6 +77656,13 @@ Object.freeze({
|
|
|
77123
77656
|
access: "create",
|
|
77124
77657
|
role: "admin"
|
|
77125
77658
|
},
|
|
77659
|
+
"meter.getStatus": {
|
|
77660
|
+
capName: "meter",
|
|
77661
|
+
capScope: "device",
|
|
77662
|
+
addonId: null,
|
|
77663
|
+
access: "view",
|
|
77664
|
+
role: "viewer"
|
|
77665
|
+
},
|
|
77126
77666
|
"metricsProvider.collectSnapshot": {
|
|
77127
77667
|
capName: "metrics-provider",
|
|
77128
77668
|
capScope: "system",
|
|
@@ -85221,7 +85761,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
85221
85761
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
85222
85762
|
icon: "square"
|
|
85223
85763
|
}
|
|
85224
|
-
}
|
|
85764
|
+
},
|
|
85765
|
+
overrides: { byType: {
|
|
85766
|
+
[DeviceType.Washer]: {
|
|
85767
|
+
state: { running: {
|
|
85768
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
85769
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
85770
|
+
} },
|
|
85771
|
+
events: {
|
|
85772
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
85773
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
85774
|
+
}
|
|
85775
|
+
},
|
|
85776
|
+
[DeviceType.Dryer]: {
|
|
85777
|
+
state: { running: {
|
|
85778
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
85779
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
85780
|
+
} },
|
|
85781
|
+
events: {
|
|
85782
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
85783
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
85784
|
+
}
|
|
85785
|
+
},
|
|
85786
|
+
[DeviceType.Dishwasher]: {
|
|
85787
|
+
state: { running: {
|
|
85788
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
85789
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
85790
|
+
} },
|
|
85791
|
+
events: {
|
|
85792
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
85793
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
85794
|
+
}
|
|
85795
|
+
}
|
|
85796
|
+
} }
|
|
85225
85797
|
},
|
|
85226
85798
|
update: {
|
|
85227
85799
|
scope: "device",
|
|
@@ -85993,6 +86565,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85993
86565
|
icon: "flame"
|
|
85994
86566
|
}]
|
|
85995
86567
|
},
|
|
86568
|
+
"group-active": {
|
|
86569
|
+
scope: "device",
|
|
86570
|
+
noun: t("Group state", "Stato del gruppo")
|
|
86571
|
+
},
|
|
85996
86572
|
"group-commands": {
|
|
85997
86573
|
scope: "device",
|
|
85998
86574
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -86049,6 +86625,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86049
86625
|
}],
|
|
86050
86626
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
86051
86627
|
},
|
|
86628
|
+
meter: {
|
|
86629
|
+
scope: "device",
|
|
86630
|
+
noun: t("Meter", "Contatore"),
|
|
86631
|
+
state: [{
|
|
86632
|
+
kind: "numeric",
|
|
86633
|
+
field: "value",
|
|
86634
|
+
quantity: t("the total", "il totale"),
|
|
86635
|
+
label: t("Total", "Totale"),
|
|
86636
|
+
icon: "gauge"
|
|
86637
|
+
}]
|
|
86638
|
+
},
|
|
86052
86639
|
"numeric-sensor": {
|
|
86053
86640
|
scope: "device",
|
|
86054
86641
|
noun: t("Sensor", "Sensore"),
|
|
@@ -86521,8 +87108,47 @@ function projectAction(cap, action) {
|
|
|
86521
87108
|
};
|
|
86522
87109
|
}
|
|
86523
87110
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
86524
|
-
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;
|
|
87111
|
+
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;
|
|
86525
87112
|
DeviceFeature.BatteryOperated;
|
|
87113
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
87114
|
+
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.";
|
|
87115
|
+
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.";
|
|
87116
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
87117
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
87118
|
+
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.";
|
|
87119
|
+
function withheld(reason) {
|
|
87120
|
+
return {
|
|
87121
|
+
[DeviceType.Washer]: {
|
|
87122
|
+
exported: false,
|
|
87123
|
+
reason
|
|
87124
|
+
},
|
|
87125
|
+
[DeviceType.Dryer]: {
|
|
87126
|
+
exported: false,
|
|
87127
|
+
reason
|
|
87128
|
+
},
|
|
87129
|
+
[DeviceType.Dishwasher]: {
|
|
87130
|
+
exported: false,
|
|
87131
|
+
reason
|
|
87132
|
+
}
|
|
87133
|
+
};
|
|
87134
|
+
}
|
|
87135
|
+
function offered(received) {
|
|
87136
|
+
return {
|
|
87137
|
+
[DeviceType.Washer]: {
|
|
87138
|
+
exported: true,
|
|
87139
|
+
as: received
|
|
87140
|
+
},
|
|
87141
|
+
[DeviceType.Dryer]: {
|
|
87142
|
+
exported: true,
|
|
87143
|
+
as: received
|
|
87144
|
+
},
|
|
87145
|
+
[DeviceType.Dishwasher]: {
|
|
87146
|
+
exported: true,
|
|
87147
|
+
as: received
|
|
87148
|
+
}
|
|
87149
|
+
};
|
|
87150
|
+
}
|
|
87151
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
86526
87152
|
var LAST_FETCHED_FIELD = "lastFetchedAt";
|
|
86527
87153
|
/**
|
|
86528
87154
|
* How long a bridge stops re-attempting a refresh that did not land.
|
|
@@ -87641,6 +88267,11 @@ Object.freeze({
|
|
|
87641
88267
|
form: "single",
|
|
87642
88268
|
optional: false
|
|
87643
88269
|
}],
|
|
88270
|
+
"groupActive.getStatus": [{
|
|
88271
|
+
name: "deviceId",
|
|
88272
|
+
form: "single",
|
|
88273
|
+
optional: false
|
|
88274
|
+
}],
|
|
87644
88275
|
"groupCommands.getStatus": [{
|
|
87645
88276
|
name: "deviceId",
|
|
87646
88277
|
form: "single",
|
|
@@ -87851,6 +88482,11 @@ Object.freeze({
|
|
|
87851
88482
|
form: "single",
|
|
87852
88483
|
optional: false
|
|
87853
88484
|
}],
|
|
88485
|
+
"meter.getStatus": [{
|
|
88486
|
+
name: "deviceId",
|
|
88487
|
+
form: "single",
|
|
88488
|
+
optional: false
|
|
88489
|
+
}],
|
|
87854
88490
|
"motion.getStatus": [{
|
|
87855
88491
|
name: "deviceId",
|
|
87856
88492
|
form: "single",
|
|
@@ -89458,7 +90094,6 @@ Object.freeze({
|
|
|
89458
90094
|
"network-access": "ingress",
|
|
89459
90095
|
"smtp-provider": "email"
|
|
89460
90096
|
});
|
|
89461
|
-
DeviceType.Camera;
|
|
89462
90097
|
/**
|
|
89463
90098
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
89464
90099
|
* `z.infer`, they do not restate the shape.
|