@camstack/addon-google-services 0.2.32 → 0.2.33
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 +26 -8
- package/dist/google-services.addon.js +542 -47
- package/dist/google-services.addon.mjs +542 -47
- package/package.json +4 -4
|
@@ -5579,7 +5579,7 @@ var ZodIssueCode = {
|
|
|
5579
5579
|
var ZodFirstPartyTypeKind;
|
|
5580
5580
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5581
5581
|
//#endregion
|
|
5582
|
-
//#region ../types/dist/sleep
|
|
5582
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5583
5583
|
/**
|
|
5584
5584
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5585
5585
|
* window to float samples (D455).
|
|
@@ -8956,6 +8956,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8956
8956
|
"filesystem-browse",
|
|
8957
8957
|
"flood",
|
|
8958
8958
|
"gas",
|
|
8959
|
+
"group-active",
|
|
8959
8960
|
"group-commands",
|
|
8960
8961
|
"group-status",
|
|
8961
8962
|
"heating-valve",
|
|
@@ -8978,6 +8979,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8978
8979
|
"login-method",
|
|
8979
8980
|
"media-player",
|
|
8980
8981
|
"mesh-network",
|
|
8982
|
+
"meter",
|
|
8981
8983
|
"metrics-provider",
|
|
8982
8984
|
"model-convert",
|
|
8983
8985
|
"model-distributor",
|
|
@@ -9776,6 +9778,10 @@ Object.freeze({
|
|
|
9776
9778
|
"path": "detected",
|
|
9777
9779
|
"valueType": "boolean"
|
|
9778
9780
|
}],
|
|
9781
|
+
"group-active": [{
|
|
9782
|
+
"path": "active",
|
|
9783
|
+
"valueType": "boolean"
|
|
9784
|
+
}],
|
|
9779
9785
|
"group-status": [
|
|
9780
9786
|
{
|
|
9781
9787
|
"path": "included",
|
|
@@ -10035,6 +10041,10 @@ Object.freeze({
|
|
|
10035
10041
|
]
|
|
10036
10042
|
}
|
|
10037
10043
|
],
|
|
10044
|
+
"meter": [{
|
|
10045
|
+
"path": "value",
|
|
10046
|
+
"valueType": "number"
|
|
10047
|
+
}],
|
|
10038
10048
|
"motion": [
|
|
10039
10049
|
{
|
|
10040
10050
|
"path": "detected",
|
|
@@ -10792,7 +10802,7 @@ function userError(code, params, englishFallback) {
|
|
|
10792
10802
|
return new CamstackError(code, params, englishFallback);
|
|
10793
10803
|
}
|
|
10794
10804
|
//#endregion
|
|
10795
|
-
//#region ../types/dist/err-msg-
|
|
10805
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
10796
10806
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
10797
10807
|
DeviceType["Camera"] = "camera";
|
|
10798
10808
|
DeviceType["Hub"] = "hub";
|
|
@@ -10886,8 +10896,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
10886
10896
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
10887
10897
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
10888
10898
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
10889
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10899
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10900
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
10890
10901
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
10902
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
10903
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
10904
|
+
DeviceType["Washer"] = "washer";
|
|
10905
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
10906
|
+
DeviceType["Dryer"] = "dryer";
|
|
10891
10907
|
return DeviceType;
|
|
10892
10908
|
}({});
|
|
10893
10909
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -11135,7 +11151,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11135
11151
|
return DeviceRole;
|
|
11136
11152
|
}({});
|
|
11137
11153
|
//#endregion
|
|
11138
|
-
//#region ../types/dist/composition-
|
|
11154
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
11139
11155
|
/**
|
|
11140
11156
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11141
11157
|
*
|
|
@@ -11450,6 +11466,13 @@ var table = {
|
|
|
11450
11466
|
apply: () => {
|
|
11451
11467
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11452
11468
|
}
|
|
11469
|
+
},
|
|
11470
|
+
schmitt: {
|
|
11471
|
+
minArgs: 3,
|
|
11472
|
+
maxArgs: 5,
|
|
11473
|
+
apply: () => {
|
|
11474
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11475
|
+
}
|
|
11453
11476
|
}
|
|
11454
11477
|
};
|
|
11455
11478
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11891,6 +11914,99 @@ function validateExpressionSource(src) {
|
|
|
11891
11914
|
return null;
|
|
11892
11915
|
}
|
|
11893
11916
|
/**
|
|
11917
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
11918
|
+
*
|
|
11919
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
11920
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
11921
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
11922
|
+
*
|
|
11923
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
11924
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
11925
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
11926
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
11927
|
+
* can move later without moving the others.
|
|
11928
|
+
*/
|
|
11929
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
11930
|
+
var APPLIANCE_KINDS = [
|
|
11931
|
+
"washer",
|
|
11932
|
+
"dryer",
|
|
11933
|
+
"dishwasher"
|
|
11934
|
+
];
|
|
11935
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11936
|
+
/**
|
|
11937
|
+
* Statistics and integrals over a history read (D944).
|
|
11938
|
+
*
|
|
11939
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11940
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11941
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11942
|
+
* as zero. A truncated read is not published.
|
|
11943
|
+
*/
|
|
11944
|
+
var STATISTIC_STATS = [
|
|
11945
|
+
"min",
|
|
11946
|
+
"max",
|
|
11947
|
+
"mean",
|
|
11948
|
+
"sum",
|
|
11949
|
+
"count",
|
|
11950
|
+
"change"
|
|
11951
|
+
];
|
|
11952
|
+
/**
|
|
11953
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11954
|
+
*
|
|
11955
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11956
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11957
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11958
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11959
|
+
*/
|
|
11960
|
+
var MINUTE_MS = 6e4;
|
|
11961
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11962
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11963
|
+
var ROLLING_SPANS = [
|
|
11964
|
+
"1h",
|
|
11965
|
+
"24h",
|
|
11966
|
+
"2d",
|
|
11967
|
+
"7d",
|
|
11968
|
+
"30d",
|
|
11969
|
+
"custom"
|
|
11970
|
+
];
|
|
11971
|
+
var CALENDAR_PERIODS = [
|
|
11972
|
+
"today",
|
|
11973
|
+
"yesterday",
|
|
11974
|
+
"this-week",
|
|
11975
|
+
"this-month"
|
|
11976
|
+
];
|
|
11977
|
+
var RESET_PERIODS = [
|
|
11978
|
+
"never",
|
|
11979
|
+
"daily",
|
|
11980
|
+
"weekly",
|
|
11981
|
+
"monthly"
|
|
11982
|
+
];
|
|
11983
|
+
5 * MINUTE_MS;
|
|
11984
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11985
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11986
|
+
var rollingWindowObject = object({
|
|
11987
|
+
kind: literal("rolling"),
|
|
11988
|
+
span: _enum(ROLLING_SPANS),
|
|
11989
|
+
customMinutes: number().int().min(5).optional()
|
|
11990
|
+
}).check((payload) => {
|
|
11991
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11992
|
+
code: "custom",
|
|
11993
|
+
message: "a custom range needs a duration in minutes",
|
|
11994
|
+
path: ["customMinutes"],
|
|
11995
|
+
input: payload.value
|
|
11996
|
+
});
|
|
11997
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11998
|
+
code: "custom",
|
|
11999
|
+
message: "only a custom range carries a duration",
|
|
12000
|
+
path: ["customMinutes"],
|
|
12001
|
+
input: payload.value
|
|
12002
|
+
});
|
|
12003
|
+
});
|
|
12004
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
12005
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
12006
|
+
kind: literal("calendar"),
|
|
12007
|
+
period: _enum(CALENDAR_PERIODS)
|
|
12008
|
+
})]);
|
|
12009
|
+
/**
|
|
11894
12010
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11895
12011
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11896
12012
|
* `composition.ts` (D659).
|
|
@@ -11916,7 +12032,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11916
12032
|
"occupancy",
|
|
11917
12033
|
"binary",
|
|
11918
12034
|
"switch",
|
|
11919
|
-
"light"
|
|
12035
|
+
"light",
|
|
12036
|
+
"fan",
|
|
12037
|
+
"cover",
|
|
12038
|
+
"valve",
|
|
12039
|
+
"lock",
|
|
12040
|
+
"media-player",
|
|
12041
|
+
"climate"
|
|
11920
12042
|
];
|
|
11921
12043
|
var NUMERIC_AGGREGATES = [
|
|
11922
12044
|
"mean",
|
|
@@ -11946,14 +12068,73 @@ var HelperMemberSchema = object({
|
|
|
11946
12068
|
cap: string().min(1),
|
|
11947
12069
|
fieldPath: string().min(1)
|
|
11948
12070
|
});
|
|
11949
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
11955
|
-
|
|
11956
|
-
|
|
12071
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12072
|
+
object({
|
|
12073
|
+
kind: literal("group"),
|
|
12074
|
+
templateId: GroupTemplateIdSchema,
|
|
12075
|
+
aggregate: AggregateReducerSchema,
|
|
12076
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
12077
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
12078
|
+
active: ActiveCriterionSchema.optional()
|
|
12079
|
+
}),
|
|
12080
|
+
object({
|
|
12081
|
+
kind: literal("appliance"),
|
|
12082
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
12083
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
12084
|
+
thresholdWatts: number().positive(),
|
|
12085
|
+
startDwellMs: number().int().nonnegative(),
|
|
12086
|
+
stopDwellMs: number().int().nonnegative(),
|
|
12087
|
+
member: HelperMemberSchema
|
|
12088
|
+
}),
|
|
12089
|
+
object({
|
|
12090
|
+
kind: literal("statistic"),
|
|
12091
|
+
stat: _enum(STATISTIC_STATS),
|
|
12092
|
+
window: StatisticWindowSchema,
|
|
12093
|
+
source: HelperMemberSchema
|
|
12094
|
+
}),
|
|
12095
|
+
object({
|
|
12096
|
+
kind: literal("integral"),
|
|
12097
|
+
reset: _enum(RESET_PERIODS),
|
|
12098
|
+
output: _enum(["energy", "meter"]),
|
|
12099
|
+
source: HelperMemberSchema
|
|
12100
|
+
}),
|
|
12101
|
+
object({
|
|
12102
|
+
kind: literal("threshold"),
|
|
12103
|
+
source: HelperMemberSchema,
|
|
12104
|
+
high: number(),
|
|
12105
|
+
low: number(),
|
|
12106
|
+
onForMs: number().int().nonnegative(),
|
|
12107
|
+
offForMs: number().int().nonnegative()
|
|
12108
|
+
}),
|
|
12109
|
+
object({
|
|
12110
|
+
kind: literal("arithmetic"),
|
|
12111
|
+
op: _enum([
|
|
12112
|
+
"sum",
|
|
12113
|
+
"difference",
|
|
12114
|
+
"ratio"
|
|
12115
|
+
]),
|
|
12116
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
12117
|
+
}),
|
|
12118
|
+
object({
|
|
12119
|
+
kind: literal("expression"),
|
|
12120
|
+
expr: string().min(1),
|
|
12121
|
+
inputs: array(object({
|
|
12122
|
+
name: string().min(1),
|
|
12123
|
+
member: HelperMemberSchema
|
|
12124
|
+
})).min(1).max(64),
|
|
12125
|
+
output: _enum(["number", "boolean"])
|
|
12126
|
+
}),
|
|
12127
|
+
object({
|
|
12128
|
+
kind: literal("derivative"),
|
|
12129
|
+
window: RollingWindowSchema,
|
|
12130
|
+
per: _enum([
|
|
12131
|
+
"second",
|
|
12132
|
+
"minute",
|
|
12133
|
+
"hour"
|
|
12134
|
+
]),
|
|
12135
|
+
source: HelperMemberSchema
|
|
12136
|
+
})
|
|
12137
|
+
]);
|
|
11957
12138
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11958
12139
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11959
12140
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -12014,6 +12195,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12014
12195
|
"all"
|
|
12015
12196
|
]),
|
|
12016
12197
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12198
|
+
/**
|
|
12199
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
12200
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
12201
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
12202
|
+
*/
|
|
12203
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
12017
12204
|
/** `value` is the reading; the others are the member counts. */
|
|
12018
12205
|
publish: _enum([
|
|
12019
12206
|
"value",
|
|
@@ -12027,6 +12214,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12027
12214
|
"omit",
|
|
12028
12215
|
"offline"
|
|
12029
12216
|
])
|
|
12217
|
+
}),
|
|
12218
|
+
object({
|
|
12219
|
+
kind: literal("series"),
|
|
12220
|
+
read: CompositionFieldReadSchema,
|
|
12221
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
12222
|
+
publish: _enum([
|
|
12223
|
+
"value",
|
|
12224
|
+
"included",
|
|
12225
|
+
"excluded",
|
|
12226
|
+
"total"
|
|
12227
|
+
]),
|
|
12228
|
+
/**
|
|
12229
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12230
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12231
|
+
*/
|
|
12232
|
+
empty: _enum([
|
|
12233
|
+
"null",
|
|
12234
|
+
"omit",
|
|
12235
|
+
"offline"
|
|
12236
|
+
])
|
|
12030
12237
|
})
|
|
12031
12238
|
]);
|
|
12032
12239
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -17322,7 +17529,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
17322
17529
|
*/
|
|
17323
17530
|
interactiveConnectPath: string().min(1).optional(),
|
|
17324
17531
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
17325
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
17532
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
17533
|
+
/**
|
|
17534
|
+
* The kind signs in through a server-held interactive session instead of
|
|
17535
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
17536
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
17537
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
17538
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
17539
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
17540
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
17541
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
17542
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
17543
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
17544
|
+
* offers it as the default path; the fields the session fills are
|
|
17545
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
17546
|
+
*/
|
|
17547
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
17326
17548
|
}))
|
|
17327
17549
|
});
|
|
17328
17550
|
var ListInputSchema = object({
|
|
@@ -18370,7 +18592,8 @@ var CompositionProblemSchema = object({
|
|
|
18370
18592
|
"native-capability-replace",
|
|
18371
18593
|
"mixed-quantity",
|
|
18372
18594
|
"helper-mismatch",
|
|
18373
|
-
"member-constraint"
|
|
18595
|
+
"member-constraint",
|
|
18596
|
+
"retention"
|
|
18374
18597
|
]),
|
|
18375
18598
|
path: string(),
|
|
18376
18599
|
message: string()
|
|
@@ -18604,13 +18827,17 @@ Object.freeze({
|
|
|
18604
18827
|
latchedAt: {
|
|
18605
18828
|
kind: "fixed",
|
|
18606
18829
|
result: ["number", "null"]
|
|
18830
|
+
},
|
|
18831
|
+
schmitt: {
|
|
18832
|
+
kind: "fixed",
|
|
18833
|
+
result: ["boolean", "null"]
|
|
18607
18834
|
}
|
|
18608
18835
|
});
|
|
18609
18836
|
/**
|
|
18610
18837
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18611
18838
|
* Data, not a form default written into the block.
|
|
18612
18839
|
*/
|
|
18613
|
-
var NOW = {
|
|
18840
|
+
var NOW$2 = {
|
|
18614
18841
|
fieldPath: "lastFetchedAt",
|
|
18615
18842
|
expr: "now"
|
|
18616
18843
|
};
|
|
@@ -18624,6 +18851,8 @@ function numeric(input) {
|
|
|
18624
18851
|
family: "numeric",
|
|
18625
18852
|
deviceType: DeviceType.Sensor,
|
|
18626
18853
|
memberDeviceType: DeviceType.Sensor,
|
|
18854
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18855
|
+
activeWhen: void 0,
|
|
18627
18856
|
commandCaps: [],
|
|
18628
18857
|
baseUnit: baseUnitOf(input.quantity),
|
|
18629
18858
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18639,6 +18868,8 @@ function binary(input) {
|
|
|
18639
18868
|
family: "binary",
|
|
18640
18869
|
deviceType: DeviceType.Sensor,
|
|
18641
18870
|
memberDeviceType: DeviceType.Sensor,
|
|
18871
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18872
|
+
activeWhen: void 0,
|
|
18642
18873
|
commandCaps: [],
|
|
18643
18874
|
quantity: "none",
|
|
18644
18875
|
baseUnit: void 0,
|
|
@@ -18656,7 +18887,7 @@ var GROUP_TEMPLATES = [
|
|
|
18656
18887
|
quantity: "temperature",
|
|
18657
18888
|
defaultAggregate: "mean",
|
|
18658
18889
|
empty: "null",
|
|
18659
|
-
companions: [NOW]
|
|
18890
|
+
companions: [NOW$2]
|
|
18660
18891
|
}),
|
|
18661
18892
|
numeric({
|
|
18662
18893
|
id: "humidity",
|
|
@@ -18667,7 +18898,7 @@ var GROUP_TEMPLATES = [
|
|
|
18667
18898
|
quantity: "humidity",
|
|
18668
18899
|
defaultAggregate: "mean",
|
|
18669
18900
|
empty: "null",
|
|
18670
|
-
companions: [NOW]
|
|
18901
|
+
companions: [NOW$2]
|
|
18671
18902
|
}),
|
|
18672
18903
|
numeric({
|
|
18673
18904
|
id: "pressure",
|
|
@@ -18678,7 +18909,7 @@ var GROUP_TEMPLATES = [
|
|
|
18678
18909
|
quantity: "pressure",
|
|
18679
18910
|
defaultAggregate: "mean",
|
|
18680
18911
|
empty: "null",
|
|
18681
|
-
companions: [NOW]
|
|
18912
|
+
companions: [NOW$2]
|
|
18682
18913
|
}),
|
|
18683
18914
|
numeric({
|
|
18684
18915
|
id: "illuminance",
|
|
@@ -18689,7 +18920,7 @@ var GROUP_TEMPLATES = [
|
|
|
18689
18920
|
quantity: "illuminance",
|
|
18690
18921
|
defaultAggregate: "mean",
|
|
18691
18922
|
empty: "null",
|
|
18692
|
-
companions: [NOW]
|
|
18923
|
+
companions: [NOW$2]
|
|
18693
18924
|
}),
|
|
18694
18925
|
numeric({
|
|
18695
18926
|
id: "power",
|
|
@@ -18700,7 +18931,7 @@ var GROUP_TEMPLATES = [
|
|
|
18700
18931
|
quantity: "power",
|
|
18701
18932
|
defaultAggregate: "sum",
|
|
18702
18933
|
empty: "omit",
|
|
18703
|
-
companions: [NOW]
|
|
18934
|
+
companions: [NOW$2]
|
|
18704
18935
|
}),
|
|
18705
18936
|
numeric({
|
|
18706
18937
|
id: "energy",
|
|
@@ -18711,7 +18942,7 @@ var GROUP_TEMPLATES = [
|
|
|
18711
18942
|
quantity: "energy",
|
|
18712
18943
|
defaultAggregate: "sum",
|
|
18713
18944
|
empty: "omit",
|
|
18714
|
-
companions: [NOW]
|
|
18945
|
+
companions: [NOW$2]
|
|
18715
18946
|
}),
|
|
18716
18947
|
numeric({
|
|
18717
18948
|
id: "battery",
|
|
@@ -18746,7 +18977,7 @@ var GROUP_TEMPLATES = [
|
|
|
18746
18977
|
quantity: "device",
|
|
18747
18978
|
defaultAggregate: "mean",
|
|
18748
18979
|
empty: "null",
|
|
18749
|
-
companions: [NOW]
|
|
18980
|
+
companions: [NOW$2]
|
|
18750
18981
|
}),
|
|
18751
18982
|
binary({
|
|
18752
18983
|
id: "motion",
|
|
@@ -18840,6 +19071,11 @@ var GROUP_TEMPLATES = [
|
|
|
18840
19071
|
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.",
|
|
18841
19072
|
deviceType: DeviceType.Switch,
|
|
18842
19073
|
outputCap: "switch",
|
|
19074
|
+
outputField: "on",
|
|
19075
|
+
member: {
|
|
19076
|
+
cap: "switch",
|
|
19077
|
+
fieldPath: "on"
|
|
19078
|
+
},
|
|
18843
19079
|
commandCaps: ["switch"]
|
|
18844
19080
|
}),
|
|
18845
19081
|
actuator({
|
|
@@ -18847,34 +19083,136 @@ var GROUP_TEMPLATES = [
|
|
|
18847
19083
|
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.",
|
|
18848
19084
|
deviceType: DeviceType.Light,
|
|
18849
19085
|
outputCap: "switch",
|
|
19086
|
+
outputField: "on",
|
|
19087
|
+
member: {
|
|
19088
|
+
cap: "switch",
|
|
19089
|
+
fieldPath: "on"
|
|
19090
|
+
},
|
|
18850
19091
|
commandCaps: [
|
|
18851
19092
|
"switch",
|
|
18852
19093
|
"brightness",
|
|
18853
19094
|
"color"
|
|
18854
19095
|
]
|
|
19096
|
+
}),
|
|
19097
|
+
actuator({
|
|
19098
|
+
id: "fan",
|
|
19099
|
+
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.",
|
|
19100
|
+
deviceType: DeviceType.Fan,
|
|
19101
|
+
outputCap: "switch",
|
|
19102
|
+
outputField: "on",
|
|
19103
|
+
member: {
|
|
19104
|
+
cap: "switch",
|
|
19105
|
+
fieldPath: "on"
|
|
19106
|
+
},
|
|
19107
|
+
commandCaps: ["switch", "fan-control"]
|
|
19108
|
+
}),
|
|
19109
|
+
actuator({
|
|
19110
|
+
id: "cover",
|
|
19111
|
+
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.",
|
|
19112
|
+
deviceType: DeviceType.Cover,
|
|
19113
|
+
outputCap: "group-active",
|
|
19114
|
+
outputField: "active",
|
|
19115
|
+
member: {
|
|
19116
|
+
cap: "cover",
|
|
19117
|
+
fieldPath: "state"
|
|
19118
|
+
},
|
|
19119
|
+
activeWhen: [
|
|
19120
|
+
"open",
|
|
19121
|
+
"opening",
|
|
19122
|
+
"stopped"
|
|
19123
|
+
],
|
|
19124
|
+
commandCaps: ["cover"]
|
|
19125
|
+
}),
|
|
19126
|
+
actuator({
|
|
19127
|
+
id: "valve",
|
|
19128
|
+
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.",
|
|
19129
|
+
deviceType: DeviceType.Valve,
|
|
19130
|
+
outputCap: "group-active",
|
|
19131
|
+
outputField: "active",
|
|
19132
|
+
member: {
|
|
19133
|
+
cap: "valve",
|
|
19134
|
+
fieldPath: "state"
|
|
19135
|
+
},
|
|
19136
|
+
activeWhen: [
|
|
19137
|
+
"open",
|
|
19138
|
+
"opening",
|
|
19139
|
+
"stopped"
|
|
19140
|
+
],
|
|
19141
|
+
commandCaps: ["valve"]
|
|
19142
|
+
}),
|
|
19143
|
+
actuator({
|
|
19144
|
+
id: "lock",
|
|
19145
|
+
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.",
|
|
19146
|
+
deviceType: DeviceType.Lock,
|
|
19147
|
+
outputCap: "group-active",
|
|
19148
|
+
outputField: "active",
|
|
19149
|
+
member: {
|
|
19150
|
+
cap: "lock-control",
|
|
19151
|
+
fieldPath: "state"
|
|
19152
|
+
},
|
|
19153
|
+
activeWhen: ["locked"],
|
|
19154
|
+
commandCaps: ["lock-control"]
|
|
19155
|
+
}),
|
|
19156
|
+
actuator({
|
|
19157
|
+
id: "media-player",
|
|
19158
|
+
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.",
|
|
19159
|
+
deviceType: DeviceType.MediaPlayer,
|
|
19160
|
+
outputCap: "group-active",
|
|
19161
|
+
outputField: "active",
|
|
19162
|
+
member: {
|
|
19163
|
+
cap: "media-player",
|
|
19164
|
+
fieldPath: "state"
|
|
19165
|
+
},
|
|
19166
|
+
activeWhen: ["playing", "buffering"],
|
|
19167
|
+
commandCaps: ["media-player"]
|
|
19168
|
+
}),
|
|
19169
|
+
actuator({
|
|
19170
|
+
id: "climate",
|
|
19171
|
+
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.",
|
|
19172
|
+
deviceType: DeviceType.Thermostat,
|
|
19173
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
19174
|
+
outputCap: "group-active",
|
|
19175
|
+
outputField: "active",
|
|
19176
|
+
member: {
|
|
19177
|
+
cap: "climate-control",
|
|
19178
|
+
fieldPath: "mode"
|
|
19179
|
+
},
|
|
19180
|
+
activeWhen: [
|
|
19181
|
+
"heat",
|
|
19182
|
+
"cool",
|
|
19183
|
+
"auto",
|
|
19184
|
+
"heat_cool",
|
|
19185
|
+
"fan_only",
|
|
19186
|
+
"dry"
|
|
19187
|
+
],
|
|
19188
|
+
commandCaps: ["climate-control"]
|
|
18855
19189
|
})
|
|
18856
19190
|
];
|
|
18857
19191
|
function actuator(input) {
|
|
18858
19192
|
return {
|
|
18859
|
-
|
|
19193
|
+
id: input.id,
|
|
19194
|
+
summary: input.summary,
|
|
19195
|
+
deviceType: input.deviceType,
|
|
19196
|
+
outputCap: input.outputCap,
|
|
19197
|
+
outputField: input.outputField,
|
|
19198
|
+
commandCaps: input.commandCaps,
|
|
18860
19199
|
family: "actuator",
|
|
18861
19200
|
role: void 0,
|
|
18862
19201
|
memberDeviceType: input.deviceType,
|
|
18863
|
-
|
|
19202
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
19203
|
+
activeWhen: input.activeWhen,
|
|
18864
19204
|
quantity: "none",
|
|
18865
19205
|
baseUnit: void 0,
|
|
18866
19206
|
aggregates: BINARY_AGGREGATES,
|
|
18867
19207
|
defaultAggregate: "any",
|
|
18868
19208
|
empty: "offline",
|
|
18869
|
-
accept: [
|
|
18870
|
-
cap: "switch",
|
|
18871
|
-
fieldPath: "on"
|
|
18872
|
-
}],
|
|
19209
|
+
accept: [input.member],
|
|
18873
19210
|
companions: [CHANGED]
|
|
18874
19211
|
};
|
|
18875
19212
|
}
|
|
18876
19213
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18877
19214
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
19215
|
+
DeviceType.Camera;
|
|
18878
19216
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18879
19217
|
/**
|
|
18880
19218
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -43889,7 +44227,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
43889
44227
|
});
|
|
43890
44228
|
/**
|
|
43891
44229
|
* Optional, richer endpoint shape returned by providers that expose
|
|
43892
|
-
* MORE than one ingress concurrently (Tailscale
|
|
44230
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
43893
44231
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
43894
44232
|
* the originating provider config (mode + sourcePort) so the
|
|
43895
44233
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -46532,7 +46870,20 @@ var NcRuleInputSchema = object({
|
|
|
46532
46870
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
46533
46871
|
* path does not run Zod defaults.
|
|
46534
46872
|
*/
|
|
46535
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46873
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46874
|
+
/**
|
|
46875
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46876
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46877
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46878
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46879
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46880
|
+
*
|
|
46881
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46882
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46883
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46884
|
+
* `false`, so it needs no `clear` key.
|
|
46885
|
+
*/
|
|
46886
|
+
askVerdict: boolean().optional()
|
|
46536
46887
|
});
|
|
46537
46888
|
/**
|
|
46538
46889
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -57002,7 +57353,7 @@ var BatteryStatusSchema = object({
|
|
|
57002
57353
|
*/
|
|
57003
57354
|
binary: boolean().optional().meta({ label: "Binary indicator" })
|
|
57004
57355
|
});
|
|
57005
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
|
|
57356
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter;
|
|
57006
57357
|
method(object({
|
|
57007
57358
|
deviceId: number(),
|
|
57008
57359
|
/** Bound on the wait. Sensible range 3000–10000ms. */
|
|
@@ -58756,7 +59107,13 @@ results: array(object({
|
|
|
58756
59107
|
/** Ms epoch of the attempt. */
|
|
58757
59108
|
at: number()
|
|
58758
59109
|
})) });
|
|
58759
|
-
DeviceType.Switch, DeviceType.Light;
|
|
59110
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
59111
|
+
object({
|
|
59112
|
+
active: boolean().meta({ label: "Active" }),
|
|
59113
|
+
/** Ms epoch when the slice was last updated. */
|
|
59114
|
+
lastChangedAt: number()
|
|
59115
|
+
});
|
|
59116
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
58760
59117
|
object({
|
|
58761
59118
|
/** Members whose current value entered the aggregate. */
|
|
58762
59119
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -58774,7 +59131,7 @@ object({
|
|
|
58774
59131
|
label: "Members"
|
|
58775
59132
|
}))
|
|
58776
59133
|
});
|
|
58777
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
59134
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58778
59135
|
object({
|
|
58779
59136
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58780
59137
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -59681,7 +60038,14 @@ DeviceType.Lock, method(object({
|
|
|
59681
60038
|
auth: "protected"
|
|
59682
60039
|
}), method(object({
|
|
59683
60040
|
deviceId: number().int().nonnegative(),
|
|
59684
|
-
code: string().min(1).optional()
|
|
60041
|
+
code: string().min(1).optional(),
|
|
60042
|
+
/**
|
|
60043
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
60044
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
60045
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
60046
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
60047
|
+
*/
|
|
60048
|
+
confirm: boolean().optional()
|
|
59685
60049
|
}), _void(), {
|
|
59686
60050
|
kind: "mutation",
|
|
59687
60051
|
auth: "protected"
|
|
@@ -59689,6 +60053,11 @@ DeviceType.Lock, method(object({
|
|
|
59689
60053
|
kind: "mutation",
|
|
59690
60054
|
auth: "protected"
|
|
59691
60055
|
});
|
|
60056
|
+
object({
|
|
60057
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
60058
|
+
lastFetchedAt: number()
|
|
60059
|
+
});
|
|
60060
|
+
DeviceType.Sensor;
|
|
59692
60061
|
/**
|
|
59693
60062
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
59694
60063
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -61596,9 +61965,9 @@ object({
|
|
|
61596
61965
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61597
61966
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61598
61967
|
/** Voltage in volts. */
|
|
61599
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
61968
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
61600
61969
|
/** Current in amperes. */
|
|
61601
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
61970
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
61602
61971
|
/** Apparent power in volt-amperes. */
|
|
61603
61972
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61604
61973
|
/** Power factor (0..1) if reported. */
|
|
@@ -61606,7 +61975,23 @@ object({
|
|
|
61606
61975
|
/** Ms epoch when the slice was last updated. */
|
|
61607
61976
|
lastFetchedAt: number()
|
|
61608
61977
|
});
|
|
61609
|
-
|
|
61978
|
+
[
|
|
61979
|
+
DeviceType.Sensor,
|
|
61980
|
+
DeviceType.Switch,
|
|
61981
|
+
DeviceType.Light,
|
|
61982
|
+
DeviceType.Fan,
|
|
61983
|
+
DeviceType.Climate,
|
|
61984
|
+
DeviceType.Thermostat,
|
|
61985
|
+
DeviceType.Humidifier,
|
|
61986
|
+
DeviceType.WaterHeater,
|
|
61987
|
+
DeviceType.MediaPlayer,
|
|
61988
|
+
DeviceType.Washer,
|
|
61989
|
+
DeviceType.Dryer,
|
|
61990
|
+
DeviceType.Dishwasher,
|
|
61991
|
+
DeviceType.Vacuum,
|
|
61992
|
+
DeviceType.LawnMower,
|
|
61993
|
+
DeviceType.PetFeeder
|
|
61994
|
+
].filter((type) => type !== DeviceType.Sensor);
|
|
61610
61995
|
/**
|
|
61611
61996
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
61612
61997
|
* on `DeviceType.Presence`. Read-only — no setters: presence is
|
|
@@ -62053,7 +62438,7 @@ object({
|
|
|
62053
62438
|
phase: string().nullable()
|
|
62054
62439
|
});
|
|
62055
62440
|
Object.values(DeviceType);
|
|
62056
|
-
DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
62441
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
62057
62442
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
|
|
62058
62443
|
kind: "mutation",
|
|
62059
62444
|
auth: "admin"
|
|
@@ -64092,7 +64477,7 @@ object({
|
|
|
64092
64477
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
64093
64478
|
lastChangedAt: number()
|
|
64094
64479
|
});
|
|
64095
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
64480
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
64096
64481
|
deviceId: number(),
|
|
64097
64482
|
on: boolean()
|
|
64098
64483
|
}), _void(), {
|
|
@@ -65784,8 +66169,9 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
65784
66169
|
kind: "mutation",
|
|
65785
66170
|
auth: "admin"
|
|
65786
66171
|
});
|
|
66172
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
65787
66173
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
65788
|
-
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;
|
|
66174
|
+
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;
|
|
65789
66175
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
65790
66176
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
65791
66177
|
new Set(CAP_NAMES);
|
|
@@ -65838,7 +66224,7 @@ var AccessoryKind = {
|
|
|
65838
66224
|
PrivacyMask: DeviceRole.PrivacyMask
|
|
65839
66225
|
};
|
|
65840
66226
|
AccessoryKind.Siren, AccessoryKind.Floodlight, AccessoryKind.Spotlight, AccessoryKind.PirSensor, AccessoryKind.Chime, AccessoryKind.Autotrack, AccessoryKind.Nightvision, AccessoryKind.PrivacyMask;
|
|
65841
|
-
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;
|
|
66227
|
+
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;
|
|
65842
66228
|
new Set(Object.values(DeviceType));
|
|
65843
66229
|
Object.freeze({
|
|
65844
66230
|
"accessories.getStatus": {
|
|
@@ -69061,6 +69447,13 @@ Object.freeze({
|
|
|
69061
69447
|
access: "view",
|
|
69062
69448
|
role: "viewer"
|
|
69063
69449
|
},
|
|
69450
|
+
"groupActive.getStatus": {
|
|
69451
|
+
capName: "group-active",
|
|
69452
|
+
capScope: "device",
|
|
69453
|
+
addonId: null,
|
|
69454
|
+
access: "view",
|
|
69455
|
+
role: "viewer"
|
|
69456
|
+
},
|
|
69064
69457
|
"groupCommands.getStatus": {
|
|
69065
69458
|
capName: "group-commands",
|
|
69066
69459
|
capScope: "device",
|
|
@@ -70027,6 +70420,13 @@ Object.freeze({
|
|
|
70027
70420
|
access: "create",
|
|
70028
70421
|
role: "admin"
|
|
70029
70422
|
},
|
|
70423
|
+
"meter.getStatus": {
|
|
70424
|
+
capName: "meter",
|
|
70425
|
+
capScope: "device",
|
|
70426
|
+
addonId: null,
|
|
70427
|
+
access: "view",
|
|
70428
|
+
role: "viewer"
|
|
70429
|
+
},
|
|
70030
70430
|
"metricsProvider.collectSnapshot": {
|
|
70031
70431
|
capName: "metrics-provider",
|
|
70032
70432
|
capScope: "system",
|
|
@@ -78125,7 +78525,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
78125
78525
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
78126
78526
|
icon: "square"
|
|
78127
78527
|
}
|
|
78128
|
-
}
|
|
78528
|
+
},
|
|
78529
|
+
overrides: { byType: {
|
|
78530
|
+
[DeviceType.Washer]: {
|
|
78531
|
+
state: { running: {
|
|
78532
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
78533
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
78534
|
+
} },
|
|
78535
|
+
events: {
|
|
78536
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
78537
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
78538
|
+
}
|
|
78539
|
+
},
|
|
78540
|
+
[DeviceType.Dryer]: {
|
|
78541
|
+
state: { running: {
|
|
78542
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
78543
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
78544
|
+
} },
|
|
78545
|
+
events: {
|
|
78546
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
78547
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
78548
|
+
}
|
|
78549
|
+
},
|
|
78550
|
+
[DeviceType.Dishwasher]: {
|
|
78551
|
+
state: { running: {
|
|
78552
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
78553
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
78554
|
+
} },
|
|
78555
|
+
events: {
|
|
78556
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
78557
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
78558
|
+
}
|
|
78559
|
+
}
|
|
78560
|
+
} }
|
|
78129
78561
|
},
|
|
78130
78562
|
update: {
|
|
78131
78563
|
scope: "device",
|
|
@@ -78897,6 +79329,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78897
79329
|
icon: "flame"
|
|
78898
79330
|
}]
|
|
78899
79331
|
},
|
|
79332
|
+
"group-active": {
|
|
79333
|
+
scope: "device",
|
|
79334
|
+
noun: t("Group state", "Stato del gruppo")
|
|
79335
|
+
},
|
|
78900
79336
|
"group-commands": {
|
|
78901
79337
|
scope: "device",
|
|
78902
79338
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -78953,6 +79389,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78953
79389
|
}],
|
|
78954
79390
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
78955
79391
|
},
|
|
79392
|
+
meter: {
|
|
79393
|
+
scope: "device",
|
|
79394
|
+
noun: t("Meter", "Contatore"),
|
|
79395
|
+
state: [{
|
|
79396
|
+
kind: "numeric",
|
|
79397
|
+
field: "value",
|
|
79398
|
+
quantity: t("the total", "il totale"),
|
|
79399
|
+
label: t("Total", "Totale"),
|
|
79400
|
+
icon: "gauge"
|
|
79401
|
+
}]
|
|
79402
|
+
},
|
|
78956
79403
|
"numeric-sensor": {
|
|
78957
79404
|
scope: "device",
|
|
78958
79405
|
noun: t("Sensor", "Sensore"),
|
|
@@ -79425,8 +79872,47 @@ function projectAction(cap, action) {
|
|
|
79425
79872
|
};
|
|
79426
79873
|
}
|
|
79427
79874
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
79428
|
-
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;
|
|
79875
|
+
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;
|
|
79429
79876
|
DeviceFeature.BatteryOperated;
|
|
79877
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
79878
|
+
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.";
|
|
79879
|
+
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.";
|
|
79880
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
79881
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
79882
|
+
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.";
|
|
79883
|
+
function withheld(reason) {
|
|
79884
|
+
return {
|
|
79885
|
+
[DeviceType.Washer]: {
|
|
79886
|
+
exported: false,
|
|
79887
|
+
reason
|
|
79888
|
+
},
|
|
79889
|
+
[DeviceType.Dryer]: {
|
|
79890
|
+
exported: false,
|
|
79891
|
+
reason
|
|
79892
|
+
},
|
|
79893
|
+
[DeviceType.Dishwasher]: {
|
|
79894
|
+
exported: false,
|
|
79895
|
+
reason
|
|
79896
|
+
}
|
|
79897
|
+
};
|
|
79898
|
+
}
|
|
79899
|
+
function offered(received) {
|
|
79900
|
+
return {
|
|
79901
|
+
[DeviceType.Washer]: {
|
|
79902
|
+
exported: true,
|
|
79903
|
+
as: received
|
|
79904
|
+
},
|
|
79905
|
+
[DeviceType.Dryer]: {
|
|
79906
|
+
exported: true,
|
|
79907
|
+
as: received
|
|
79908
|
+
},
|
|
79909
|
+
[DeviceType.Dishwasher]: {
|
|
79910
|
+
exported: true,
|
|
79911
|
+
as: received
|
|
79912
|
+
}
|
|
79913
|
+
};
|
|
79914
|
+
}
|
|
79915
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
79430
79916
|
Object.freeze({
|
|
79431
79917
|
"accessories.getStatus": [{
|
|
79432
79918
|
name: "deviceId",
|
|
@@ -80393,6 +80879,11 @@ Object.freeze({
|
|
|
80393
80879
|
form: "single",
|
|
80394
80880
|
optional: false
|
|
80395
80881
|
}],
|
|
80882
|
+
"groupActive.getStatus": [{
|
|
80883
|
+
name: "deviceId",
|
|
80884
|
+
form: "single",
|
|
80885
|
+
optional: false
|
|
80886
|
+
}],
|
|
80396
80887
|
"groupCommands.getStatus": [{
|
|
80397
80888
|
name: "deviceId",
|
|
80398
80889
|
form: "single",
|
|
@@ -80603,6 +81094,11 @@ Object.freeze({
|
|
|
80603
81094
|
form: "single",
|
|
80604
81095
|
optional: false
|
|
80605
81096
|
}],
|
|
81097
|
+
"meter.getStatus": [{
|
|
81098
|
+
name: "deviceId",
|
|
81099
|
+
form: "single",
|
|
81100
|
+
optional: false
|
|
81101
|
+
}],
|
|
80606
81102
|
"motion.getStatus": [{
|
|
80607
81103
|
name: "deviceId",
|
|
80608
81104
|
form: "single",
|
|
@@ -82210,7 +82706,6 @@ Object.freeze({
|
|
|
82210
82706
|
"network-access": "ingress",
|
|
82211
82707
|
"smtp-provider": "email"
|
|
82212
82708
|
});
|
|
82213
|
-
DeviceType.Camera;
|
|
82214
82709
|
/**
|
|
82215
82710
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
82216
82711
|
* `z.infer`, they do not restate the shape.
|
|
@@ -84541,7 +85036,7 @@ function pickOauthRedirectOrigin(book) {
|
|
|
84541
85036
|
return book.roles.publicEndpoint.resolved ?? book.roles.internal.resolved ?? null;
|
|
84542
85037
|
}
|
|
84543
85038
|
var googleBrokersEntryKind = defineEntryKind("brokers", {
|
|
84544
|
-
title: "Google
|
|
85039
|
+
title: "Google brokers",
|
|
84545
85040
|
schema: entryBody({
|
|
84546
85041
|
clientId: GoogleBrokerEntrySchema.shape.clientId,
|
|
84547
85042
|
clientSecret: GoogleBrokerEntrySchema.shape.clientSecret,
|
|
@@ -84610,7 +85105,7 @@ var GoogleBrokerStore = class GoogleBrokerStore {
|
|
|
84610
85105
|
//#endregion
|
|
84611
85106
|
//#region src/google-services.addon.ts
|
|
84612
85107
|
/**
|
|
84613
|
-
* Google
|
|
85108
|
+
* Google — hub-only broker kind `google` + calendar-source + Gmail smtp.
|
|
84614
85109
|
* One OAuth account = one broker entry; feature caps aggregate connected brokers.
|
|
84615
85110
|
*/
|
|
84616
85111
|
var ADDON_ID = "google-services";
|