@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
|
@@ -5608,7 +5608,7 @@ var ZodIssueCode = {
|
|
|
5608
5608
|
var ZodFirstPartyTypeKind;
|
|
5609
5609
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5610
5610
|
//#endregion
|
|
5611
|
-
//#region ../types/dist/sleep
|
|
5611
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5612
5612
|
/**
|
|
5613
5613
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5614
5614
|
* window to float samples (D455).
|
|
@@ -8978,6 +8978,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8978
8978
|
"filesystem-browse",
|
|
8979
8979
|
"flood",
|
|
8980
8980
|
"gas",
|
|
8981
|
+
"group-active",
|
|
8981
8982
|
"group-commands",
|
|
8982
8983
|
"group-status",
|
|
8983
8984
|
"heating-valve",
|
|
@@ -9000,6 +9001,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9000
9001
|
"login-method",
|
|
9001
9002
|
"media-player",
|
|
9002
9003
|
"mesh-network",
|
|
9004
|
+
"meter",
|
|
9003
9005
|
"metrics-provider",
|
|
9004
9006
|
"model-convert",
|
|
9005
9007
|
"model-distributor",
|
|
@@ -9798,6 +9800,10 @@ Object.freeze({
|
|
|
9798
9800
|
"path": "detected",
|
|
9799
9801
|
"valueType": "boolean"
|
|
9800
9802
|
}],
|
|
9803
|
+
"group-active": [{
|
|
9804
|
+
"path": "active",
|
|
9805
|
+
"valueType": "boolean"
|
|
9806
|
+
}],
|
|
9801
9807
|
"group-status": [
|
|
9802
9808
|
{
|
|
9803
9809
|
"path": "included",
|
|
@@ -10057,6 +10063,10 @@ Object.freeze({
|
|
|
10057
10063
|
]
|
|
10058
10064
|
}
|
|
10059
10065
|
],
|
|
10066
|
+
"meter": [{
|
|
10067
|
+
"path": "value",
|
|
10068
|
+
"valueType": "number"
|
|
10069
|
+
}],
|
|
10060
10070
|
"motion": [
|
|
10061
10071
|
{
|
|
10062
10072
|
"path": "detected",
|
|
@@ -11149,7 +11159,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11149
11159
|
return DeviceRole;
|
|
11150
11160
|
}({});
|
|
11151
11161
|
//#endregion
|
|
11152
|
-
//#region ../types/dist/composition-
|
|
11162
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
11153
11163
|
/**
|
|
11154
11164
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11155
11165
|
*
|
|
@@ -11464,6 +11474,13 @@ var table = {
|
|
|
11464
11474
|
apply: () => {
|
|
11465
11475
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11466
11476
|
}
|
|
11477
|
+
},
|
|
11478
|
+
schmitt: {
|
|
11479
|
+
minArgs: 3,
|
|
11480
|
+
maxArgs: 5,
|
|
11481
|
+
apply: () => {
|
|
11482
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11483
|
+
}
|
|
11467
11484
|
}
|
|
11468
11485
|
};
|
|
11469
11486
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11925,6 +11942,79 @@ var APPLIANCE_KINDS = [
|
|
|
11925
11942
|
];
|
|
11926
11943
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11927
11944
|
/**
|
|
11945
|
+
* Statistics and integrals over a history read (D944).
|
|
11946
|
+
*
|
|
11947
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11948
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11949
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11950
|
+
* as zero. A truncated read is not published.
|
|
11951
|
+
*/
|
|
11952
|
+
var STATISTIC_STATS = [
|
|
11953
|
+
"min",
|
|
11954
|
+
"max",
|
|
11955
|
+
"mean",
|
|
11956
|
+
"sum",
|
|
11957
|
+
"count",
|
|
11958
|
+
"change"
|
|
11959
|
+
];
|
|
11960
|
+
/**
|
|
11961
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11962
|
+
*
|
|
11963
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11964
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11965
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11966
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11967
|
+
*/
|
|
11968
|
+
var MINUTE_MS = 6e4;
|
|
11969
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11970
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11971
|
+
var ROLLING_SPANS = [
|
|
11972
|
+
"1h",
|
|
11973
|
+
"24h",
|
|
11974
|
+
"2d",
|
|
11975
|
+
"7d",
|
|
11976
|
+
"30d",
|
|
11977
|
+
"custom"
|
|
11978
|
+
];
|
|
11979
|
+
var CALENDAR_PERIODS = [
|
|
11980
|
+
"today",
|
|
11981
|
+
"yesterday",
|
|
11982
|
+
"this-week",
|
|
11983
|
+
"this-month"
|
|
11984
|
+
];
|
|
11985
|
+
var RESET_PERIODS = [
|
|
11986
|
+
"never",
|
|
11987
|
+
"daily",
|
|
11988
|
+
"weekly",
|
|
11989
|
+
"monthly"
|
|
11990
|
+
];
|
|
11991
|
+
5 * MINUTE_MS;
|
|
11992
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11993
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11994
|
+
var rollingWindowObject = object({
|
|
11995
|
+
kind: literal("rolling"),
|
|
11996
|
+
span: _enum(ROLLING_SPANS),
|
|
11997
|
+
customMinutes: number().int().min(5).optional()
|
|
11998
|
+
}).check((payload) => {
|
|
11999
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
12000
|
+
code: "custom",
|
|
12001
|
+
message: "a custom range needs a duration in minutes",
|
|
12002
|
+
path: ["customMinutes"],
|
|
12003
|
+
input: payload.value
|
|
12004
|
+
});
|
|
12005
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
12006
|
+
code: "custom",
|
|
12007
|
+
message: "only a custom range carries a duration",
|
|
12008
|
+
path: ["customMinutes"],
|
|
12009
|
+
input: payload.value
|
|
12010
|
+
});
|
|
12011
|
+
});
|
|
12012
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
12013
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
12014
|
+
kind: literal("calendar"),
|
|
12015
|
+
period: _enum(CALENDAR_PERIODS)
|
|
12016
|
+
})]);
|
|
12017
|
+
/**
|
|
11928
12018
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11929
12019
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11930
12020
|
* `composition.ts` (D659).
|
|
@@ -11950,7 +12040,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11950
12040
|
"occupancy",
|
|
11951
12041
|
"binary",
|
|
11952
12042
|
"switch",
|
|
11953
|
-
"light"
|
|
12043
|
+
"light",
|
|
12044
|
+
"fan",
|
|
12045
|
+
"cover",
|
|
12046
|
+
"valve",
|
|
12047
|
+
"lock",
|
|
12048
|
+
"media-player",
|
|
12049
|
+
"climate"
|
|
11954
12050
|
];
|
|
11955
12051
|
var NUMERIC_AGGREGATES = [
|
|
11956
12052
|
"mean",
|
|
@@ -11980,22 +12076,73 @@ var HelperMemberSchema = object({
|
|
|
11980
12076
|
cap: string().min(1),
|
|
11981
12077
|
fieldPath: string().min(1)
|
|
11982
12078
|
});
|
|
11983
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11984
|
-
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
11988
|
-
|
|
11989
|
-
|
|
11990
|
-
|
|
11991
|
-
|
|
11992
|
-
|
|
11993
|
-
|
|
11994
|
-
|
|
11995
|
-
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
|
|
12079
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12080
|
+
object({
|
|
12081
|
+
kind: literal("group"),
|
|
12082
|
+
templateId: GroupTemplateIdSchema,
|
|
12083
|
+
aggregate: AggregateReducerSchema,
|
|
12084
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
12085
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
12086
|
+
active: ActiveCriterionSchema.optional()
|
|
12087
|
+
}),
|
|
12088
|
+
object({
|
|
12089
|
+
kind: literal("appliance"),
|
|
12090
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
12091
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
12092
|
+
thresholdWatts: number().positive(),
|
|
12093
|
+
startDwellMs: number().int().nonnegative(),
|
|
12094
|
+
stopDwellMs: number().int().nonnegative(),
|
|
12095
|
+
member: HelperMemberSchema
|
|
12096
|
+
}),
|
|
12097
|
+
object({
|
|
12098
|
+
kind: literal("statistic"),
|
|
12099
|
+
stat: _enum(STATISTIC_STATS),
|
|
12100
|
+
window: StatisticWindowSchema,
|
|
12101
|
+
source: HelperMemberSchema
|
|
12102
|
+
}),
|
|
12103
|
+
object({
|
|
12104
|
+
kind: literal("integral"),
|
|
12105
|
+
reset: _enum(RESET_PERIODS),
|
|
12106
|
+
output: _enum(["energy", "meter"]),
|
|
12107
|
+
source: HelperMemberSchema
|
|
12108
|
+
}),
|
|
12109
|
+
object({
|
|
12110
|
+
kind: literal("threshold"),
|
|
12111
|
+
source: HelperMemberSchema,
|
|
12112
|
+
high: number(),
|
|
12113
|
+
low: number(),
|
|
12114
|
+
onForMs: number().int().nonnegative(),
|
|
12115
|
+
offForMs: number().int().nonnegative()
|
|
12116
|
+
}),
|
|
12117
|
+
object({
|
|
12118
|
+
kind: literal("arithmetic"),
|
|
12119
|
+
op: _enum([
|
|
12120
|
+
"sum",
|
|
12121
|
+
"difference",
|
|
12122
|
+
"ratio"
|
|
12123
|
+
]),
|
|
12124
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
12125
|
+
}),
|
|
12126
|
+
object({
|
|
12127
|
+
kind: literal("expression"),
|
|
12128
|
+
expr: string().min(1),
|
|
12129
|
+
inputs: array(object({
|
|
12130
|
+
name: string().min(1),
|
|
12131
|
+
member: HelperMemberSchema
|
|
12132
|
+
})).min(1).max(64),
|
|
12133
|
+
output: _enum(["number", "boolean"])
|
|
12134
|
+
}),
|
|
12135
|
+
object({
|
|
12136
|
+
kind: literal("derivative"),
|
|
12137
|
+
window: RollingWindowSchema,
|
|
12138
|
+
per: _enum([
|
|
12139
|
+
"second",
|
|
12140
|
+
"minute",
|
|
12141
|
+
"hour"
|
|
12142
|
+
]),
|
|
12143
|
+
source: HelperMemberSchema
|
|
12144
|
+
})
|
|
12145
|
+
]);
|
|
11999
12146
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
12000
12147
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
12001
12148
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -12056,6 +12203,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12056
12203
|
"all"
|
|
12057
12204
|
]),
|
|
12058
12205
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12206
|
+
/**
|
|
12207
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
12208
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
12209
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
12210
|
+
*/
|
|
12211
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
12059
12212
|
/** `value` is the reading; the others are the member counts. */
|
|
12060
12213
|
publish: _enum([
|
|
12061
12214
|
"value",
|
|
@@ -12069,6 +12222,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12069
12222
|
"omit",
|
|
12070
12223
|
"offline"
|
|
12071
12224
|
])
|
|
12225
|
+
}),
|
|
12226
|
+
object({
|
|
12227
|
+
kind: literal("series"),
|
|
12228
|
+
read: CompositionFieldReadSchema,
|
|
12229
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
12230
|
+
publish: _enum([
|
|
12231
|
+
"value",
|
|
12232
|
+
"included",
|
|
12233
|
+
"excluded",
|
|
12234
|
+
"total"
|
|
12235
|
+
]),
|
|
12236
|
+
/**
|
|
12237
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12238
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12239
|
+
*/
|
|
12240
|
+
empty: _enum([
|
|
12241
|
+
"null",
|
|
12242
|
+
"omit",
|
|
12243
|
+
"offline"
|
|
12244
|
+
])
|
|
12072
12245
|
})
|
|
12073
12246
|
]);
|
|
12074
12247
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -18262,7 +18435,8 @@ var CompositionProblemSchema = object({
|
|
|
18262
18435
|
"native-capability-replace",
|
|
18263
18436
|
"mixed-quantity",
|
|
18264
18437
|
"helper-mismatch",
|
|
18265
|
-
"member-constraint"
|
|
18438
|
+
"member-constraint",
|
|
18439
|
+
"retention"
|
|
18266
18440
|
]),
|
|
18267
18441
|
path: string(),
|
|
18268
18442
|
message: string()
|
|
@@ -18496,13 +18670,17 @@ Object.freeze({
|
|
|
18496
18670
|
latchedAt: {
|
|
18497
18671
|
kind: "fixed",
|
|
18498
18672
|
result: ["number", "null"]
|
|
18673
|
+
},
|
|
18674
|
+
schmitt: {
|
|
18675
|
+
kind: "fixed",
|
|
18676
|
+
result: ["boolean", "null"]
|
|
18499
18677
|
}
|
|
18500
18678
|
});
|
|
18501
18679
|
/**
|
|
18502
18680
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18503
18681
|
* Data, not a form default written into the block.
|
|
18504
18682
|
*/
|
|
18505
|
-
var NOW = {
|
|
18683
|
+
var NOW$2 = {
|
|
18506
18684
|
fieldPath: "lastFetchedAt",
|
|
18507
18685
|
expr: "now"
|
|
18508
18686
|
};
|
|
@@ -18516,6 +18694,8 @@ function numeric(input) {
|
|
|
18516
18694
|
family: "numeric",
|
|
18517
18695
|
deviceType: DeviceType.Sensor,
|
|
18518
18696
|
memberDeviceType: DeviceType.Sensor,
|
|
18697
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18698
|
+
activeWhen: void 0,
|
|
18519
18699
|
commandCaps: [],
|
|
18520
18700
|
baseUnit: baseUnitOf(input.quantity),
|
|
18521
18701
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18531,6 +18711,8 @@ function binary(input) {
|
|
|
18531
18711
|
family: "binary",
|
|
18532
18712
|
deviceType: DeviceType.Sensor,
|
|
18533
18713
|
memberDeviceType: DeviceType.Sensor,
|
|
18714
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18715
|
+
activeWhen: void 0,
|
|
18534
18716
|
commandCaps: [],
|
|
18535
18717
|
quantity: "none",
|
|
18536
18718
|
baseUnit: void 0,
|
|
@@ -18548,7 +18730,7 @@ var GROUP_TEMPLATES = [
|
|
|
18548
18730
|
quantity: "temperature",
|
|
18549
18731
|
defaultAggregate: "mean",
|
|
18550
18732
|
empty: "null",
|
|
18551
|
-
companions: [NOW]
|
|
18733
|
+
companions: [NOW$2]
|
|
18552
18734
|
}),
|
|
18553
18735
|
numeric({
|
|
18554
18736
|
id: "humidity",
|
|
@@ -18559,7 +18741,7 @@ var GROUP_TEMPLATES = [
|
|
|
18559
18741
|
quantity: "humidity",
|
|
18560
18742
|
defaultAggregate: "mean",
|
|
18561
18743
|
empty: "null",
|
|
18562
|
-
companions: [NOW]
|
|
18744
|
+
companions: [NOW$2]
|
|
18563
18745
|
}),
|
|
18564
18746
|
numeric({
|
|
18565
18747
|
id: "pressure",
|
|
@@ -18570,7 +18752,7 @@ var GROUP_TEMPLATES = [
|
|
|
18570
18752
|
quantity: "pressure",
|
|
18571
18753
|
defaultAggregate: "mean",
|
|
18572
18754
|
empty: "null",
|
|
18573
|
-
companions: [NOW]
|
|
18755
|
+
companions: [NOW$2]
|
|
18574
18756
|
}),
|
|
18575
18757
|
numeric({
|
|
18576
18758
|
id: "illuminance",
|
|
@@ -18581,7 +18763,7 @@ var GROUP_TEMPLATES = [
|
|
|
18581
18763
|
quantity: "illuminance",
|
|
18582
18764
|
defaultAggregate: "mean",
|
|
18583
18765
|
empty: "null",
|
|
18584
|
-
companions: [NOW]
|
|
18766
|
+
companions: [NOW$2]
|
|
18585
18767
|
}),
|
|
18586
18768
|
numeric({
|
|
18587
18769
|
id: "power",
|
|
@@ -18592,7 +18774,7 @@ var GROUP_TEMPLATES = [
|
|
|
18592
18774
|
quantity: "power",
|
|
18593
18775
|
defaultAggregate: "sum",
|
|
18594
18776
|
empty: "omit",
|
|
18595
|
-
companions: [NOW]
|
|
18777
|
+
companions: [NOW$2]
|
|
18596
18778
|
}),
|
|
18597
18779
|
numeric({
|
|
18598
18780
|
id: "energy",
|
|
@@ -18603,7 +18785,7 @@ var GROUP_TEMPLATES = [
|
|
|
18603
18785
|
quantity: "energy",
|
|
18604
18786
|
defaultAggregate: "sum",
|
|
18605
18787
|
empty: "omit",
|
|
18606
|
-
companions: [NOW]
|
|
18788
|
+
companions: [NOW$2]
|
|
18607
18789
|
}),
|
|
18608
18790
|
numeric({
|
|
18609
18791
|
id: "battery",
|
|
@@ -18638,7 +18820,7 @@ var GROUP_TEMPLATES = [
|
|
|
18638
18820
|
quantity: "device",
|
|
18639
18821
|
defaultAggregate: "mean",
|
|
18640
18822
|
empty: "null",
|
|
18641
|
-
companions: [NOW]
|
|
18823
|
+
companions: [NOW$2]
|
|
18642
18824
|
}),
|
|
18643
18825
|
binary({
|
|
18644
18826
|
id: "motion",
|
|
@@ -18732,6 +18914,11 @@ var GROUP_TEMPLATES = [
|
|
|
18732
18914
|
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.",
|
|
18733
18915
|
deviceType: DeviceType.Switch,
|
|
18734
18916
|
outputCap: "switch",
|
|
18917
|
+
outputField: "on",
|
|
18918
|
+
member: {
|
|
18919
|
+
cap: "switch",
|
|
18920
|
+
fieldPath: "on"
|
|
18921
|
+
},
|
|
18735
18922
|
commandCaps: ["switch"]
|
|
18736
18923
|
}),
|
|
18737
18924
|
actuator({
|
|
@@ -18739,34 +18926,136 @@ var GROUP_TEMPLATES = [
|
|
|
18739
18926
|
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.",
|
|
18740
18927
|
deviceType: DeviceType.Light,
|
|
18741
18928
|
outputCap: "switch",
|
|
18929
|
+
outputField: "on",
|
|
18930
|
+
member: {
|
|
18931
|
+
cap: "switch",
|
|
18932
|
+
fieldPath: "on"
|
|
18933
|
+
},
|
|
18742
18934
|
commandCaps: [
|
|
18743
18935
|
"switch",
|
|
18744
18936
|
"brightness",
|
|
18745
18937
|
"color"
|
|
18746
18938
|
]
|
|
18939
|
+
}),
|
|
18940
|
+
actuator({
|
|
18941
|
+
id: "fan",
|
|
18942
|
+
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.",
|
|
18943
|
+
deviceType: DeviceType.Fan,
|
|
18944
|
+
outputCap: "switch",
|
|
18945
|
+
outputField: "on",
|
|
18946
|
+
member: {
|
|
18947
|
+
cap: "switch",
|
|
18948
|
+
fieldPath: "on"
|
|
18949
|
+
},
|
|
18950
|
+
commandCaps: ["switch", "fan-control"]
|
|
18951
|
+
}),
|
|
18952
|
+
actuator({
|
|
18953
|
+
id: "cover",
|
|
18954
|
+
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.",
|
|
18955
|
+
deviceType: DeviceType.Cover,
|
|
18956
|
+
outputCap: "group-active",
|
|
18957
|
+
outputField: "active",
|
|
18958
|
+
member: {
|
|
18959
|
+
cap: "cover",
|
|
18960
|
+
fieldPath: "state"
|
|
18961
|
+
},
|
|
18962
|
+
activeWhen: [
|
|
18963
|
+
"open",
|
|
18964
|
+
"opening",
|
|
18965
|
+
"stopped"
|
|
18966
|
+
],
|
|
18967
|
+
commandCaps: ["cover"]
|
|
18968
|
+
}),
|
|
18969
|
+
actuator({
|
|
18970
|
+
id: "valve",
|
|
18971
|
+
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.",
|
|
18972
|
+
deviceType: DeviceType.Valve,
|
|
18973
|
+
outputCap: "group-active",
|
|
18974
|
+
outputField: "active",
|
|
18975
|
+
member: {
|
|
18976
|
+
cap: "valve",
|
|
18977
|
+
fieldPath: "state"
|
|
18978
|
+
},
|
|
18979
|
+
activeWhen: [
|
|
18980
|
+
"open",
|
|
18981
|
+
"opening",
|
|
18982
|
+
"stopped"
|
|
18983
|
+
],
|
|
18984
|
+
commandCaps: ["valve"]
|
|
18985
|
+
}),
|
|
18986
|
+
actuator({
|
|
18987
|
+
id: "lock",
|
|
18988
|
+
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.",
|
|
18989
|
+
deviceType: DeviceType.Lock,
|
|
18990
|
+
outputCap: "group-active",
|
|
18991
|
+
outputField: "active",
|
|
18992
|
+
member: {
|
|
18993
|
+
cap: "lock-control",
|
|
18994
|
+
fieldPath: "state"
|
|
18995
|
+
},
|
|
18996
|
+
activeWhen: ["locked"],
|
|
18997
|
+
commandCaps: ["lock-control"]
|
|
18998
|
+
}),
|
|
18999
|
+
actuator({
|
|
19000
|
+
id: "media-player",
|
|
19001
|
+
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.",
|
|
19002
|
+
deviceType: DeviceType.MediaPlayer,
|
|
19003
|
+
outputCap: "group-active",
|
|
19004
|
+
outputField: "active",
|
|
19005
|
+
member: {
|
|
19006
|
+
cap: "media-player",
|
|
19007
|
+
fieldPath: "state"
|
|
19008
|
+
},
|
|
19009
|
+
activeWhen: ["playing", "buffering"],
|
|
19010
|
+
commandCaps: ["media-player"]
|
|
19011
|
+
}),
|
|
19012
|
+
actuator({
|
|
19013
|
+
id: "climate",
|
|
19014
|
+
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.",
|
|
19015
|
+
deviceType: DeviceType.Thermostat,
|
|
19016
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
19017
|
+
outputCap: "group-active",
|
|
19018
|
+
outputField: "active",
|
|
19019
|
+
member: {
|
|
19020
|
+
cap: "climate-control",
|
|
19021
|
+
fieldPath: "mode"
|
|
19022
|
+
},
|
|
19023
|
+
activeWhen: [
|
|
19024
|
+
"heat",
|
|
19025
|
+
"cool",
|
|
19026
|
+
"auto",
|
|
19027
|
+
"heat_cool",
|
|
19028
|
+
"fan_only",
|
|
19029
|
+
"dry"
|
|
19030
|
+
],
|
|
19031
|
+
commandCaps: ["climate-control"]
|
|
18747
19032
|
})
|
|
18748
19033
|
];
|
|
18749
19034
|
function actuator(input) {
|
|
18750
19035
|
return {
|
|
18751
|
-
|
|
19036
|
+
id: input.id,
|
|
19037
|
+
summary: input.summary,
|
|
19038
|
+
deviceType: input.deviceType,
|
|
19039
|
+
outputCap: input.outputCap,
|
|
19040
|
+
outputField: input.outputField,
|
|
19041
|
+
commandCaps: input.commandCaps,
|
|
18752
19042
|
family: "actuator",
|
|
18753
19043
|
role: void 0,
|
|
18754
19044
|
memberDeviceType: input.deviceType,
|
|
18755
|
-
|
|
19045
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
19046
|
+
activeWhen: input.activeWhen,
|
|
18756
19047
|
quantity: "none",
|
|
18757
19048
|
baseUnit: void 0,
|
|
18758
19049
|
aggregates: BINARY_AGGREGATES,
|
|
18759
19050
|
defaultAggregate: "any",
|
|
18760
19051
|
empty: "offline",
|
|
18761
|
-
accept: [
|
|
18762
|
-
cap: "switch",
|
|
18763
|
-
fieldPath: "on"
|
|
18764
|
-
}],
|
|
19052
|
+
accept: [input.member],
|
|
18765
19053
|
companions: [CHANGED]
|
|
18766
19054
|
};
|
|
18767
19055
|
}
|
|
18768
19056
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18769
19057
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
19058
|
+
DeviceType.Camera;
|
|
18770
19059
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18771
19060
|
/**
|
|
18772
19061
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -46424,7 +46713,20 @@ var NcRuleInputSchema = object({
|
|
|
46424
46713
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
46425
46714
|
* path does not run Zod defaults.
|
|
46426
46715
|
*/
|
|
46427
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46716
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46717
|
+
/**
|
|
46718
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46719
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46720
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46721
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46722
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46723
|
+
*
|
|
46724
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46725
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46726
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46727
|
+
* `false`, so it needs no `clear` key.
|
|
46728
|
+
*/
|
|
46729
|
+
askVerdict: boolean().optional()
|
|
46428
46730
|
});
|
|
46429
46731
|
/**
|
|
46430
46732
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -58625,7 +58927,13 @@ results: array(object({
|
|
|
58625
58927
|
/** Ms epoch of the attempt. */
|
|
58626
58928
|
at: number()
|
|
58627
58929
|
})) });
|
|
58628
|
-
DeviceType.Switch, DeviceType.Light;
|
|
58930
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58931
|
+
object({
|
|
58932
|
+
active: boolean().meta({ label: "Active" }),
|
|
58933
|
+
/** Ms epoch when the slice was last updated. */
|
|
58934
|
+
lastChangedAt: number()
|
|
58935
|
+
});
|
|
58936
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
58629
58937
|
object({
|
|
58630
58938
|
/** Members whose current value entered the aggregate. */
|
|
58631
58939
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -58643,7 +58951,7 @@ object({
|
|
|
58643
58951
|
label: "Members"
|
|
58644
58952
|
}))
|
|
58645
58953
|
});
|
|
58646
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58954
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58647
58955
|
object({
|
|
58648
58956
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58649
58957
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -59550,7 +59858,14 @@ DeviceType.Lock, method(object({
|
|
|
59550
59858
|
auth: "protected"
|
|
59551
59859
|
}), method(object({
|
|
59552
59860
|
deviceId: number().int().nonnegative(),
|
|
59553
|
-
code: string().min(1).optional()
|
|
59861
|
+
code: string().min(1).optional(),
|
|
59862
|
+
/**
|
|
59863
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
59864
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
59865
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
59866
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
59867
|
+
*/
|
|
59868
|
+
confirm: boolean().optional()
|
|
59554
59869
|
}), _void(), {
|
|
59555
59870
|
kind: "mutation",
|
|
59556
59871
|
auth: "protected"
|
|
@@ -59558,6 +59873,11 @@ DeviceType.Lock, method(object({
|
|
|
59558
59873
|
kind: "mutation",
|
|
59559
59874
|
auth: "protected"
|
|
59560
59875
|
});
|
|
59876
|
+
object({
|
|
59877
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
59878
|
+
lastFetchedAt: number()
|
|
59879
|
+
});
|
|
59880
|
+
DeviceType.Sensor;
|
|
59561
59881
|
/**
|
|
59562
59882
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
59563
59883
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -63961,7 +64281,7 @@ object({
|
|
|
63961
64281
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
63962
64282
|
lastChangedAt: number()
|
|
63963
64283
|
});
|
|
63964
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
64284
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
63965
64285
|
deviceId: number(),
|
|
63966
64286
|
on: boolean()
|
|
63967
64287
|
}), _void(), {
|
|
@@ -65755,6 +66075,7 @@ var trainingCapability = {
|
|
|
65755
66075
|
})
|
|
65756
66076
|
}
|
|
65757
66077
|
};
|
|
66078
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
65758
66079
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
65759
66080
|
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;
|
|
65760
66081
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
@@ -69032,6 +69353,13 @@ Object.freeze({
|
|
|
69032
69353
|
access: "view",
|
|
69033
69354
|
role: "viewer"
|
|
69034
69355
|
},
|
|
69356
|
+
"groupActive.getStatus": {
|
|
69357
|
+
capName: "group-active",
|
|
69358
|
+
capScope: "device",
|
|
69359
|
+
addonId: null,
|
|
69360
|
+
access: "view",
|
|
69361
|
+
role: "viewer"
|
|
69362
|
+
},
|
|
69035
69363
|
"groupCommands.getStatus": {
|
|
69036
69364
|
capName: "group-commands",
|
|
69037
69365
|
capScope: "device",
|
|
@@ -69998,6 +70326,13 @@ Object.freeze({
|
|
|
69998
70326
|
access: "create",
|
|
69999
70327
|
role: "admin"
|
|
70000
70328
|
},
|
|
70329
|
+
"meter.getStatus": {
|
|
70330
|
+
capName: "meter",
|
|
70331
|
+
capScope: "device",
|
|
70332
|
+
addonId: null,
|
|
70333
|
+
access: "view",
|
|
70334
|
+
role: "viewer"
|
|
70335
|
+
},
|
|
70001
70336
|
"metricsProvider.collectSnapshot": {
|
|
70002
70337
|
capName: "metrics-provider",
|
|
70003
70338
|
capScope: "system",
|
|
@@ -78900,6 +79235,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78900
79235
|
icon: "flame"
|
|
78901
79236
|
}]
|
|
78902
79237
|
},
|
|
79238
|
+
"group-active": {
|
|
79239
|
+
scope: "device",
|
|
79240
|
+
noun: t("Group state", "Stato del gruppo")
|
|
79241
|
+
},
|
|
78903
79242
|
"group-commands": {
|
|
78904
79243
|
scope: "device",
|
|
78905
79244
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -78956,6 +79295,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78956
79295
|
}],
|
|
78957
79296
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
78958
79297
|
},
|
|
79298
|
+
meter: {
|
|
79299
|
+
scope: "device",
|
|
79300
|
+
noun: t("Meter", "Contatore"),
|
|
79301
|
+
state: [{
|
|
79302
|
+
kind: "numeric",
|
|
79303
|
+
field: "value",
|
|
79304
|
+
quantity: t("the total", "il totale"),
|
|
79305
|
+
label: t("Total", "Totale"),
|
|
79306
|
+
icon: "gauge"
|
|
79307
|
+
}]
|
|
79308
|
+
},
|
|
78959
79309
|
"numeric-sensor": {
|
|
78960
79310
|
scope: "device",
|
|
78961
79311
|
noun: t("Sensor", "Sensore"),
|
|
@@ -80435,6 +80785,11 @@ Object.freeze({
|
|
|
80435
80785
|
form: "single",
|
|
80436
80786
|
optional: false
|
|
80437
80787
|
}],
|
|
80788
|
+
"groupActive.getStatus": [{
|
|
80789
|
+
name: "deviceId",
|
|
80790
|
+
form: "single",
|
|
80791
|
+
optional: false
|
|
80792
|
+
}],
|
|
80438
80793
|
"groupCommands.getStatus": [{
|
|
80439
80794
|
name: "deviceId",
|
|
80440
80795
|
form: "single",
|
|
@@ -80645,6 +81000,11 @@ Object.freeze({
|
|
|
80645
81000
|
form: "single",
|
|
80646
81001
|
optional: false
|
|
80647
81002
|
}],
|
|
81003
|
+
"meter.getStatus": [{
|
|
81004
|
+
name: "deviceId",
|
|
81005
|
+
form: "single",
|
|
81006
|
+
optional: false
|
|
81007
|
+
}],
|
|
80648
81008
|
"motion.getStatus": [{
|
|
80649
81009
|
name: "deviceId",
|
|
80650
81010
|
form: "single",
|
|
@@ -82252,7 +82612,6 @@ Object.freeze({
|
|
|
82252
82612
|
"network-access": "ingress",
|
|
82253
82613
|
"smtp-provider": "email"
|
|
82254
82614
|
});
|
|
82255
|
-
DeviceType.Camera;
|
|
82256
82615
|
/**
|
|
82257
82616
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
82258
82617
|
* `z.infer`, they do not restate the shape.
|