@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.mjs
CHANGED
|
@@ -5471,7 +5471,7 @@ var ZodIssueCode = {
|
|
|
5471
5471
|
var ZodFirstPartyTypeKind;
|
|
5472
5472
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5473
5473
|
//#endregion
|
|
5474
|
-
//#region ../types/dist/sleep
|
|
5474
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5475
5475
|
/**
|
|
5476
5476
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5477
5477
|
* window to float samples (D455).
|
|
@@ -8702,6 +8702,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8702
8702
|
"filesystem-browse",
|
|
8703
8703
|
"flood",
|
|
8704
8704
|
"gas",
|
|
8705
|
+
"group-active",
|
|
8705
8706
|
"group-commands",
|
|
8706
8707
|
"group-status",
|
|
8707
8708
|
"heating-valve",
|
|
@@ -8724,6 +8725,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8724
8725
|
"login-method",
|
|
8725
8726
|
"media-player",
|
|
8726
8727
|
"mesh-network",
|
|
8728
|
+
"meter",
|
|
8727
8729
|
"metrics-provider",
|
|
8728
8730
|
"model-convert",
|
|
8729
8731
|
"model-distributor",
|
|
@@ -9522,6 +9524,10 @@ Object.freeze({
|
|
|
9522
9524
|
"path": "detected",
|
|
9523
9525
|
"valueType": "boolean"
|
|
9524
9526
|
}],
|
|
9527
|
+
"group-active": [{
|
|
9528
|
+
"path": "active",
|
|
9529
|
+
"valueType": "boolean"
|
|
9530
|
+
}],
|
|
9525
9531
|
"group-status": [
|
|
9526
9532
|
{
|
|
9527
9533
|
"path": "included",
|
|
@@ -9781,6 +9787,10 @@ Object.freeze({
|
|
|
9781
9787
|
]
|
|
9782
9788
|
}
|
|
9783
9789
|
],
|
|
9790
|
+
"meter": [{
|
|
9791
|
+
"path": "value",
|
|
9792
|
+
"valueType": "number"
|
|
9793
|
+
}],
|
|
9784
9794
|
"motion": [
|
|
9785
9795
|
{
|
|
9786
9796
|
"path": "detected",
|
|
@@ -10562,7 +10572,7 @@ function sleep$2(ms) {
|
|
|
10562
10572
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
10563
10573
|
}
|
|
10564
10574
|
//#endregion
|
|
10565
|
-
//#region ../types/dist/err-msg-
|
|
10575
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
10566
10576
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
10567
10577
|
DeviceType["Camera"] = "camera";
|
|
10568
10578
|
DeviceType["Hub"] = "hub";
|
|
@@ -10656,8 +10666,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
10656
10666
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
10657
10667
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
10658
10668
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
10659
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10669
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10670
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
10660
10671
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
10672
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
10673
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
10674
|
+
DeviceType["Washer"] = "washer";
|
|
10675
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
10676
|
+
DeviceType["Dryer"] = "dryer";
|
|
10661
10677
|
return DeviceType;
|
|
10662
10678
|
}({});
|
|
10663
10679
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -10905,7 +10921,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10905
10921
|
return DeviceRole;
|
|
10906
10922
|
}({});
|
|
10907
10923
|
//#endregion
|
|
10908
|
-
//#region ../types/dist/composition-
|
|
10924
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
10909
10925
|
/**
|
|
10910
10926
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10911
10927
|
*
|
|
@@ -11220,6 +11236,13 @@ var table$1 = {
|
|
|
11220
11236
|
apply: () => {
|
|
11221
11237
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11222
11238
|
}
|
|
11239
|
+
},
|
|
11240
|
+
schmitt: {
|
|
11241
|
+
minArgs: 3,
|
|
11242
|
+
maxArgs: 5,
|
|
11243
|
+
apply: () => {
|
|
11244
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11245
|
+
}
|
|
11223
11246
|
}
|
|
11224
11247
|
};
|
|
11225
11248
|
Object.freeze(Object.assign(Object.create(null), table$1));
|
|
@@ -11661,6 +11684,99 @@ function validateExpressionSource(src) {
|
|
|
11661
11684
|
return null;
|
|
11662
11685
|
}
|
|
11663
11686
|
/**
|
|
11687
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
11688
|
+
*
|
|
11689
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
11690
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
11691
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
11692
|
+
*
|
|
11693
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
11694
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
11695
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
11696
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
11697
|
+
* can move later without moving the others.
|
|
11698
|
+
*/
|
|
11699
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
11700
|
+
var APPLIANCE_KINDS = [
|
|
11701
|
+
"washer",
|
|
11702
|
+
"dryer",
|
|
11703
|
+
"dishwasher"
|
|
11704
|
+
];
|
|
11705
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11706
|
+
/**
|
|
11707
|
+
* Statistics and integrals over a history read (D944).
|
|
11708
|
+
*
|
|
11709
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11710
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11711
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11712
|
+
* as zero. A truncated read is not published.
|
|
11713
|
+
*/
|
|
11714
|
+
var STATISTIC_STATS = [
|
|
11715
|
+
"min",
|
|
11716
|
+
"max",
|
|
11717
|
+
"mean",
|
|
11718
|
+
"sum",
|
|
11719
|
+
"count",
|
|
11720
|
+
"change"
|
|
11721
|
+
];
|
|
11722
|
+
/**
|
|
11723
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11724
|
+
*
|
|
11725
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11726
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11727
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11728
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11729
|
+
*/
|
|
11730
|
+
var MINUTE_MS = 6e4;
|
|
11731
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11732
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11733
|
+
var ROLLING_SPANS = [
|
|
11734
|
+
"1h",
|
|
11735
|
+
"24h",
|
|
11736
|
+
"2d",
|
|
11737
|
+
"7d",
|
|
11738
|
+
"30d",
|
|
11739
|
+
"custom"
|
|
11740
|
+
];
|
|
11741
|
+
var CALENDAR_PERIODS = [
|
|
11742
|
+
"today",
|
|
11743
|
+
"yesterday",
|
|
11744
|
+
"this-week",
|
|
11745
|
+
"this-month"
|
|
11746
|
+
];
|
|
11747
|
+
var RESET_PERIODS = [
|
|
11748
|
+
"never",
|
|
11749
|
+
"daily",
|
|
11750
|
+
"weekly",
|
|
11751
|
+
"monthly"
|
|
11752
|
+
];
|
|
11753
|
+
5 * MINUTE_MS;
|
|
11754
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11755
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11756
|
+
var rollingWindowObject = object({
|
|
11757
|
+
kind: literal("rolling"),
|
|
11758
|
+
span: _enum(ROLLING_SPANS),
|
|
11759
|
+
customMinutes: number().int().min(5).optional()
|
|
11760
|
+
}).check((payload) => {
|
|
11761
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11762
|
+
code: "custom",
|
|
11763
|
+
message: "a custom range needs a duration in minutes",
|
|
11764
|
+
path: ["customMinutes"],
|
|
11765
|
+
input: payload.value
|
|
11766
|
+
});
|
|
11767
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11768
|
+
code: "custom",
|
|
11769
|
+
message: "only a custom range carries a duration",
|
|
11770
|
+
path: ["customMinutes"],
|
|
11771
|
+
input: payload.value
|
|
11772
|
+
});
|
|
11773
|
+
});
|
|
11774
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
11775
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
11776
|
+
kind: literal("calendar"),
|
|
11777
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11778
|
+
})]);
|
|
11779
|
+
/**
|
|
11664
11780
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11665
11781
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11666
11782
|
* `composition.ts` (D659).
|
|
@@ -11686,7 +11802,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11686
11802
|
"occupancy",
|
|
11687
11803
|
"binary",
|
|
11688
11804
|
"switch",
|
|
11689
|
-
"light"
|
|
11805
|
+
"light",
|
|
11806
|
+
"fan",
|
|
11807
|
+
"cover",
|
|
11808
|
+
"valve",
|
|
11809
|
+
"lock",
|
|
11810
|
+
"media-player",
|
|
11811
|
+
"climate"
|
|
11690
11812
|
];
|
|
11691
11813
|
var NUMERIC_AGGREGATES = [
|
|
11692
11814
|
"mean",
|
|
@@ -11716,14 +11838,73 @@ var HelperMemberSchema = object({
|
|
|
11716
11838
|
cap: string().min(1),
|
|
11717
11839
|
fieldPath: string().min(1)
|
|
11718
11840
|
});
|
|
11719
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11841
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11842
|
+
object({
|
|
11843
|
+
kind: literal("group"),
|
|
11844
|
+
templateId: GroupTemplateIdSchema,
|
|
11845
|
+
aggregate: AggregateReducerSchema,
|
|
11846
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11847
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11848
|
+
active: ActiveCriterionSchema.optional()
|
|
11849
|
+
}),
|
|
11850
|
+
object({
|
|
11851
|
+
kind: literal("appliance"),
|
|
11852
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
11853
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
11854
|
+
thresholdWatts: number().positive(),
|
|
11855
|
+
startDwellMs: number().int().nonnegative(),
|
|
11856
|
+
stopDwellMs: number().int().nonnegative(),
|
|
11857
|
+
member: HelperMemberSchema
|
|
11858
|
+
}),
|
|
11859
|
+
object({
|
|
11860
|
+
kind: literal("statistic"),
|
|
11861
|
+
stat: _enum(STATISTIC_STATS),
|
|
11862
|
+
window: StatisticWindowSchema,
|
|
11863
|
+
source: HelperMemberSchema
|
|
11864
|
+
}),
|
|
11865
|
+
object({
|
|
11866
|
+
kind: literal("integral"),
|
|
11867
|
+
reset: _enum(RESET_PERIODS),
|
|
11868
|
+
output: _enum(["energy", "meter"]),
|
|
11869
|
+
source: HelperMemberSchema
|
|
11870
|
+
}),
|
|
11871
|
+
object({
|
|
11872
|
+
kind: literal("threshold"),
|
|
11873
|
+
source: HelperMemberSchema,
|
|
11874
|
+
high: number(),
|
|
11875
|
+
low: number(),
|
|
11876
|
+
onForMs: number().int().nonnegative(),
|
|
11877
|
+
offForMs: number().int().nonnegative()
|
|
11878
|
+
}),
|
|
11879
|
+
object({
|
|
11880
|
+
kind: literal("arithmetic"),
|
|
11881
|
+
op: _enum([
|
|
11882
|
+
"sum",
|
|
11883
|
+
"difference",
|
|
11884
|
+
"ratio"
|
|
11885
|
+
]),
|
|
11886
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
11887
|
+
}),
|
|
11888
|
+
object({
|
|
11889
|
+
kind: literal("expression"),
|
|
11890
|
+
expr: string().min(1),
|
|
11891
|
+
inputs: array(object({
|
|
11892
|
+
name: string().min(1),
|
|
11893
|
+
member: HelperMemberSchema
|
|
11894
|
+
})).min(1).max(64),
|
|
11895
|
+
output: _enum(["number", "boolean"])
|
|
11896
|
+
}),
|
|
11897
|
+
object({
|
|
11898
|
+
kind: literal("derivative"),
|
|
11899
|
+
window: RollingWindowSchema,
|
|
11900
|
+
per: _enum([
|
|
11901
|
+
"second",
|
|
11902
|
+
"minute",
|
|
11903
|
+
"hour"
|
|
11904
|
+
]),
|
|
11905
|
+
source: HelperMemberSchema
|
|
11906
|
+
})
|
|
11907
|
+
]);
|
|
11727
11908
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11728
11909
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11729
11910
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -11784,6 +11965,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11784
11965
|
"all"
|
|
11785
11966
|
]),
|
|
11786
11967
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11968
|
+
/**
|
|
11969
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
11970
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
11971
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
11972
|
+
*/
|
|
11973
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
11787
11974
|
/** `value` is the reading; the others are the member counts. */
|
|
11788
11975
|
publish: _enum([
|
|
11789
11976
|
"value",
|
|
@@ -11797,6 +11984,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11797
11984
|
"omit",
|
|
11798
11985
|
"offline"
|
|
11799
11986
|
])
|
|
11987
|
+
}),
|
|
11988
|
+
object({
|
|
11989
|
+
kind: literal("series"),
|
|
11990
|
+
read: CompositionFieldReadSchema,
|
|
11991
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
11992
|
+
publish: _enum([
|
|
11993
|
+
"value",
|
|
11994
|
+
"included",
|
|
11995
|
+
"excluded",
|
|
11996
|
+
"total"
|
|
11997
|
+
]),
|
|
11998
|
+
/**
|
|
11999
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12000
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12001
|
+
*/
|
|
12002
|
+
empty: _enum([
|
|
12003
|
+
"null",
|
|
12004
|
+
"omit",
|
|
12005
|
+
"offline"
|
|
12006
|
+
])
|
|
11800
12007
|
})
|
|
11801
12008
|
]);
|
|
11802
12009
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -17526,7 +17733,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
17526
17733
|
*/
|
|
17527
17734
|
interactiveConnectPath: string().min(1).optional(),
|
|
17528
17735
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
17529
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
17736
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
17737
|
+
/**
|
|
17738
|
+
* The kind signs in through a server-held interactive session instead of
|
|
17739
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
17740
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
17741
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
17742
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
17743
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
17744
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
17745
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
17746
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
17747
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
17748
|
+
* offers it as the default path; the fields the session fills are
|
|
17749
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
17750
|
+
*/
|
|
17751
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
17530
17752
|
}))
|
|
17531
17753
|
});
|
|
17532
17754
|
var ListInputSchema = object({
|
|
@@ -18631,7 +18853,8 @@ var CompositionProblemSchema = object({
|
|
|
18631
18853
|
"native-capability-replace",
|
|
18632
18854
|
"mixed-quantity",
|
|
18633
18855
|
"helper-mismatch",
|
|
18634
|
-
"member-constraint"
|
|
18856
|
+
"member-constraint",
|
|
18857
|
+
"retention"
|
|
18635
18858
|
]),
|
|
18636
18859
|
path: string(),
|
|
18637
18860
|
message: string()
|
|
@@ -18865,13 +19088,17 @@ Object.freeze({
|
|
|
18865
19088
|
latchedAt: {
|
|
18866
19089
|
kind: "fixed",
|
|
18867
19090
|
result: ["number", "null"]
|
|
19091
|
+
},
|
|
19092
|
+
schmitt: {
|
|
19093
|
+
kind: "fixed",
|
|
19094
|
+
result: ["boolean", "null"]
|
|
18868
19095
|
}
|
|
18869
19096
|
});
|
|
18870
19097
|
/**
|
|
18871
19098
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18872
19099
|
* Data, not a form default written into the block.
|
|
18873
19100
|
*/
|
|
18874
|
-
var NOW = {
|
|
19101
|
+
var NOW$2 = {
|
|
18875
19102
|
fieldPath: "lastFetchedAt",
|
|
18876
19103
|
expr: "now"
|
|
18877
19104
|
};
|
|
@@ -18885,6 +19112,8 @@ function numeric(input) {
|
|
|
18885
19112
|
family: "numeric",
|
|
18886
19113
|
deviceType: DeviceType.Sensor,
|
|
18887
19114
|
memberDeviceType: DeviceType.Sensor,
|
|
19115
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
19116
|
+
activeWhen: void 0,
|
|
18888
19117
|
commandCaps: [],
|
|
18889
19118
|
baseUnit: baseUnitOf(input.quantity),
|
|
18890
19119
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18900,6 +19129,8 @@ function binary(input) {
|
|
|
18900
19129
|
family: "binary",
|
|
18901
19130
|
deviceType: DeviceType.Sensor,
|
|
18902
19131
|
memberDeviceType: DeviceType.Sensor,
|
|
19132
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
19133
|
+
activeWhen: void 0,
|
|
18903
19134
|
commandCaps: [],
|
|
18904
19135
|
quantity: "none",
|
|
18905
19136
|
baseUnit: void 0,
|
|
@@ -18917,7 +19148,7 @@ var GROUP_TEMPLATES = [
|
|
|
18917
19148
|
quantity: "temperature",
|
|
18918
19149
|
defaultAggregate: "mean",
|
|
18919
19150
|
empty: "null",
|
|
18920
|
-
companions: [NOW]
|
|
19151
|
+
companions: [NOW$2]
|
|
18921
19152
|
}),
|
|
18922
19153
|
numeric({
|
|
18923
19154
|
id: "humidity",
|
|
@@ -18928,7 +19159,7 @@ var GROUP_TEMPLATES = [
|
|
|
18928
19159
|
quantity: "humidity",
|
|
18929
19160
|
defaultAggregate: "mean",
|
|
18930
19161
|
empty: "null",
|
|
18931
|
-
companions: [NOW]
|
|
19162
|
+
companions: [NOW$2]
|
|
18932
19163
|
}),
|
|
18933
19164
|
numeric({
|
|
18934
19165
|
id: "pressure",
|
|
@@ -18939,7 +19170,7 @@ var GROUP_TEMPLATES = [
|
|
|
18939
19170
|
quantity: "pressure",
|
|
18940
19171
|
defaultAggregate: "mean",
|
|
18941
19172
|
empty: "null",
|
|
18942
|
-
companions: [NOW]
|
|
19173
|
+
companions: [NOW$2]
|
|
18943
19174
|
}),
|
|
18944
19175
|
numeric({
|
|
18945
19176
|
id: "illuminance",
|
|
@@ -18950,7 +19181,7 @@ var GROUP_TEMPLATES = [
|
|
|
18950
19181
|
quantity: "illuminance",
|
|
18951
19182
|
defaultAggregate: "mean",
|
|
18952
19183
|
empty: "null",
|
|
18953
|
-
companions: [NOW]
|
|
19184
|
+
companions: [NOW$2]
|
|
18954
19185
|
}),
|
|
18955
19186
|
numeric({
|
|
18956
19187
|
id: "power",
|
|
@@ -18961,7 +19192,7 @@ var GROUP_TEMPLATES = [
|
|
|
18961
19192
|
quantity: "power",
|
|
18962
19193
|
defaultAggregate: "sum",
|
|
18963
19194
|
empty: "omit",
|
|
18964
|
-
companions: [NOW]
|
|
19195
|
+
companions: [NOW$2]
|
|
18965
19196
|
}),
|
|
18966
19197
|
numeric({
|
|
18967
19198
|
id: "energy",
|
|
@@ -18972,7 +19203,7 @@ var GROUP_TEMPLATES = [
|
|
|
18972
19203
|
quantity: "energy",
|
|
18973
19204
|
defaultAggregate: "sum",
|
|
18974
19205
|
empty: "omit",
|
|
18975
|
-
companions: [NOW]
|
|
19206
|
+
companions: [NOW$2]
|
|
18976
19207
|
}),
|
|
18977
19208
|
numeric({
|
|
18978
19209
|
id: "battery",
|
|
@@ -19007,7 +19238,7 @@ var GROUP_TEMPLATES = [
|
|
|
19007
19238
|
quantity: "device",
|
|
19008
19239
|
defaultAggregate: "mean",
|
|
19009
19240
|
empty: "null",
|
|
19010
|
-
companions: [NOW]
|
|
19241
|
+
companions: [NOW$2]
|
|
19011
19242
|
}),
|
|
19012
19243
|
binary({
|
|
19013
19244
|
id: "motion",
|
|
@@ -19101,6 +19332,11 @@ var GROUP_TEMPLATES = [
|
|
|
19101
19332
|
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.",
|
|
19102
19333
|
deviceType: DeviceType.Switch,
|
|
19103
19334
|
outputCap: "switch",
|
|
19335
|
+
outputField: "on",
|
|
19336
|
+
member: {
|
|
19337
|
+
cap: "switch",
|
|
19338
|
+
fieldPath: "on"
|
|
19339
|
+
},
|
|
19104
19340
|
commandCaps: ["switch"]
|
|
19105
19341
|
}),
|
|
19106
19342
|
actuator({
|
|
@@ -19108,34 +19344,136 @@ var GROUP_TEMPLATES = [
|
|
|
19108
19344
|
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.",
|
|
19109
19345
|
deviceType: DeviceType.Light,
|
|
19110
19346
|
outputCap: "switch",
|
|
19347
|
+
outputField: "on",
|
|
19348
|
+
member: {
|
|
19349
|
+
cap: "switch",
|
|
19350
|
+
fieldPath: "on"
|
|
19351
|
+
},
|
|
19111
19352
|
commandCaps: [
|
|
19112
19353
|
"switch",
|
|
19113
19354
|
"brightness",
|
|
19114
19355
|
"color"
|
|
19115
19356
|
]
|
|
19357
|
+
}),
|
|
19358
|
+
actuator({
|
|
19359
|
+
id: "fan",
|
|
19360
|
+
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.",
|
|
19361
|
+
deviceType: DeviceType.Fan,
|
|
19362
|
+
outputCap: "switch",
|
|
19363
|
+
outputField: "on",
|
|
19364
|
+
member: {
|
|
19365
|
+
cap: "switch",
|
|
19366
|
+
fieldPath: "on"
|
|
19367
|
+
},
|
|
19368
|
+
commandCaps: ["switch", "fan-control"]
|
|
19369
|
+
}),
|
|
19370
|
+
actuator({
|
|
19371
|
+
id: "cover",
|
|
19372
|
+
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.",
|
|
19373
|
+
deviceType: DeviceType.Cover,
|
|
19374
|
+
outputCap: "group-active",
|
|
19375
|
+
outputField: "active",
|
|
19376
|
+
member: {
|
|
19377
|
+
cap: "cover",
|
|
19378
|
+
fieldPath: "state"
|
|
19379
|
+
},
|
|
19380
|
+
activeWhen: [
|
|
19381
|
+
"open",
|
|
19382
|
+
"opening",
|
|
19383
|
+
"stopped"
|
|
19384
|
+
],
|
|
19385
|
+
commandCaps: ["cover"]
|
|
19386
|
+
}),
|
|
19387
|
+
actuator({
|
|
19388
|
+
id: "valve",
|
|
19389
|
+
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.",
|
|
19390
|
+
deviceType: DeviceType.Valve,
|
|
19391
|
+
outputCap: "group-active",
|
|
19392
|
+
outputField: "active",
|
|
19393
|
+
member: {
|
|
19394
|
+
cap: "valve",
|
|
19395
|
+
fieldPath: "state"
|
|
19396
|
+
},
|
|
19397
|
+
activeWhen: [
|
|
19398
|
+
"open",
|
|
19399
|
+
"opening",
|
|
19400
|
+
"stopped"
|
|
19401
|
+
],
|
|
19402
|
+
commandCaps: ["valve"]
|
|
19403
|
+
}),
|
|
19404
|
+
actuator({
|
|
19405
|
+
id: "lock",
|
|
19406
|
+
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.",
|
|
19407
|
+
deviceType: DeviceType.Lock,
|
|
19408
|
+
outputCap: "group-active",
|
|
19409
|
+
outputField: "active",
|
|
19410
|
+
member: {
|
|
19411
|
+
cap: "lock-control",
|
|
19412
|
+
fieldPath: "state"
|
|
19413
|
+
},
|
|
19414
|
+
activeWhen: ["locked"],
|
|
19415
|
+
commandCaps: ["lock-control"]
|
|
19416
|
+
}),
|
|
19417
|
+
actuator({
|
|
19418
|
+
id: "media-player",
|
|
19419
|
+
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.",
|
|
19420
|
+
deviceType: DeviceType.MediaPlayer,
|
|
19421
|
+
outputCap: "group-active",
|
|
19422
|
+
outputField: "active",
|
|
19423
|
+
member: {
|
|
19424
|
+
cap: "media-player",
|
|
19425
|
+
fieldPath: "state"
|
|
19426
|
+
},
|
|
19427
|
+
activeWhen: ["playing", "buffering"],
|
|
19428
|
+
commandCaps: ["media-player"]
|
|
19429
|
+
}),
|
|
19430
|
+
actuator({
|
|
19431
|
+
id: "climate",
|
|
19432
|
+
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.",
|
|
19433
|
+
deviceType: DeviceType.Thermostat,
|
|
19434
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
19435
|
+
outputCap: "group-active",
|
|
19436
|
+
outputField: "active",
|
|
19437
|
+
member: {
|
|
19438
|
+
cap: "climate-control",
|
|
19439
|
+
fieldPath: "mode"
|
|
19440
|
+
},
|
|
19441
|
+
activeWhen: [
|
|
19442
|
+
"heat",
|
|
19443
|
+
"cool",
|
|
19444
|
+
"auto",
|
|
19445
|
+
"heat_cool",
|
|
19446
|
+
"fan_only",
|
|
19447
|
+
"dry"
|
|
19448
|
+
],
|
|
19449
|
+
commandCaps: ["climate-control"]
|
|
19116
19450
|
})
|
|
19117
19451
|
];
|
|
19118
19452
|
function actuator(input) {
|
|
19119
19453
|
return {
|
|
19120
|
-
|
|
19454
|
+
id: input.id,
|
|
19455
|
+
summary: input.summary,
|
|
19456
|
+
deviceType: input.deviceType,
|
|
19457
|
+
outputCap: input.outputCap,
|
|
19458
|
+
outputField: input.outputField,
|
|
19459
|
+
commandCaps: input.commandCaps,
|
|
19121
19460
|
family: "actuator",
|
|
19122
19461
|
role: void 0,
|
|
19123
19462
|
memberDeviceType: input.deviceType,
|
|
19124
|
-
|
|
19463
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
19464
|
+
activeWhen: input.activeWhen,
|
|
19125
19465
|
quantity: "none",
|
|
19126
19466
|
baseUnit: void 0,
|
|
19127
19467
|
aggregates: BINARY_AGGREGATES,
|
|
19128
19468
|
defaultAggregate: "any",
|
|
19129
19469
|
empty: "offline",
|
|
19130
|
-
accept: [
|
|
19131
|
-
cap: "switch",
|
|
19132
|
-
fieldPath: "on"
|
|
19133
|
-
}],
|
|
19470
|
+
accept: [input.member],
|
|
19134
19471
|
companions: [CHANGED]
|
|
19135
19472
|
};
|
|
19136
19473
|
}
|
|
19137
19474
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
19138
19475
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
19476
|
+
DeviceType.Camera;
|
|
19139
19477
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
19140
19478
|
/**
|
|
19141
19479
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -44495,7 +44833,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
44495
44833
|
});
|
|
44496
44834
|
/**
|
|
44497
44835
|
* Optional, richer endpoint shape returned by providers that expose
|
|
44498
|
-
* MORE than one ingress concurrently (Tailscale
|
|
44836
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
44499
44837
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
44500
44838
|
* the originating provider config (mode + sourcePort) so the
|
|
44501
44839
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -47182,7 +47520,20 @@ var NcRuleInputSchema = object({
|
|
|
47182
47520
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
47183
47521
|
* path does not run Zod defaults.
|
|
47184
47522
|
*/
|
|
47185
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
47523
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
47524
|
+
/**
|
|
47525
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
47526
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
47527
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
47528
|
+
* same mark the Library writes, and records whose notification it was and
|
|
47529
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
47530
|
+
*
|
|
47531
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
47532
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
47533
|
+
* authored before this field meant. An editor turns it off by writing
|
|
47534
|
+
* `false`, so it needs no `clear` key.
|
|
47535
|
+
*/
|
|
47536
|
+
askVerdict: boolean().optional()
|
|
47186
47537
|
});
|
|
47187
47538
|
/**
|
|
47188
47539
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -58424,7 +58775,8 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58424
58775
|
DeviceType.Switch,
|
|
58425
58776
|
DeviceType.PetFeeder,
|
|
58426
58777
|
DeviceType.Container,
|
|
58427
|
-
DeviceType.Thermostat
|
|
58778
|
+
DeviceType.Thermostat,
|
|
58779
|
+
DeviceType.EventEmitter
|
|
58428
58780
|
];
|
|
58429
58781
|
/** Generic Customize target for the percentage reading (D936). */
|
|
58430
58782
|
var batteryCustomize = {
|
|
@@ -61284,7 +61636,17 @@ var groupCommandsCapability = {
|
|
|
61284
61636
|
scope: "device",
|
|
61285
61637
|
deviceNative: true,
|
|
61286
61638
|
mode: "singleton",
|
|
61287
|
-
deviceTypes: [
|
|
61639
|
+
deviceTypes: [
|
|
61640
|
+
DeviceType.Switch,
|
|
61641
|
+
DeviceType.Light,
|
|
61642
|
+
DeviceType.Fan,
|
|
61643
|
+
DeviceType.Cover,
|
|
61644
|
+
DeviceType.Valve,
|
|
61645
|
+
DeviceType.Lock,
|
|
61646
|
+
DeviceType.MediaPlayer,
|
|
61647
|
+
DeviceType.Thermostat,
|
|
61648
|
+
DeviceType.Climate
|
|
61649
|
+
],
|
|
61288
61650
|
methods: {},
|
|
61289
61651
|
status: {
|
|
61290
61652
|
schema: GroupCommandsSchema,
|
|
@@ -61302,6 +61664,49 @@ var groupCommandsCapability = {
|
|
|
61302
61664
|
history: "none"
|
|
61303
61665
|
};
|
|
61304
61666
|
/**
|
|
61667
|
+
* Whether a helper actuator group counts as active (D944): at least one
|
|
61668
|
+
* included member is, or every included member is. What "active" means is the
|
|
61669
|
+
* type's: a cover is open, a lock is locked, a media player is playing, a
|
|
61670
|
+
* climate device is not off. A group of lights, switches and fans reports
|
|
61671
|
+
* `switch.on` instead; this cap is for the types whose own state is not a
|
|
61672
|
+
* yes/no. Unknown members are left out (`group-status` counts them) and an
|
|
61673
|
+
* empty included set takes the device offline, never `active: false`.
|
|
61674
|
+
*/
|
|
61675
|
+
var GroupActiveSchema = object({
|
|
61676
|
+
active: boolean().meta({ label: "Active" }),
|
|
61677
|
+
/** Ms epoch when the slice was last updated. */
|
|
61678
|
+
lastChangedAt: number()
|
|
61679
|
+
});
|
|
61680
|
+
var groupActiveCapability = {
|
|
61681
|
+
name: "group-active",
|
|
61682
|
+
scope: "device",
|
|
61683
|
+
deviceNative: true,
|
|
61684
|
+
mode: "singleton",
|
|
61685
|
+
deviceTypes: [
|
|
61686
|
+
DeviceType.Cover,
|
|
61687
|
+
DeviceType.Valve,
|
|
61688
|
+
DeviceType.Lock,
|
|
61689
|
+
DeviceType.MediaPlayer,
|
|
61690
|
+
DeviceType.Climate,
|
|
61691
|
+
DeviceType.Thermostat
|
|
61692
|
+
],
|
|
61693
|
+
methods: {},
|
|
61694
|
+
status: {
|
|
61695
|
+
schema: GroupActiveSchema,
|
|
61696
|
+
kind: "push"
|
|
61697
|
+
},
|
|
61698
|
+
runtimeState: GroupActiveSchema,
|
|
61699
|
+
/**
|
|
61700
|
+
* Runtime-state durability: **session** — recomputed from the members on the
|
|
61701
|
+
* next source event; a restored value would outlive the members it named.
|
|
61702
|
+
*
|
|
61703
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61704
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61705
|
+
*/
|
|
61706
|
+
durability: "session",
|
|
61707
|
+
history: "none"
|
|
61708
|
+
};
|
|
61709
|
+
/**
|
|
61305
61710
|
* How many members of a helper group answered (D944). Counts are integers,
|
|
61306
61711
|
* not measurements: zero included is a real count, never a stand-in reading.
|
|
61307
61712
|
* The reading itself stays on the output capability. History is none — the
|
|
@@ -61332,7 +61737,14 @@ var groupStatusCapability = {
|
|
|
61332
61737
|
deviceTypes: [
|
|
61333
61738
|
DeviceType.Sensor,
|
|
61334
61739
|
DeviceType.Switch,
|
|
61335
|
-
DeviceType.Light
|
|
61740
|
+
DeviceType.Light,
|
|
61741
|
+
DeviceType.Fan,
|
|
61742
|
+
DeviceType.Cover,
|
|
61743
|
+
DeviceType.Valve,
|
|
61744
|
+
DeviceType.Lock,
|
|
61745
|
+
DeviceType.MediaPlayer,
|
|
61746
|
+
DeviceType.Thermostat,
|
|
61747
|
+
DeviceType.Climate
|
|
61336
61748
|
],
|
|
61337
61749
|
methods: {},
|
|
61338
61750
|
status: {
|
|
@@ -62605,7 +63017,14 @@ var lockControlCapability = {
|
|
|
62605
63017
|
}),
|
|
62606
63018
|
unlock: method(object({
|
|
62607
63019
|
deviceId: number().int().nonnegative(),
|
|
62608
|
-
code: string().min(1).optional()
|
|
63020
|
+
code: string().min(1).optional(),
|
|
63021
|
+
/**
|
|
63022
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
63023
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
63024
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
63025
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
63026
|
+
*/
|
|
63027
|
+
confirm: boolean().optional()
|
|
62609
63028
|
}), _void(), {
|
|
62610
63029
|
kind: "mutation",
|
|
62611
63030
|
auth: "protected"
|
|
@@ -62642,6 +63061,44 @@ var lockControlCapability = {
|
|
|
62642
63061
|
volatileStateFields: ["lastChangedAt"]
|
|
62643
63062
|
};
|
|
62644
63063
|
/**
|
|
63064
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.kwhTotal`
|
|
63065
|
+
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
63066
|
+
* `value` is the time integral in the source quantity's accumulated base
|
|
63067
|
+
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
63068
|
+
*/
|
|
63069
|
+
var MeterStatusSchema = object({
|
|
63070
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
63071
|
+
lastFetchedAt: number()
|
|
63072
|
+
});
|
|
63073
|
+
var meterCapability = {
|
|
63074
|
+
name: "meter",
|
|
63075
|
+
scope: "device",
|
|
63076
|
+
deviceNative: true,
|
|
63077
|
+
mode: "singleton",
|
|
63078
|
+
deviceTypes: [DeviceType.Sensor],
|
|
63079
|
+
methods: {},
|
|
63080
|
+
status: {
|
|
63081
|
+
schema: MeterStatusSchema,
|
|
63082
|
+
kind: "push"
|
|
63083
|
+
},
|
|
63084
|
+
runtimeState: MeterStatusSchema,
|
|
63085
|
+
/**
|
|
63086
|
+
* Runtime-state durability: **restored** — the total is a cache of the
|
|
63087
|
+
* history integral. A restart shows it only until the history pass
|
|
63088
|
+
* recomputes the open period; it is not an in-memory buffer.
|
|
63089
|
+
*
|
|
63090
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
63091
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
63092
|
+
*/
|
|
63093
|
+
durability: "restored",
|
|
63094
|
+
history: { fields: { value: {
|
|
63095
|
+
kind: "counter",
|
|
63096
|
+
deadband: .001,
|
|
63097
|
+
minIntervalMs: 6e4
|
|
63098
|
+
} } },
|
|
63099
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63100
|
+
};
|
|
63101
|
+
/**
|
|
62645
63102
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
62646
63103
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
62647
63104
|
* `DeviceType.MediaPlayer`. Disjoint from the camera streaming
|
|
@@ -65219,9 +65676,9 @@ var PowerMeterStatusSchema = object({
|
|
|
65219
65676
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
65220
65677
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
65221
65678
|
/** Voltage in volts. */
|
|
65222
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
65679
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
65223
65680
|
/** Current in amperes. */
|
|
65224
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
65681
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
65225
65682
|
/** Apparent power in volt-amperes. */
|
|
65226
65683
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
65227
65684
|
/** Power factor (0..1) if reported. */
|
|
@@ -65229,12 +65686,74 @@ var PowerMeterStatusSchema = object({
|
|
|
65229
65686
|
/** Ms epoch when the slice was last updated. */
|
|
65230
65687
|
lastFetchedAt: number()
|
|
65231
65688
|
});
|
|
65689
|
+
/**
|
|
65690
|
+
* Loads that draw metered mains power (D951). The reading is a feature of the
|
|
65691
|
+
* device itself — a plug, a lamp, a fan, an air conditioner, a boiler, a
|
|
65692
|
+
* vacuum dock — not a separate sensor beside it. A `Sensor` stays: a clamp
|
|
65693
|
+
* meter or a standalone energy monitor IS the device. Cover, lock, valve,
|
|
65694
|
+
* camera and the like are left out: their draw is not what anyone meters.
|
|
65695
|
+
*/
|
|
65696
|
+
var POWER_METER_DEVICE_TYPES = [
|
|
65697
|
+
DeviceType.Sensor,
|
|
65698
|
+
DeviceType.Switch,
|
|
65699
|
+
DeviceType.Light,
|
|
65700
|
+
DeviceType.Fan,
|
|
65701
|
+
DeviceType.Climate,
|
|
65702
|
+
DeviceType.Thermostat,
|
|
65703
|
+
DeviceType.Humidifier,
|
|
65704
|
+
DeviceType.WaterHeater,
|
|
65705
|
+
DeviceType.MediaPlayer,
|
|
65706
|
+
DeviceType.Washer,
|
|
65707
|
+
DeviceType.Dryer,
|
|
65708
|
+
DeviceType.Dishwasher,
|
|
65709
|
+
DeviceType.Vacuum,
|
|
65710
|
+
DeviceType.LawnMower,
|
|
65711
|
+
DeviceType.PetFeeder
|
|
65712
|
+
];
|
|
65713
|
+
/** Everything but a bare `Sensor`: a sensor that takes its reading from another sensor adds nothing. */
|
|
65714
|
+
var POWER_METER_CUSTOMIZE_DEVICE_TYPES = POWER_METER_DEVICE_TYPES.filter((type) => type !== DeviceType.Sensor);
|
|
65715
|
+
/** One scalar target per reading; each is sourced from a device of its own (D951). */
|
|
65716
|
+
function powerTarget(id, unit) {
|
|
65717
|
+
return {
|
|
65718
|
+
id,
|
|
65719
|
+
cardinality: "scalar",
|
|
65720
|
+
vocabulary: {
|
|
65721
|
+
cap: "power-meter",
|
|
65722
|
+
stateField: id
|
|
65723
|
+
},
|
|
65724
|
+
deviceTypes: POWER_METER_CUSTOMIZE_DEVICE_TYPES,
|
|
65725
|
+
apply: "add",
|
|
65726
|
+
path: id,
|
|
65727
|
+
sources: [{
|
|
65728
|
+
kind: "numeric",
|
|
65729
|
+
requiredUnit: unit,
|
|
65730
|
+
transforms: [{ kind: "identity" }]
|
|
65731
|
+
}],
|
|
65732
|
+
companions: [{
|
|
65733
|
+
kind: "clock",
|
|
65734
|
+
path: "lastFetchedAt",
|
|
65735
|
+
when: "always"
|
|
65736
|
+
}],
|
|
65737
|
+
sourceReport: { status: "assignment-status" },
|
|
65738
|
+
advancedExpression: true
|
|
65739
|
+
};
|
|
65740
|
+
}
|
|
65741
|
+
/** "Power and energy" extension: watts, energy, voltage and current from other devices (D951). */
|
|
65742
|
+
var powerMeterCustomize = {
|
|
65743
|
+
version: 1,
|
|
65744
|
+
targets: [
|
|
65745
|
+
powerTarget("watts", "W"),
|
|
65746
|
+
powerTarget("kwhTotal", "kWh"),
|
|
65747
|
+
powerTarget("volts", "V"),
|
|
65748
|
+
powerTarget("amps", "A")
|
|
65749
|
+
]
|
|
65750
|
+
};
|
|
65232
65751
|
var powerMeterCapability = {
|
|
65233
65752
|
name: "power-meter",
|
|
65234
65753
|
scope: "device",
|
|
65235
65754
|
deviceNative: true,
|
|
65236
65755
|
mode: "singleton",
|
|
65237
|
-
deviceTypes:
|
|
65756
|
+
deviceTypes: POWER_METER_DEVICE_TYPES,
|
|
65238
65757
|
methods: {},
|
|
65239
65758
|
status: {
|
|
65240
65759
|
schema: PowerMeterStatusSchema,
|
|
@@ -65291,7 +65810,8 @@ var powerMeterCapability = {
|
|
|
65291
65810
|
} },
|
|
65292
65811
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65293
65812
|
* whether persisting is worth a SQLite commit. */
|
|
65294
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
65813
|
+
volatileStateFields: ["lastFetchedAt"],
|
|
65814
|
+
customize: powerMeterCustomize
|
|
65295
65815
|
};
|
|
65296
65816
|
/**
|
|
65297
65817
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -66084,6 +66604,8 @@ var runningCustomize = {
|
|
|
66084
66604
|
stateField: "running"
|
|
66085
66605
|
},
|
|
66086
66606
|
deviceTypes: [
|
|
66607
|
+
DeviceType.Washer,
|
|
66608
|
+
DeviceType.Dryer,
|
|
66087
66609
|
DeviceType.Dishwasher,
|
|
66088
66610
|
DeviceType.Vacuum,
|
|
66089
66611
|
DeviceType.LawnMower,
|
|
@@ -68965,7 +69487,8 @@ var switchCapability = {
|
|
|
68965
69487
|
deviceTypes: [
|
|
68966
69488
|
DeviceType.Switch,
|
|
68967
69489
|
DeviceType.Siren,
|
|
68968
|
-
DeviceType.Light
|
|
69490
|
+
DeviceType.Light,
|
|
69491
|
+
DeviceType.Fan
|
|
68969
69492
|
],
|
|
68970
69493
|
methods: { setState: method(object({
|
|
68971
69494
|
deviceId: number(),
|
|
@@ -71311,8 +71834,9 @@ function withClipEventLabels(provider, deps) {
|
|
|
71311
71834
|
listClips
|
|
71312
71835
|
};
|
|
71313
71836
|
}
|
|
71837
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
71314
71838
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
71315
|
-
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;
|
|
71839
|
+
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;
|
|
71316
71840
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
71317
71841
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
71318
71842
|
new Set(CAP_NAMES);
|
|
@@ -71656,6 +72180,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
71656
72180
|
featureProbe: featureProbeCapability,
|
|
71657
72181
|
flood: floodCapability,
|
|
71658
72182
|
gas: gasCapability,
|
|
72183
|
+
groupActive: groupActiveCapability,
|
|
71659
72184
|
groupCommands: groupCommandsCapability,
|
|
71660
72185
|
groupStatus: groupStatusCapability,
|
|
71661
72186
|
heatingValve: heatingValveCapability,
|
|
@@ -71667,6 +72192,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
71667
72192
|
lawnMowerControl: lawnMowerControlCapability,
|
|
71668
72193
|
lockControl: lockControlCapability,
|
|
71669
72194
|
mediaPlayer: mediaPlayerCapability,
|
|
72195
|
+
meter: meterCapability,
|
|
71670
72196
|
motion: motionCapability,
|
|
71671
72197
|
motionTrigger: motionTriggerCapability,
|
|
71672
72198
|
motionZones: motionZonesCapability,
|
|
@@ -72926,7 +73452,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
72926
73452
|
return toDeviceSummary(device, this.addonId);
|
|
72927
73453
|
}
|
|
72928
73454
|
};
|
|
72929
|
-
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;
|
|
73455
|
+
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;
|
|
72930
73456
|
new Set(Object.values(DeviceType));
|
|
72931
73457
|
Object.freeze({
|
|
72932
73458
|
"accessories.getStatus": {
|
|
@@ -76149,6 +76675,13 @@ Object.freeze({
|
|
|
76149
76675
|
access: "view",
|
|
76150
76676
|
role: "viewer"
|
|
76151
76677
|
},
|
|
76678
|
+
"groupActive.getStatus": {
|
|
76679
|
+
capName: "group-active",
|
|
76680
|
+
capScope: "device",
|
|
76681
|
+
addonId: null,
|
|
76682
|
+
access: "view",
|
|
76683
|
+
role: "viewer"
|
|
76684
|
+
},
|
|
76152
76685
|
"groupCommands.getStatus": {
|
|
76153
76686
|
capName: "group-commands",
|
|
76154
76687
|
capScope: "device",
|
|
@@ -77115,6 +77648,13 @@ Object.freeze({
|
|
|
77115
77648
|
access: "create",
|
|
77116
77649
|
role: "admin"
|
|
77117
77650
|
},
|
|
77651
|
+
"meter.getStatus": {
|
|
77652
|
+
capName: "meter",
|
|
77653
|
+
capScope: "device",
|
|
77654
|
+
addonId: null,
|
|
77655
|
+
access: "view",
|
|
77656
|
+
role: "viewer"
|
|
77657
|
+
},
|
|
77118
77658
|
"metricsProvider.collectSnapshot": {
|
|
77119
77659
|
capName: "metrics-provider",
|
|
77120
77660
|
capScope: "system",
|
|
@@ -85213,7 +85753,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
85213
85753
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
85214
85754
|
icon: "square"
|
|
85215
85755
|
}
|
|
85216
|
-
}
|
|
85756
|
+
},
|
|
85757
|
+
overrides: { byType: {
|
|
85758
|
+
[DeviceType.Washer]: {
|
|
85759
|
+
state: { running: {
|
|
85760
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
85761
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
85762
|
+
} },
|
|
85763
|
+
events: {
|
|
85764
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
85765
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
85766
|
+
}
|
|
85767
|
+
},
|
|
85768
|
+
[DeviceType.Dryer]: {
|
|
85769
|
+
state: { running: {
|
|
85770
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
85771
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
85772
|
+
} },
|
|
85773
|
+
events: {
|
|
85774
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
85775
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
85776
|
+
}
|
|
85777
|
+
},
|
|
85778
|
+
[DeviceType.Dishwasher]: {
|
|
85779
|
+
state: { running: {
|
|
85780
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
85781
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
85782
|
+
} },
|
|
85783
|
+
events: {
|
|
85784
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
85785
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
85786
|
+
}
|
|
85787
|
+
}
|
|
85788
|
+
} }
|
|
85217
85789
|
},
|
|
85218
85790
|
update: {
|
|
85219
85791
|
scope: "device",
|
|
@@ -85985,6 +86557,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85985
86557
|
icon: "flame"
|
|
85986
86558
|
}]
|
|
85987
86559
|
},
|
|
86560
|
+
"group-active": {
|
|
86561
|
+
scope: "device",
|
|
86562
|
+
noun: t("Group state", "Stato del gruppo")
|
|
86563
|
+
},
|
|
85988
86564
|
"group-commands": {
|
|
85989
86565
|
scope: "device",
|
|
85990
86566
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -86041,6 +86617,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86041
86617
|
}],
|
|
86042
86618
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
86043
86619
|
},
|
|
86620
|
+
meter: {
|
|
86621
|
+
scope: "device",
|
|
86622
|
+
noun: t("Meter", "Contatore"),
|
|
86623
|
+
state: [{
|
|
86624
|
+
kind: "numeric",
|
|
86625
|
+
field: "value",
|
|
86626
|
+
quantity: t("the total", "il totale"),
|
|
86627
|
+
label: t("Total", "Totale"),
|
|
86628
|
+
icon: "gauge"
|
|
86629
|
+
}]
|
|
86630
|
+
},
|
|
86044
86631
|
"numeric-sensor": {
|
|
86045
86632
|
scope: "device",
|
|
86046
86633
|
noun: t("Sensor", "Sensore"),
|
|
@@ -86513,8 +87100,47 @@ function projectAction(cap, action) {
|
|
|
86513
87100
|
};
|
|
86514
87101
|
}
|
|
86515
87102
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
86516
|
-
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;
|
|
87103
|
+
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;
|
|
86517
87104
|
DeviceFeature.BatteryOperated;
|
|
87105
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
87106
|
+
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.";
|
|
87107
|
+
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.";
|
|
87108
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
87109
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
87110
|
+
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.";
|
|
87111
|
+
function withheld(reason) {
|
|
87112
|
+
return {
|
|
87113
|
+
[DeviceType.Washer]: {
|
|
87114
|
+
exported: false,
|
|
87115
|
+
reason
|
|
87116
|
+
},
|
|
87117
|
+
[DeviceType.Dryer]: {
|
|
87118
|
+
exported: false,
|
|
87119
|
+
reason
|
|
87120
|
+
},
|
|
87121
|
+
[DeviceType.Dishwasher]: {
|
|
87122
|
+
exported: false,
|
|
87123
|
+
reason
|
|
87124
|
+
}
|
|
87125
|
+
};
|
|
87126
|
+
}
|
|
87127
|
+
function offered(received) {
|
|
87128
|
+
return {
|
|
87129
|
+
[DeviceType.Washer]: {
|
|
87130
|
+
exported: true,
|
|
87131
|
+
as: received
|
|
87132
|
+
},
|
|
87133
|
+
[DeviceType.Dryer]: {
|
|
87134
|
+
exported: true,
|
|
87135
|
+
as: received
|
|
87136
|
+
},
|
|
87137
|
+
[DeviceType.Dishwasher]: {
|
|
87138
|
+
exported: true,
|
|
87139
|
+
as: received
|
|
87140
|
+
}
|
|
87141
|
+
};
|
|
87142
|
+
}
|
|
87143
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
86518
87144
|
var LAST_FETCHED_FIELD = "lastFetchedAt";
|
|
86519
87145
|
/**
|
|
86520
87146
|
* How long a bridge stops re-attempting a refresh that did not land.
|
|
@@ -87633,6 +88259,11 @@ Object.freeze({
|
|
|
87633
88259
|
form: "single",
|
|
87634
88260
|
optional: false
|
|
87635
88261
|
}],
|
|
88262
|
+
"groupActive.getStatus": [{
|
|
88263
|
+
name: "deviceId",
|
|
88264
|
+
form: "single",
|
|
88265
|
+
optional: false
|
|
88266
|
+
}],
|
|
87636
88267
|
"groupCommands.getStatus": [{
|
|
87637
88268
|
name: "deviceId",
|
|
87638
88269
|
form: "single",
|
|
@@ -87843,6 +88474,11 @@ Object.freeze({
|
|
|
87843
88474
|
form: "single",
|
|
87844
88475
|
optional: false
|
|
87845
88476
|
}],
|
|
88477
|
+
"meter.getStatus": [{
|
|
88478
|
+
name: "deviceId",
|
|
88479
|
+
form: "single",
|
|
88480
|
+
optional: false
|
|
88481
|
+
}],
|
|
87846
88482
|
"motion.getStatus": [{
|
|
87847
88483
|
name: "deviceId",
|
|
87848
88484
|
form: "single",
|
|
@@ -89450,7 +90086,6 @@ Object.freeze({
|
|
|
89450
90086
|
"network-access": "ingress",
|
|
89451
90087
|
"smtp-provider": "email"
|
|
89452
90088
|
});
|
|
89453
|
-
DeviceType.Camera;
|
|
89454
90089
|
/**
|
|
89455
90090
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
89456
90091
|
* `z.infer`, they do not restate the shape.
|