@camstack/addon-training 0.1.90 → 0.1.92
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/dist/{MotionZonesSettings-BmrNAOJO.mjs → MotionZonesSettings-Cli21_S4.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-BzPCdIdZ.mjs → PrivacyMaskSettings-BqMnLgR4.mjs} +2 -2
- package/dist/{SceneMonitorEditor-Xk84BCuE.mjs → SceneMonitorEditor-TOlMkkSx.mjs} +1 -1
- package/dist/_stub.js +18 -17
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-Bc9jWFjH.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-Ki3rRnXi.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-COkV6wxS.mjs +26 -0
- package/dist/{dist-BypcWIVo.mjs → dist-BLeIfxL-.mjs} +399 -40
- package/dist/{dist-CbnB8LuE.js → dist-BYGiAfO5.js} +399 -40
- package/dist/{hostInit-D4bIo0lR.mjs → hostInit-SSLNnzqp.mjs} +2 -2
- package/dist/index.js +1 -1
- package/dist/orchestrator/training.addon.js +1 -1
- package/dist/orchestrator/training.addon.mjs +1 -1
- package/dist/{player-overlays-CT4LlpcW.mjs → player-overlays-CpnLw8Tf.mjs} +1 -1
- package/dist/providers/modal/training-modal.addon.js +1 -1
- package/dist/providers/modal/training-modal.addon.mjs +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-Sb8JnuVU.mjs → responsive-wZ7jMF7F.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-Cxqt93xt.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-CG3LeBz1.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DZIdVQ_a.mjs +0 -26
|
@@ -5575,7 +5575,7 @@ var ZodIssueCode = {
|
|
|
5575
5575
|
var ZodFirstPartyTypeKind;
|
|
5576
5576
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5577
5577
|
//#endregion
|
|
5578
|
-
//#region ../types/dist/sleep
|
|
5578
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5579
5579
|
/**
|
|
5580
5580
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5581
5581
|
* window to float samples (D455).
|
|
@@ -8945,6 +8945,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8945
8945
|
"filesystem-browse",
|
|
8946
8946
|
"flood",
|
|
8947
8947
|
"gas",
|
|
8948
|
+
"group-active",
|
|
8948
8949
|
"group-commands",
|
|
8949
8950
|
"group-status",
|
|
8950
8951
|
"heating-valve",
|
|
@@ -8967,6 +8968,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8967
8968
|
"login-method",
|
|
8968
8969
|
"media-player",
|
|
8969
8970
|
"mesh-network",
|
|
8971
|
+
"meter",
|
|
8970
8972
|
"metrics-provider",
|
|
8971
8973
|
"model-convert",
|
|
8972
8974
|
"model-distributor",
|
|
@@ -9765,6 +9767,10 @@ Object.freeze({
|
|
|
9765
9767
|
"path": "detected",
|
|
9766
9768
|
"valueType": "boolean"
|
|
9767
9769
|
}],
|
|
9770
|
+
"group-active": [{
|
|
9771
|
+
"path": "active",
|
|
9772
|
+
"valueType": "boolean"
|
|
9773
|
+
}],
|
|
9768
9774
|
"group-status": [
|
|
9769
9775
|
{
|
|
9770
9776
|
"path": "included",
|
|
@@ -10024,6 +10030,10 @@ Object.freeze({
|
|
|
10024
10030
|
]
|
|
10025
10031
|
}
|
|
10026
10032
|
],
|
|
10033
|
+
"meter": [{
|
|
10034
|
+
"path": "value",
|
|
10035
|
+
"valueType": "number"
|
|
10036
|
+
}],
|
|
10027
10037
|
"motion": [
|
|
10028
10038
|
{
|
|
10029
10039
|
"path": "detected",
|
|
@@ -11116,7 +11126,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11116
11126
|
return DeviceRole;
|
|
11117
11127
|
}({});
|
|
11118
11128
|
//#endregion
|
|
11119
|
-
//#region ../types/dist/composition-
|
|
11129
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
11120
11130
|
/**
|
|
11121
11131
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11122
11132
|
*
|
|
@@ -11431,6 +11441,13 @@ var table = {
|
|
|
11431
11441
|
apply: () => {
|
|
11432
11442
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11433
11443
|
}
|
|
11444
|
+
},
|
|
11445
|
+
schmitt: {
|
|
11446
|
+
minArgs: 3,
|
|
11447
|
+
maxArgs: 5,
|
|
11448
|
+
apply: () => {
|
|
11449
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11450
|
+
}
|
|
11434
11451
|
}
|
|
11435
11452
|
};
|
|
11436
11453
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11892,6 +11909,79 @@ var APPLIANCE_KINDS = [
|
|
|
11892
11909
|
];
|
|
11893
11910
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11894
11911
|
/**
|
|
11912
|
+
* Statistics and integrals over a history read (D944).
|
|
11913
|
+
*
|
|
11914
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11915
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11916
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11917
|
+
* as zero. A truncated read is not published.
|
|
11918
|
+
*/
|
|
11919
|
+
var STATISTIC_STATS = [
|
|
11920
|
+
"min",
|
|
11921
|
+
"max",
|
|
11922
|
+
"mean",
|
|
11923
|
+
"sum",
|
|
11924
|
+
"count",
|
|
11925
|
+
"change"
|
|
11926
|
+
];
|
|
11927
|
+
/**
|
|
11928
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11929
|
+
*
|
|
11930
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11931
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11932
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11933
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11934
|
+
*/
|
|
11935
|
+
var MINUTE_MS = 6e4;
|
|
11936
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11937
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11938
|
+
var ROLLING_SPANS = [
|
|
11939
|
+
"1h",
|
|
11940
|
+
"24h",
|
|
11941
|
+
"2d",
|
|
11942
|
+
"7d",
|
|
11943
|
+
"30d",
|
|
11944
|
+
"custom"
|
|
11945
|
+
];
|
|
11946
|
+
var CALENDAR_PERIODS = [
|
|
11947
|
+
"today",
|
|
11948
|
+
"yesterday",
|
|
11949
|
+
"this-week",
|
|
11950
|
+
"this-month"
|
|
11951
|
+
];
|
|
11952
|
+
var RESET_PERIODS = [
|
|
11953
|
+
"never",
|
|
11954
|
+
"daily",
|
|
11955
|
+
"weekly",
|
|
11956
|
+
"monthly"
|
|
11957
|
+
];
|
|
11958
|
+
5 * MINUTE_MS;
|
|
11959
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11960
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11961
|
+
var rollingWindowObject = object({
|
|
11962
|
+
kind: literal("rolling"),
|
|
11963
|
+
span: _enum(ROLLING_SPANS),
|
|
11964
|
+
customMinutes: number().int().min(5).optional()
|
|
11965
|
+
}).check((payload) => {
|
|
11966
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11967
|
+
code: "custom",
|
|
11968
|
+
message: "a custom range needs a duration in minutes",
|
|
11969
|
+
path: ["customMinutes"],
|
|
11970
|
+
input: payload.value
|
|
11971
|
+
});
|
|
11972
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11973
|
+
code: "custom",
|
|
11974
|
+
message: "only a custom range carries a duration",
|
|
11975
|
+
path: ["customMinutes"],
|
|
11976
|
+
input: payload.value
|
|
11977
|
+
});
|
|
11978
|
+
});
|
|
11979
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
11980
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
11981
|
+
kind: literal("calendar"),
|
|
11982
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11983
|
+
})]);
|
|
11984
|
+
/**
|
|
11895
11985
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11896
11986
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11897
11987
|
* `composition.ts` (D659).
|
|
@@ -11917,7 +12007,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11917
12007
|
"occupancy",
|
|
11918
12008
|
"binary",
|
|
11919
12009
|
"switch",
|
|
11920
|
-
"light"
|
|
12010
|
+
"light",
|
|
12011
|
+
"fan",
|
|
12012
|
+
"cover",
|
|
12013
|
+
"valve",
|
|
12014
|
+
"lock",
|
|
12015
|
+
"media-player",
|
|
12016
|
+
"climate"
|
|
11921
12017
|
];
|
|
11922
12018
|
var NUMERIC_AGGREGATES = [
|
|
11923
12019
|
"mean",
|
|
@@ -11947,22 +12043,73 @@ var HelperMemberSchema = object({
|
|
|
11947
12043
|
cap: string().min(1),
|
|
11948
12044
|
fieldPath: string().min(1)
|
|
11949
12045
|
});
|
|
11950
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
11955
|
-
|
|
11956
|
-
|
|
11957
|
-
|
|
11958
|
-
|
|
11959
|
-
|
|
11960
|
-
|
|
11961
|
-
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
|
|
11965
|
-
|
|
12046
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12047
|
+
object({
|
|
12048
|
+
kind: literal("group"),
|
|
12049
|
+
templateId: GroupTemplateIdSchema,
|
|
12050
|
+
aggregate: AggregateReducerSchema,
|
|
12051
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
12052
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
12053
|
+
active: ActiveCriterionSchema.optional()
|
|
12054
|
+
}),
|
|
12055
|
+
object({
|
|
12056
|
+
kind: literal("appliance"),
|
|
12057
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
12058
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
12059
|
+
thresholdWatts: number().positive(),
|
|
12060
|
+
startDwellMs: number().int().nonnegative(),
|
|
12061
|
+
stopDwellMs: number().int().nonnegative(),
|
|
12062
|
+
member: HelperMemberSchema
|
|
12063
|
+
}),
|
|
12064
|
+
object({
|
|
12065
|
+
kind: literal("statistic"),
|
|
12066
|
+
stat: _enum(STATISTIC_STATS),
|
|
12067
|
+
window: StatisticWindowSchema,
|
|
12068
|
+
source: HelperMemberSchema
|
|
12069
|
+
}),
|
|
12070
|
+
object({
|
|
12071
|
+
kind: literal("integral"),
|
|
12072
|
+
reset: _enum(RESET_PERIODS),
|
|
12073
|
+
output: _enum(["energy", "meter"]),
|
|
12074
|
+
source: HelperMemberSchema
|
|
12075
|
+
}),
|
|
12076
|
+
object({
|
|
12077
|
+
kind: literal("threshold"),
|
|
12078
|
+
source: HelperMemberSchema,
|
|
12079
|
+
high: number(),
|
|
12080
|
+
low: number(),
|
|
12081
|
+
onForMs: number().int().nonnegative(),
|
|
12082
|
+
offForMs: number().int().nonnegative()
|
|
12083
|
+
}),
|
|
12084
|
+
object({
|
|
12085
|
+
kind: literal("arithmetic"),
|
|
12086
|
+
op: _enum([
|
|
12087
|
+
"sum",
|
|
12088
|
+
"difference",
|
|
12089
|
+
"ratio"
|
|
12090
|
+
]),
|
|
12091
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
12092
|
+
}),
|
|
12093
|
+
object({
|
|
12094
|
+
kind: literal("expression"),
|
|
12095
|
+
expr: string().min(1),
|
|
12096
|
+
inputs: array(object({
|
|
12097
|
+
name: string().min(1),
|
|
12098
|
+
member: HelperMemberSchema
|
|
12099
|
+
})).min(1).max(64),
|
|
12100
|
+
output: _enum(["number", "boolean"])
|
|
12101
|
+
}),
|
|
12102
|
+
object({
|
|
12103
|
+
kind: literal("derivative"),
|
|
12104
|
+
window: RollingWindowSchema,
|
|
12105
|
+
per: _enum([
|
|
12106
|
+
"second",
|
|
12107
|
+
"minute",
|
|
12108
|
+
"hour"
|
|
12109
|
+
]),
|
|
12110
|
+
source: HelperMemberSchema
|
|
12111
|
+
})
|
|
12112
|
+
]);
|
|
11966
12113
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11967
12114
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11968
12115
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -12023,6 +12170,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12023
12170
|
"all"
|
|
12024
12171
|
]),
|
|
12025
12172
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12173
|
+
/**
|
|
12174
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
12175
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
12176
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
12177
|
+
*/
|
|
12178
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
12026
12179
|
/** `value` is the reading; the others are the member counts. */
|
|
12027
12180
|
publish: _enum([
|
|
12028
12181
|
"value",
|
|
@@ -12036,6 +12189,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12036
12189
|
"omit",
|
|
12037
12190
|
"offline"
|
|
12038
12191
|
])
|
|
12192
|
+
}),
|
|
12193
|
+
object({
|
|
12194
|
+
kind: literal("series"),
|
|
12195
|
+
read: CompositionFieldReadSchema,
|
|
12196
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
12197
|
+
publish: _enum([
|
|
12198
|
+
"value",
|
|
12199
|
+
"included",
|
|
12200
|
+
"excluded",
|
|
12201
|
+
"total"
|
|
12202
|
+
]),
|
|
12203
|
+
/**
|
|
12204
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12205
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12206
|
+
*/
|
|
12207
|
+
empty: _enum([
|
|
12208
|
+
"null",
|
|
12209
|
+
"omit",
|
|
12210
|
+
"offline"
|
|
12211
|
+
])
|
|
12039
12212
|
})
|
|
12040
12213
|
]);
|
|
12041
12214
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -18229,7 +18402,8 @@ var CompositionProblemSchema = object({
|
|
|
18229
18402
|
"native-capability-replace",
|
|
18230
18403
|
"mixed-quantity",
|
|
18231
18404
|
"helper-mismatch",
|
|
18232
|
-
"member-constraint"
|
|
18405
|
+
"member-constraint",
|
|
18406
|
+
"retention"
|
|
18233
18407
|
]),
|
|
18234
18408
|
path: string(),
|
|
18235
18409
|
message: string()
|
|
@@ -18463,13 +18637,17 @@ Object.freeze({
|
|
|
18463
18637
|
latchedAt: {
|
|
18464
18638
|
kind: "fixed",
|
|
18465
18639
|
result: ["number", "null"]
|
|
18640
|
+
},
|
|
18641
|
+
schmitt: {
|
|
18642
|
+
kind: "fixed",
|
|
18643
|
+
result: ["boolean", "null"]
|
|
18466
18644
|
}
|
|
18467
18645
|
});
|
|
18468
18646
|
/**
|
|
18469
18647
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18470
18648
|
* Data, not a form default written into the block.
|
|
18471
18649
|
*/
|
|
18472
|
-
var NOW = {
|
|
18650
|
+
var NOW$2 = {
|
|
18473
18651
|
fieldPath: "lastFetchedAt",
|
|
18474
18652
|
expr: "now"
|
|
18475
18653
|
};
|
|
@@ -18483,6 +18661,8 @@ function numeric(input) {
|
|
|
18483
18661
|
family: "numeric",
|
|
18484
18662
|
deviceType: DeviceType.Sensor,
|
|
18485
18663
|
memberDeviceType: DeviceType.Sensor,
|
|
18664
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18665
|
+
activeWhen: void 0,
|
|
18486
18666
|
commandCaps: [],
|
|
18487
18667
|
baseUnit: baseUnitOf(input.quantity),
|
|
18488
18668
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18498,6 +18678,8 @@ function binary(input) {
|
|
|
18498
18678
|
family: "binary",
|
|
18499
18679
|
deviceType: DeviceType.Sensor,
|
|
18500
18680
|
memberDeviceType: DeviceType.Sensor,
|
|
18681
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18682
|
+
activeWhen: void 0,
|
|
18501
18683
|
commandCaps: [],
|
|
18502
18684
|
quantity: "none",
|
|
18503
18685
|
baseUnit: void 0,
|
|
@@ -18515,7 +18697,7 @@ var GROUP_TEMPLATES = [
|
|
|
18515
18697
|
quantity: "temperature",
|
|
18516
18698
|
defaultAggregate: "mean",
|
|
18517
18699
|
empty: "null",
|
|
18518
|
-
companions: [NOW]
|
|
18700
|
+
companions: [NOW$2]
|
|
18519
18701
|
}),
|
|
18520
18702
|
numeric({
|
|
18521
18703
|
id: "humidity",
|
|
@@ -18526,7 +18708,7 @@ var GROUP_TEMPLATES = [
|
|
|
18526
18708
|
quantity: "humidity",
|
|
18527
18709
|
defaultAggregate: "mean",
|
|
18528
18710
|
empty: "null",
|
|
18529
|
-
companions: [NOW]
|
|
18711
|
+
companions: [NOW$2]
|
|
18530
18712
|
}),
|
|
18531
18713
|
numeric({
|
|
18532
18714
|
id: "pressure",
|
|
@@ -18537,7 +18719,7 @@ var GROUP_TEMPLATES = [
|
|
|
18537
18719
|
quantity: "pressure",
|
|
18538
18720
|
defaultAggregate: "mean",
|
|
18539
18721
|
empty: "null",
|
|
18540
|
-
companions: [NOW]
|
|
18722
|
+
companions: [NOW$2]
|
|
18541
18723
|
}),
|
|
18542
18724
|
numeric({
|
|
18543
18725
|
id: "illuminance",
|
|
@@ -18548,7 +18730,7 @@ var GROUP_TEMPLATES = [
|
|
|
18548
18730
|
quantity: "illuminance",
|
|
18549
18731
|
defaultAggregate: "mean",
|
|
18550
18732
|
empty: "null",
|
|
18551
|
-
companions: [NOW]
|
|
18733
|
+
companions: [NOW$2]
|
|
18552
18734
|
}),
|
|
18553
18735
|
numeric({
|
|
18554
18736
|
id: "power",
|
|
@@ -18559,7 +18741,7 @@ var GROUP_TEMPLATES = [
|
|
|
18559
18741
|
quantity: "power",
|
|
18560
18742
|
defaultAggregate: "sum",
|
|
18561
18743
|
empty: "omit",
|
|
18562
|
-
companions: [NOW]
|
|
18744
|
+
companions: [NOW$2]
|
|
18563
18745
|
}),
|
|
18564
18746
|
numeric({
|
|
18565
18747
|
id: "energy",
|
|
@@ -18570,7 +18752,7 @@ var GROUP_TEMPLATES = [
|
|
|
18570
18752
|
quantity: "energy",
|
|
18571
18753
|
defaultAggregate: "sum",
|
|
18572
18754
|
empty: "omit",
|
|
18573
|
-
companions: [NOW]
|
|
18755
|
+
companions: [NOW$2]
|
|
18574
18756
|
}),
|
|
18575
18757
|
numeric({
|
|
18576
18758
|
id: "battery",
|
|
@@ -18605,7 +18787,7 @@ var GROUP_TEMPLATES = [
|
|
|
18605
18787
|
quantity: "device",
|
|
18606
18788
|
defaultAggregate: "mean",
|
|
18607
18789
|
empty: "null",
|
|
18608
|
-
companions: [NOW]
|
|
18790
|
+
companions: [NOW$2]
|
|
18609
18791
|
}),
|
|
18610
18792
|
binary({
|
|
18611
18793
|
id: "motion",
|
|
@@ -18699,6 +18881,11 @@ var GROUP_TEMPLATES = [
|
|
|
18699
18881
|
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.",
|
|
18700
18882
|
deviceType: DeviceType.Switch,
|
|
18701
18883
|
outputCap: "switch",
|
|
18884
|
+
outputField: "on",
|
|
18885
|
+
member: {
|
|
18886
|
+
cap: "switch",
|
|
18887
|
+
fieldPath: "on"
|
|
18888
|
+
},
|
|
18702
18889
|
commandCaps: ["switch"]
|
|
18703
18890
|
}),
|
|
18704
18891
|
actuator({
|
|
@@ -18706,34 +18893,136 @@ var GROUP_TEMPLATES = [
|
|
|
18706
18893
|
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.",
|
|
18707
18894
|
deviceType: DeviceType.Light,
|
|
18708
18895
|
outputCap: "switch",
|
|
18896
|
+
outputField: "on",
|
|
18897
|
+
member: {
|
|
18898
|
+
cap: "switch",
|
|
18899
|
+
fieldPath: "on"
|
|
18900
|
+
},
|
|
18709
18901
|
commandCaps: [
|
|
18710
18902
|
"switch",
|
|
18711
18903
|
"brightness",
|
|
18712
18904
|
"color"
|
|
18713
18905
|
]
|
|
18906
|
+
}),
|
|
18907
|
+
actuator({
|
|
18908
|
+
id: "fan",
|
|
18909
|
+
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.",
|
|
18910
|
+
deviceType: DeviceType.Fan,
|
|
18911
|
+
outputCap: "switch",
|
|
18912
|
+
outputField: "on",
|
|
18913
|
+
member: {
|
|
18914
|
+
cap: "switch",
|
|
18915
|
+
fieldPath: "on"
|
|
18916
|
+
},
|
|
18917
|
+
commandCaps: ["switch", "fan-control"]
|
|
18918
|
+
}),
|
|
18919
|
+
actuator({
|
|
18920
|
+
id: "cover",
|
|
18921
|
+
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.",
|
|
18922
|
+
deviceType: DeviceType.Cover,
|
|
18923
|
+
outputCap: "group-active",
|
|
18924
|
+
outputField: "active",
|
|
18925
|
+
member: {
|
|
18926
|
+
cap: "cover",
|
|
18927
|
+
fieldPath: "state"
|
|
18928
|
+
},
|
|
18929
|
+
activeWhen: [
|
|
18930
|
+
"open",
|
|
18931
|
+
"opening",
|
|
18932
|
+
"stopped"
|
|
18933
|
+
],
|
|
18934
|
+
commandCaps: ["cover"]
|
|
18935
|
+
}),
|
|
18936
|
+
actuator({
|
|
18937
|
+
id: "valve",
|
|
18938
|
+
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.",
|
|
18939
|
+
deviceType: DeviceType.Valve,
|
|
18940
|
+
outputCap: "group-active",
|
|
18941
|
+
outputField: "active",
|
|
18942
|
+
member: {
|
|
18943
|
+
cap: "valve",
|
|
18944
|
+
fieldPath: "state"
|
|
18945
|
+
},
|
|
18946
|
+
activeWhen: [
|
|
18947
|
+
"open",
|
|
18948
|
+
"opening",
|
|
18949
|
+
"stopped"
|
|
18950
|
+
],
|
|
18951
|
+
commandCaps: ["valve"]
|
|
18952
|
+
}),
|
|
18953
|
+
actuator({
|
|
18954
|
+
id: "lock",
|
|
18955
|
+
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.",
|
|
18956
|
+
deviceType: DeviceType.Lock,
|
|
18957
|
+
outputCap: "group-active",
|
|
18958
|
+
outputField: "active",
|
|
18959
|
+
member: {
|
|
18960
|
+
cap: "lock-control",
|
|
18961
|
+
fieldPath: "state"
|
|
18962
|
+
},
|
|
18963
|
+
activeWhen: ["locked"],
|
|
18964
|
+
commandCaps: ["lock-control"]
|
|
18965
|
+
}),
|
|
18966
|
+
actuator({
|
|
18967
|
+
id: "media-player",
|
|
18968
|
+
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.",
|
|
18969
|
+
deviceType: DeviceType.MediaPlayer,
|
|
18970
|
+
outputCap: "group-active",
|
|
18971
|
+
outputField: "active",
|
|
18972
|
+
member: {
|
|
18973
|
+
cap: "media-player",
|
|
18974
|
+
fieldPath: "state"
|
|
18975
|
+
},
|
|
18976
|
+
activeWhen: ["playing", "buffering"],
|
|
18977
|
+
commandCaps: ["media-player"]
|
|
18978
|
+
}),
|
|
18979
|
+
actuator({
|
|
18980
|
+
id: "climate",
|
|
18981
|
+
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.",
|
|
18982
|
+
deviceType: DeviceType.Thermostat,
|
|
18983
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
18984
|
+
outputCap: "group-active",
|
|
18985
|
+
outputField: "active",
|
|
18986
|
+
member: {
|
|
18987
|
+
cap: "climate-control",
|
|
18988
|
+
fieldPath: "mode"
|
|
18989
|
+
},
|
|
18990
|
+
activeWhen: [
|
|
18991
|
+
"heat",
|
|
18992
|
+
"cool",
|
|
18993
|
+
"auto",
|
|
18994
|
+
"heat_cool",
|
|
18995
|
+
"fan_only",
|
|
18996
|
+
"dry"
|
|
18997
|
+
],
|
|
18998
|
+
commandCaps: ["climate-control"]
|
|
18714
18999
|
})
|
|
18715
19000
|
];
|
|
18716
19001
|
function actuator(input) {
|
|
18717
19002
|
return {
|
|
18718
|
-
|
|
19003
|
+
id: input.id,
|
|
19004
|
+
summary: input.summary,
|
|
19005
|
+
deviceType: input.deviceType,
|
|
19006
|
+
outputCap: input.outputCap,
|
|
19007
|
+
outputField: input.outputField,
|
|
19008
|
+
commandCaps: input.commandCaps,
|
|
18719
19009
|
family: "actuator",
|
|
18720
19010
|
role: void 0,
|
|
18721
19011
|
memberDeviceType: input.deviceType,
|
|
18722
|
-
|
|
19012
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
19013
|
+
activeWhen: input.activeWhen,
|
|
18723
19014
|
quantity: "none",
|
|
18724
19015
|
baseUnit: void 0,
|
|
18725
19016
|
aggregates: BINARY_AGGREGATES,
|
|
18726
19017
|
defaultAggregate: "any",
|
|
18727
19018
|
empty: "offline",
|
|
18728
|
-
accept: [
|
|
18729
|
-
cap: "switch",
|
|
18730
|
-
fieldPath: "on"
|
|
18731
|
-
}],
|
|
19019
|
+
accept: [input.member],
|
|
18732
19020
|
companions: [CHANGED]
|
|
18733
19021
|
};
|
|
18734
19022
|
}
|
|
18735
19023
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18736
19024
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
19025
|
+
DeviceType.Camera;
|
|
18737
19026
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18738
19027
|
/**
|
|
18739
19028
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -46391,7 +46680,20 @@ var NcRuleInputSchema = object({
|
|
|
46391
46680
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
46392
46681
|
* path does not run Zod defaults.
|
|
46393
46682
|
*/
|
|
46394
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46683
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46684
|
+
/**
|
|
46685
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46686
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46687
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46688
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46689
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46690
|
+
*
|
|
46691
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46692
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46693
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46694
|
+
* `false`, so it needs no `clear` key.
|
|
46695
|
+
*/
|
|
46696
|
+
askVerdict: boolean().optional()
|
|
46395
46697
|
});
|
|
46396
46698
|
/**
|
|
46397
46699
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -58592,7 +58894,13 @@ results: array(object({
|
|
|
58592
58894
|
/** Ms epoch of the attempt. */
|
|
58593
58895
|
at: number()
|
|
58594
58896
|
})) });
|
|
58595
|
-
DeviceType.Switch, DeviceType.Light;
|
|
58897
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58898
|
+
object({
|
|
58899
|
+
active: boolean().meta({ label: "Active" }),
|
|
58900
|
+
/** Ms epoch when the slice was last updated. */
|
|
58901
|
+
lastChangedAt: number()
|
|
58902
|
+
});
|
|
58903
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
58596
58904
|
object({
|
|
58597
58905
|
/** Members whose current value entered the aggregate. */
|
|
58598
58906
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -58610,7 +58918,7 @@ object({
|
|
|
58610
58918
|
label: "Members"
|
|
58611
58919
|
}))
|
|
58612
58920
|
});
|
|
58613
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58921
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58614
58922
|
object({
|
|
58615
58923
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58616
58924
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -59517,7 +59825,14 @@ DeviceType.Lock, method(object({
|
|
|
59517
59825
|
auth: "protected"
|
|
59518
59826
|
}), method(object({
|
|
59519
59827
|
deviceId: number().int().nonnegative(),
|
|
59520
|
-
code: string().min(1).optional()
|
|
59828
|
+
code: string().min(1).optional(),
|
|
59829
|
+
/**
|
|
59830
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
59831
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
59832
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
59833
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
59834
|
+
*/
|
|
59835
|
+
confirm: boolean().optional()
|
|
59521
59836
|
}), _void(), {
|
|
59522
59837
|
kind: "mutation",
|
|
59523
59838
|
auth: "protected"
|
|
@@ -59525,6 +59840,11 @@ DeviceType.Lock, method(object({
|
|
|
59525
59840
|
kind: "mutation",
|
|
59526
59841
|
auth: "protected"
|
|
59527
59842
|
});
|
|
59843
|
+
object({
|
|
59844
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
59845
|
+
lastFetchedAt: number()
|
|
59846
|
+
});
|
|
59847
|
+
DeviceType.Sensor;
|
|
59528
59848
|
/**
|
|
59529
59849
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
59530
59850
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -63928,7 +64248,7 @@ object({
|
|
|
63928
64248
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
63929
64249
|
lastChangedAt: number()
|
|
63930
64250
|
});
|
|
63931
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
64251
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
63932
64252
|
deviceId: number(),
|
|
63933
64253
|
on: boolean()
|
|
63934
64254
|
}), _void(), {
|
|
@@ -65722,6 +66042,7 @@ var trainingCapability = {
|
|
|
65722
66042
|
})
|
|
65723
66043
|
}
|
|
65724
66044
|
};
|
|
66045
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
65725
66046
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
65726
66047
|
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.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
65727
66048
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
@@ -68999,6 +69320,13 @@ Object.freeze({
|
|
|
68999
69320
|
access: "view",
|
|
69000
69321
|
role: "viewer"
|
|
69001
69322
|
},
|
|
69323
|
+
"groupActive.getStatus": {
|
|
69324
|
+
capName: "group-active",
|
|
69325
|
+
capScope: "device",
|
|
69326
|
+
addonId: null,
|
|
69327
|
+
access: "view",
|
|
69328
|
+
role: "viewer"
|
|
69329
|
+
},
|
|
69002
69330
|
"groupCommands.getStatus": {
|
|
69003
69331
|
capName: "group-commands",
|
|
69004
69332
|
capScope: "device",
|
|
@@ -69965,6 +70293,13 @@ Object.freeze({
|
|
|
69965
70293
|
access: "create",
|
|
69966
70294
|
role: "admin"
|
|
69967
70295
|
},
|
|
70296
|
+
"meter.getStatus": {
|
|
70297
|
+
capName: "meter",
|
|
70298
|
+
capScope: "device",
|
|
70299
|
+
addonId: null,
|
|
70300
|
+
access: "view",
|
|
70301
|
+
role: "viewer"
|
|
70302
|
+
},
|
|
69968
70303
|
"metricsProvider.collectSnapshot": {
|
|
69969
70304
|
capName: "metrics-provider",
|
|
69970
70305
|
capScope: "system",
|
|
@@ -78867,6 +79202,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78867
79202
|
icon: "flame"
|
|
78868
79203
|
}]
|
|
78869
79204
|
},
|
|
79205
|
+
"group-active": {
|
|
79206
|
+
scope: "device",
|
|
79207
|
+
noun: t("Group state", "Stato del gruppo")
|
|
79208
|
+
},
|
|
78870
79209
|
"group-commands": {
|
|
78871
79210
|
scope: "device",
|
|
78872
79211
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -78923,6 +79262,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78923
79262
|
}],
|
|
78924
79263
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
78925
79264
|
},
|
|
79265
|
+
meter: {
|
|
79266
|
+
scope: "device",
|
|
79267
|
+
noun: t("Meter", "Contatore"),
|
|
79268
|
+
state: [{
|
|
79269
|
+
kind: "numeric",
|
|
79270
|
+
field: "value",
|
|
79271
|
+
quantity: t("the total", "il totale"),
|
|
79272
|
+
label: t("Total", "Totale"),
|
|
79273
|
+
icon: "gauge"
|
|
79274
|
+
}]
|
|
79275
|
+
},
|
|
78926
79276
|
"numeric-sensor": {
|
|
78927
79277
|
scope: "device",
|
|
78928
79278
|
noun: t("Sensor", "Sensore"),
|
|
@@ -80402,6 +80752,11 @@ Object.freeze({
|
|
|
80402
80752
|
form: "single",
|
|
80403
80753
|
optional: false
|
|
80404
80754
|
}],
|
|
80755
|
+
"groupActive.getStatus": [{
|
|
80756
|
+
name: "deviceId",
|
|
80757
|
+
form: "single",
|
|
80758
|
+
optional: false
|
|
80759
|
+
}],
|
|
80405
80760
|
"groupCommands.getStatus": [{
|
|
80406
80761
|
name: "deviceId",
|
|
80407
80762
|
form: "single",
|
|
@@ -80612,6 +80967,11 @@ Object.freeze({
|
|
|
80612
80967
|
form: "single",
|
|
80613
80968
|
optional: false
|
|
80614
80969
|
}],
|
|
80970
|
+
"meter.getStatus": [{
|
|
80971
|
+
name: "deviceId",
|
|
80972
|
+
form: "single",
|
|
80973
|
+
optional: false
|
|
80974
|
+
}],
|
|
80615
80975
|
"motion.getStatus": [{
|
|
80616
80976
|
name: "deviceId",
|
|
80617
80977
|
form: "single",
|
|
@@ -82219,7 +82579,6 @@ Object.freeze({
|
|
|
82219
82579
|
"network-access": "ingress",
|
|
82220
82580
|
"smtp-provider": "email"
|
|
82221
82581
|
});
|
|
82222
|
-
DeviceType.Camera;
|
|
82223
82582
|
/**
|
|
82224
82583
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
82225
82584
|
* `z.infer`, they do not restate the shape.
|