@camstack/addon-model-studio 1.1.304 → 1.1.306
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-DBGT8Nj8.mjs → MotionZonesSettings-BdAF3Lx2.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-CLQVQM7P.mjs → PrivacyMaskSettings-bRMKWnGr.mjs} +4 -4
- package/dist/{SceneMonitorEditor-Bh49Hy9u.mjs → SceneMonitorEditor-DffVOhzN.mjs} +3 -3
- package/dist/_stub.js +628 -627
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-C21hMYtP.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DVVRygHY.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CsIeC3fr.mjs +26 -0
- package/dist/{hostInit-ZZzTzmNI.mjs → hostInit-fNjQtgdi.mjs} +2 -2
- package/dist/model-studio.addon.js +399 -40
- package/dist/model-studio.addon.mjs +399 -40
- package/dist/{player-overlays-Cyvfs2Sv.mjs → player-overlays-BQux3aXS.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-m4ExMXS1.mjs → responsive-BOS8RfJa.mjs} +1 -1
- package/dist/{scene-monitor-copy-BQJaiY--.mjs → scene-monitor-copy-CaVNQakt.mjs} +1 -1
- package/dist/{square-CfhGQSpr.mjs → square-DCA-7eaY.mjs} +1 -1
- package/dist/{trash-2-a_u-D224.mjs → trash-2-DYZFq4gu.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-D2OpYesY.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CWXLGHpz.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-ClO1ZruD.mjs +0 -26
|
@@ -5837,7 +5837,7 @@ var ZodIssueCode = {
|
|
|
5837
5837
|
var ZodFirstPartyTypeKind;
|
|
5838
5838
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5839
5839
|
//#endregion
|
|
5840
|
-
//#region ../types/dist/sleep
|
|
5840
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5841
5841
|
/**
|
|
5842
5842
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5843
5843
|
* window to float samples (D455).
|
|
@@ -9040,6 +9040,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9040
9040
|
"filesystem-browse",
|
|
9041
9041
|
"flood",
|
|
9042
9042
|
"gas",
|
|
9043
|
+
"group-active",
|
|
9043
9044
|
"group-commands",
|
|
9044
9045
|
"group-status",
|
|
9045
9046
|
"heating-valve",
|
|
@@ -9062,6 +9063,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9062
9063
|
"login-method",
|
|
9063
9064
|
"media-player",
|
|
9064
9065
|
"mesh-network",
|
|
9066
|
+
"meter",
|
|
9065
9067
|
"metrics-provider",
|
|
9066
9068
|
"model-convert",
|
|
9067
9069
|
"model-distributor",
|
|
@@ -9860,6 +9862,10 @@ Object.freeze({
|
|
|
9860
9862
|
"path": "detected",
|
|
9861
9863
|
"valueType": "boolean"
|
|
9862
9864
|
}],
|
|
9865
|
+
"group-active": [{
|
|
9866
|
+
"path": "active",
|
|
9867
|
+
"valueType": "boolean"
|
|
9868
|
+
}],
|
|
9863
9869
|
"group-status": [
|
|
9864
9870
|
{
|
|
9865
9871
|
"path": "included",
|
|
@@ -10119,6 +10125,10 @@ Object.freeze({
|
|
|
10119
10125
|
]
|
|
10120
10126
|
}
|
|
10121
10127
|
],
|
|
10128
|
+
"meter": [{
|
|
10129
|
+
"path": "value",
|
|
10130
|
+
"valueType": "number"
|
|
10131
|
+
}],
|
|
10122
10132
|
"motion": [
|
|
10123
10133
|
{
|
|
10124
10134
|
"path": "detected",
|
|
@@ -11211,7 +11221,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11211
11221
|
return DeviceRole;
|
|
11212
11222
|
}({});
|
|
11213
11223
|
//#endregion
|
|
11214
|
-
//#region ../types/dist/composition-
|
|
11224
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
11215
11225
|
/**
|
|
11216
11226
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11217
11227
|
*
|
|
@@ -11526,6 +11536,13 @@ var table = {
|
|
|
11526
11536
|
apply: () => {
|
|
11527
11537
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11528
11538
|
}
|
|
11539
|
+
},
|
|
11540
|
+
schmitt: {
|
|
11541
|
+
minArgs: 3,
|
|
11542
|
+
maxArgs: 5,
|
|
11543
|
+
apply: () => {
|
|
11544
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11545
|
+
}
|
|
11529
11546
|
}
|
|
11530
11547
|
};
|
|
11531
11548
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11987,6 +12004,79 @@ var APPLIANCE_KINDS = [
|
|
|
11987
12004
|
];
|
|
11988
12005
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11989
12006
|
/**
|
|
12007
|
+
* Statistics and integrals over a history read (D944).
|
|
12008
|
+
*
|
|
12009
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
12010
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
12011
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
12012
|
+
* as zero. A truncated read is not published.
|
|
12013
|
+
*/
|
|
12014
|
+
var STATISTIC_STATS = [
|
|
12015
|
+
"min",
|
|
12016
|
+
"max",
|
|
12017
|
+
"mean",
|
|
12018
|
+
"sum",
|
|
12019
|
+
"count",
|
|
12020
|
+
"change"
|
|
12021
|
+
];
|
|
12022
|
+
/**
|
|
12023
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
12024
|
+
*
|
|
12025
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
12026
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
12027
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
12028
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
12029
|
+
*/
|
|
12030
|
+
var MINUTE_MS = 6e4;
|
|
12031
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
12032
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
12033
|
+
var ROLLING_SPANS = [
|
|
12034
|
+
"1h",
|
|
12035
|
+
"24h",
|
|
12036
|
+
"2d",
|
|
12037
|
+
"7d",
|
|
12038
|
+
"30d",
|
|
12039
|
+
"custom"
|
|
12040
|
+
];
|
|
12041
|
+
var CALENDAR_PERIODS = [
|
|
12042
|
+
"today",
|
|
12043
|
+
"yesterday",
|
|
12044
|
+
"this-week",
|
|
12045
|
+
"this-month"
|
|
12046
|
+
];
|
|
12047
|
+
var RESET_PERIODS = [
|
|
12048
|
+
"never",
|
|
12049
|
+
"daily",
|
|
12050
|
+
"weekly",
|
|
12051
|
+
"monthly"
|
|
12052
|
+
];
|
|
12053
|
+
5 * MINUTE_MS;
|
|
12054
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
12055
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
12056
|
+
var rollingWindowObject = object({
|
|
12057
|
+
kind: literal("rolling"),
|
|
12058
|
+
span: _enum(ROLLING_SPANS),
|
|
12059
|
+
customMinutes: number().int().min(5).optional()
|
|
12060
|
+
}).check((payload) => {
|
|
12061
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
12062
|
+
code: "custom",
|
|
12063
|
+
message: "a custom range needs a duration in minutes",
|
|
12064
|
+
path: ["customMinutes"],
|
|
12065
|
+
input: payload.value
|
|
12066
|
+
});
|
|
12067
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
12068
|
+
code: "custom",
|
|
12069
|
+
message: "only a custom range carries a duration",
|
|
12070
|
+
path: ["customMinutes"],
|
|
12071
|
+
input: payload.value
|
|
12072
|
+
});
|
|
12073
|
+
});
|
|
12074
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
12075
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
12076
|
+
kind: literal("calendar"),
|
|
12077
|
+
period: _enum(CALENDAR_PERIODS)
|
|
12078
|
+
})]);
|
|
12079
|
+
/**
|
|
11990
12080
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11991
12081
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11992
12082
|
* `composition.ts` (D659).
|
|
@@ -12012,7 +12102,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
12012
12102
|
"occupancy",
|
|
12013
12103
|
"binary",
|
|
12014
12104
|
"switch",
|
|
12015
|
-
"light"
|
|
12105
|
+
"light",
|
|
12106
|
+
"fan",
|
|
12107
|
+
"cover",
|
|
12108
|
+
"valve",
|
|
12109
|
+
"lock",
|
|
12110
|
+
"media-player",
|
|
12111
|
+
"climate"
|
|
12016
12112
|
];
|
|
12017
12113
|
var NUMERIC_AGGREGATES = [
|
|
12018
12114
|
"mean",
|
|
@@ -12042,22 +12138,73 @@ var HelperMemberSchema = object({
|
|
|
12042
12138
|
cap: string().min(1),
|
|
12043
12139
|
fieldPath: string().min(1)
|
|
12044
12140
|
});
|
|
12045
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12046
|
-
|
|
12047
|
-
|
|
12048
|
-
|
|
12049
|
-
|
|
12050
|
-
|
|
12051
|
-
|
|
12052
|
-
|
|
12053
|
-
|
|
12054
|
-
|
|
12055
|
-
|
|
12056
|
-
|
|
12057
|
-
|
|
12058
|
-
|
|
12059
|
-
|
|
12060
|
-
|
|
12141
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12142
|
+
object({
|
|
12143
|
+
kind: literal("group"),
|
|
12144
|
+
templateId: GroupTemplateIdSchema,
|
|
12145
|
+
aggregate: AggregateReducerSchema,
|
|
12146
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
12147
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
12148
|
+
active: ActiveCriterionSchema.optional()
|
|
12149
|
+
}),
|
|
12150
|
+
object({
|
|
12151
|
+
kind: literal("appliance"),
|
|
12152
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
12153
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
12154
|
+
thresholdWatts: number().positive(),
|
|
12155
|
+
startDwellMs: number().int().nonnegative(),
|
|
12156
|
+
stopDwellMs: number().int().nonnegative(),
|
|
12157
|
+
member: HelperMemberSchema
|
|
12158
|
+
}),
|
|
12159
|
+
object({
|
|
12160
|
+
kind: literal("statistic"),
|
|
12161
|
+
stat: _enum(STATISTIC_STATS),
|
|
12162
|
+
window: StatisticWindowSchema,
|
|
12163
|
+
source: HelperMemberSchema
|
|
12164
|
+
}),
|
|
12165
|
+
object({
|
|
12166
|
+
kind: literal("integral"),
|
|
12167
|
+
reset: _enum(RESET_PERIODS),
|
|
12168
|
+
output: _enum(["energy", "meter"]),
|
|
12169
|
+
source: HelperMemberSchema
|
|
12170
|
+
}),
|
|
12171
|
+
object({
|
|
12172
|
+
kind: literal("threshold"),
|
|
12173
|
+
source: HelperMemberSchema,
|
|
12174
|
+
high: number(),
|
|
12175
|
+
low: number(),
|
|
12176
|
+
onForMs: number().int().nonnegative(),
|
|
12177
|
+
offForMs: number().int().nonnegative()
|
|
12178
|
+
}),
|
|
12179
|
+
object({
|
|
12180
|
+
kind: literal("arithmetic"),
|
|
12181
|
+
op: _enum([
|
|
12182
|
+
"sum",
|
|
12183
|
+
"difference",
|
|
12184
|
+
"ratio"
|
|
12185
|
+
]),
|
|
12186
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
12187
|
+
}),
|
|
12188
|
+
object({
|
|
12189
|
+
kind: literal("expression"),
|
|
12190
|
+
expr: string().min(1),
|
|
12191
|
+
inputs: array(object({
|
|
12192
|
+
name: string().min(1),
|
|
12193
|
+
member: HelperMemberSchema
|
|
12194
|
+
})).min(1).max(64),
|
|
12195
|
+
output: _enum(["number", "boolean"])
|
|
12196
|
+
}),
|
|
12197
|
+
object({
|
|
12198
|
+
kind: literal("derivative"),
|
|
12199
|
+
window: RollingWindowSchema,
|
|
12200
|
+
per: _enum([
|
|
12201
|
+
"second",
|
|
12202
|
+
"minute",
|
|
12203
|
+
"hour"
|
|
12204
|
+
]),
|
|
12205
|
+
source: HelperMemberSchema
|
|
12206
|
+
})
|
|
12207
|
+
]);
|
|
12061
12208
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
12062
12209
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
12063
12210
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -12118,6 +12265,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12118
12265
|
"all"
|
|
12119
12266
|
]),
|
|
12120
12267
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12268
|
+
/**
|
|
12269
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
12270
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
12271
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
12272
|
+
*/
|
|
12273
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
12121
12274
|
/** `value` is the reading; the others are the member counts. */
|
|
12122
12275
|
publish: _enum([
|
|
12123
12276
|
"value",
|
|
@@ -12131,6 +12284,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12131
12284
|
"omit",
|
|
12132
12285
|
"offline"
|
|
12133
12286
|
])
|
|
12287
|
+
}),
|
|
12288
|
+
object({
|
|
12289
|
+
kind: literal("series"),
|
|
12290
|
+
read: CompositionFieldReadSchema,
|
|
12291
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
12292
|
+
publish: _enum([
|
|
12293
|
+
"value",
|
|
12294
|
+
"included",
|
|
12295
|
+
"excluded",
|
|
12296
|
+
"total"
|
|
12297
|
+
]),
|
|
12298
|
+
/**
|
|
12299
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12300
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12301
|
+
*/
|
|
12302
|
+
empty: _enum([
|
|
12303
|
+
"null",
|
|
12304
|
+
"omit",
|
|
12305
|
+
"offline"
|
|
12306
|
+
])
|
|
12134
12307
|
})
|
|
12135
12308
|
]);
|
|
12136
12309
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -18445,7 +18618,8 @@ var CompositionProblemSchema = object({
|
|
|
18445
18618
|
"native-capability-replace",
|
|
18446
18619
|
"mixed-quantity",
|
|
18447
18620
|
"helper-mismatch",
|
|
18448
|
-
"member-constraint"
|
|
18621
|
+
"member-constraint",
|
|
18622
|
+
"retention"
|
|
18449
18623
|
]),
|
|
18450
18624
|
path: string(),
|
|
18451
18625
|
message: string()
|
|
@@ -18679,13 +18853,17 @@ Object.freeze({
|
|
|
18679
18853
|
latchedAt: {
|
|
18680
18854
|
kind: "fixed",
|
|
18681
18855
|
result: ["number", "null"]
|
|
18856
|
+
},
|
|
18857
|
+
schmitt: {
|
|
18858
|
+
kind: "fixed",
|
|
18859
|
+
result: ["boolean", "null"]
|
|
18682
18860
|
}
|
|
18683
18861
|
});
|
|
18684
18862
|
/**
|
|
18685
18863
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18686
18864
|
* Data, not a form default written into the block.
|
|
18687
18865
|
*/
|
|
18688
|
-
var NOW = {
|
|
18866
|
+
var NOW$2 = {
|
|
18689
18867
|
fieldPath: "lastFetchedAt",
|
|
18690
18868
|
expr: "now"
|
|
18691
18869
|
};
|
|
@@ -18699,6 +18877,8 @@ function numeric(input) {
|
|
|
18699
18877
|
family: "numeric",
|
|
18700
18878
|
deviceType: DeviceType.Sensor,
|
|
18701
18879
|
memberDeviceType: DeviceType.Sensor,
|
|
18880
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18881
|
+
activeWhen: void 0,
|
|
18702
18882
|
commandCaps: [],
|
|
18703
18883
|
baseUnit: baseUnitOf(input.quantity),
|
|
18704
18884
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18714,6 +18894,8 @@ function binary(input) {
|
|
|
18714
18894
|
family: "binary",
|
|
18715
18895
|
deviceType: DeviceType.Sensor,
|
|
18716
18896
|
memberDeviceType: DeviceType.Sensor,
|
|
18897
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18898
|
+
activeWhen: void 0,
|
|
18717
18899
|
commandCaps: [],
|
|
18718
18900
|
quantity: "none",
|
|
18719
18901
|
baseUnit: void 0,
|
|
@@ -18731,7 +18913,7 @@ var GROUP_TEMPLATES = [
|
|
|
18731
18913
|
quantity: "temperature",
|
|
18732
18914
|
defaultAggregate: "mean",
|
|
18733
18915
|
empty: "null",
|
|
18734
|
-
companions: [NOW]
|
|
18916
|
+
companions: [NOW$2]
|
|
18735
18917
|
}),
|
|
18736
18918
|
numeric({
|
|
18737
18919
|
id: "humidity",
|
|
@@ -18742,7 +18924,7 @@ var GROUP_TEMPLATES = [
|
|
|
18742
18924
|
quantity: "humidity",
|
|
18743
18925
|
defaultAggregate: "mean",
|
|
18744
18926
|
empty: "null",
|
|
18745
|
-
companions: [NOW]
|
|
18927
|
+
companions: [NOW$2]
|
|
18746
18928
|
}),
|
|
18747
18929
|
numeric({
|
|
18748
18930
|
id: "pressure",
|
|
@@ -18753,7 +18935,7 @@ var GROUP_TEMPLATES = [
|
|
|
18753
18935
|
quantity: "pressure",
|
|
18754
18936
|
defaultAggregate: "mean",
|
|
18755
18937
|
empty: "null",
|
|
18756
|
-
companions: [NOW]
|
|
18938
|
+
companions: [NOW$2]
|
|
18757
18939
|
}),
|
|
18758
18940
|
numeric({
|
|
18759
18941
|
id: "illuminance",
|
|
@@ -18764,7 +18946,7 @@ var GROUP_TEMPLATES = [
|
|
|
18764
18946
|
quantity: "illuminance",
|
|
18765
18947
|
defaultAggregate: "mean",
|
|
18766
18948
|
empty: "null",
|
|
18767
|
-
companions: [NOW]
|
|
18949
|
+
companions: [NOW$2]
|
|
18768
18950
|
}),
|
|
18769
18951
|
numeric({
|
|
18770
18952
|
id: "power",
|
|
@@ -18775,7 +18957,7 @@ var GROUP_TEMPLATES = [
|
|
|
18775
18957
|
quantity: "power",
|
|
18776
18958
|
defaultAggregate: "sum",
|
|
18777
18959
|
empty: "omit",
|
|
18778
|
-
companions: [NOW]
|
|
18960
|
+
companions: [NOW$2]
|
|
18779
18961
|
}),
|
|
18780
18962
|
numeric({
|
|
18781
18963
|
id: "energy",
|
|
@@ -18786,7 +18968,7 @@ var GROUP_TEMPLATES = [
|
|
|
18786
18968
|
quantity: "energy",
|
|
18787
18969
|
defaultAggregate: "sum",
|
|
18788
18970
|
empty: "omit",
|
|
18789
|
-
companions: [NOW]
|
|
18971
|
+
companions: [NOW$2]
|
|
18790
18972
|
}),
|
|
18791
18973
|
numeric({
|
|
18792
18974
|
id: "battery",
|
|
@@ -18821,7 +19003,7 @@ var GROUP_TEMPLATES = [
|
|
|
18821
19003
|
quantity: "device",
|
|
18822
19004
|
defaultAggregate: "mean",
|
|
18823
19005
|
empty: "null",
|
|
18824
|
-
companions: [NOW]
|
|
19006
|
+
companions: [NOW$2]
|
|
18825
19007
|
}),
|
|
18826
19008
|
binary({
|
|
18827
19009
|
id: "motion",
|
|
@@ -18915,6 +19097,11 @@ var GROUP_TEMPLATES = [
|
|
|
18915
19097
|
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.",
|
|
18916
19098
|
deviceType: DeviceType.Switch,
|
|
18917
19099
|
outputCap: "switch",
|
|
19100
|
+
outputField: "on",
|
|
19101
|
+
member: {
|
|
19102
|
+
cap: "switch",
|
|
19103
|
+
fieldPath: "on"
|
|
19104
|
+
},
|
|
18918
19105
|
commandCaps: ["switch"]
|
|
18919
19106
|
}),
|
|
18920
19107
|
actuator({
|
|
@@ -18922,34 +19109,136 @@ var GROUP_TEMPLATES = [
|
|
|
18922
19109
|
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.",
|
|
18923
19110
|
deviceType: DeviceType.Light,
|
|
18924
19111
|
outputCap: "switch",
|
|
19112
|
+
outputField: "on",
|
|
19113
|
+
member: {
|
|
19114
|
+
cap: "switch",
|
|
19115
|
+
fieldPath: "on"
|
|
19116
|
+
},
|
|
18925
19117
|
commandCaps: [
|
|
18926
19118
|
"switch",
|
|
18927
19119
|
"brightness",
|
|
18928
19120
|
"color"
|
|
18929
19121
|
]
|
|
19122
|
+
}),
|
|
19123
|
+
actuator({
|
|
19124
|
+
id: "fan",
|
|
19125
|
+
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.",
|
|
19126
|
+
deviceType: DeviceType.Fan,
|
|
19127
|
+
outputCap: "switch",
|
|
19128
|
+
outputField: "on",
|
|
19129
|
+
member: {
|
|
19130
|
+
cap: "switch",
|
|
19131
|
+
fieldPath: "on"
|
|
19132
|
+
},
|
|
19133
|
+
commandCaps: ["switch", "fan-control"]
|
|
19134
|
+
}),
|
|
19135
|
+
actuator({
|
|
19136
|
+
id: "cover",
|
|
19137
|
+
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.",
|
|
19138
|
+
deviceType: DeviceType.Cover,
|
|
19139
|
+
outputCap: "group-active",
|
|
19140
|
+
outputField: "active",
|
|
19141
|
+
member: {
|
|
19142
|
+
cap: "cover",
|
|
19143
|
+
fieldPath: "state"
|
|
19144
|
+
},
|
|
19145
|
+
activeWhen: [
|
|
19146
|
+
"open",
|
|
19147
|
+
"opening",
|
|
19148
|
+
"stopped"
|
|
19149
|
+
],
|
|
19150
|
+
commandCaps: ["cover"]
|
|
19151
|
+
}),
|
|
19152
|
+
actuator({
|
|
19153
|
+
id: "valve",
|
|
19154
|
+
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.",
|
|
19155
|
+
deviceType: DeviceType.Valve,
|
|
19156
|
+
outputCap: "group-active",
|
|
19157
|
+
outputField: "active",
|
|
19158
|
+
member: {
|
|
19159
|
+
cap: "valve",
|
|
19160
|
+
fieldPath: "state"
|
|
19161
|
+
},
|
|
19162
|
+
activeWhen: [
|
|
19163
|
+
"open",
|
|
19164
|
+
"opening",
|
|
19165
|
+
"stopped"
|
|
19166
|
+
],
|
|
19167
|
+
commandCaps: ["valve"]
|
|
19168
|
+
}),
|
|
19169
|
+
actuator({
|
|
19170
|
+
id: "lock",
|
|
19171
|
+
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.",
|
|
19172
|
+
deviceType: DeviceType.Lock,
|
|
19173
|
+
outputCap: "group-active",
|
|
19174
|
+
outputField: "active",
|
|
19175
|
+
member: {
|
|
19176
|
+
cap: "lock-control",
|
|
19177
|
+
fieldPath: "state"
|
|
19178
|
+
},
|
|
19179
|
+
activeWhen: ["locked"],
|
|
19180
|
+
commandCaps: ["lock-control"]
|
|
19181
|
+
}),
|
|
19182
|
+
actuator({
|
|
19183
|
+
id: "media-player",
|
|
19184
|
+
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.",
|
|
19185
|
+
deviceType: DeviceType.MediaPlayer,
|
|
19186
|
+
outputCap: "group-active",
|
|
19187
|
+
outputField: "active",
|
|
19188
|
+
member: {
|
|
19189
|
+
cap: "media-player",
|
|
19190
|
+
fieldPath: "state"
|
|
19191
|
+
},
|
|
19192
|
+
activeWhen: ["playing", "buffering"],
|
|
19193
|
+
commandCaps: ["media-player"]
|
|
19194
|
+
}),
|
|
19195
|
+
actuator({
|
|
19196
|
+
id: "climate",
|
|
19197
|
+
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.",
|
|
19198
|
+
deviceType: DeviceType.Thermostat,
|
|
19199
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
19200
|
+
outputCap: "group-active",
|
|
19201
|
+
outputField: "active",
|
|
19202
|
+
member: {
|
|
19203
|
+
cap: "climate-control",
|
|
19204
|
+
fieldPath: "mode"
|
|
19205
|
+
},
|
|
19206
|
+
activeWhen: [
|
|
19207
|
+
"heat",
|
|
19208
|
+
"cool",
|
|
19209
|
+
"auto",
|
|
19210
|
+
"heat_cool",
|
|
19211
|
+
"fan_only",
|
|
19212
|
+
"dry"
|
|
19213
|
+
],
|
|
19214
|
+
commandCaps: ["climate-control"]
|
|
18930
19215
|
})
|
|
18931
19216
|
];
|
|
18932
19217
|
function actuator(input) {
|
|
18933
19218
|
return {
|
|
18934
|
-
|
|
19219
|
+
id: input.id,
|
|
19220
|
+
summary: input.summary,
|
|
19221
|
+
deviceType: input.deviceType,
|
|
19222
|
+
outputCap: input.outputCap,
|
|
19223
|
+
outputField: input.outputField,
|
|
19224
|
+
commandCaps: input.commandCaps,
|
|
18935
19225
|
family: "actuator",
|
|
18936
19226
|
role: void 0,
|
|
18937
19227
|
memberDeviceType: input.deviceType,
|
|
18938
|
-
|
|
19228
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
19229
|
+
activeWhen: input.activeWhen,
|
|
18939
19230
|
quantity: "none",
|
|
18940
19231
|
baseUnit: void 0,
|
|
18941
19232
|
aggregates: BINARY_AGGREGATES,
|
|
18942
19233
|
defaultAggregate: "any",
|
|
18943
19234
|
empty: "offline",
|
|
18944
|
-
accept: [
|
|
18945
|
-
cap: "switch",
|
|
18946
|
-
fieldPath: "on"
|
|
18947
|
-
}],
|
|
19235
|
+
accept: [input.member],
|
|
18948
19236
|
companions: [CHANGED]
|
|
18949
19237
|
};
|
|
18950
19238
|
}
|
|
18951
19239
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18952
19240
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
19241
|
+
DeviceType.Camera;
|
|
18953
19242
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18954
19243
|
/**
|
|
18955
19244
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -46641,7 +46930,20 @@ var NcRuleInputSchema = object({
|
|
|
46641
46930
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
46642
46931
|
* path does not run Zod defaults.
|
|
46643
46932
|
*/
|
|
46644
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46933
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46934
|
+
/**
|
|
46935
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46936
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46937
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46938
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46939
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46940
|
+
*
|
|
46941
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46942
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46943
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46944
|
+
* `false`, so it needs no `clear` key.
|
|
46945
|
+
*/
|
|
46946
|
+
askVerdict: boolean().optional()
|
|
46645
46947
|
});
|
|
46646
46948
|
/**
|
|
46647
46949
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -58842,7 +59144,13 @@ results: array(object({
|
|
|
58842
59144
|
/** Ms epoch of the attempt. */
|
|
58843
59145
|
at: number()
|
|
58844
59146
|
})) });
|
|
58845
|
-
DeviceType.Switch, DeviceType.Light;
|
|
59147
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
59148
|
+
object({
|
|
59149
|
+
active: boolean().meta({ label: "Active" }),
|
|
59150
|
+
/** Ms epoch when the slice was last updated. */
|
|
59151
|
+
lastChangedAt: number()
|
|
59152
|
+
});
|
|
59153
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
58846
59154
|
object({
|
|
58847
59155
|
/** Members whose current value entered the aggregate. */
|
|
58848
59156
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -58860,7 +59168,7 @@ object({
|
|
|
58860
59168
|
label: "Members"
|
|
58861
59169
|
}))
|
|
58862
59170
|
});
|
|
58863
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
59171
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58864
59172
|
object({
|
|
58865
59173
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58866
59174
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -59767,7 +60075,14 @@ DeviceType.Lock, method(object({
|
|
|
59767
60075
|
auth: "protected"
|
|
59768
60076
|
}), method(object({
|
|
59769
60077
|
deviceId: number().int().nonnegative(),
|
|
59770
|
-
code: string().min(1).optional()
|
|
60078
|
+
code: string().min(1).optional(),
|
|
60079
|
+
/**
|
|
60080
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
60081
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
60082
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
60083
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
60084
|
+
*/
|
|
60085
|
+
confirm: boolean().optional()
|
|
59771
60086
|
}), _void(), {
|
|
59772
60087
|
kind: "mutation",
|
|
59773
60088
|
auth: "protected"
|
|
@@ -59775,6 +60090,11 @@ DeviceType.Lock, method(object({
|
|
|
59775
60090
|
kind: "mutation",
|
|
59776
60091
|
auth: "protected"
|
|
59777
60092
|
});
|
|
60093
|
+
object({
|
|
60094
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
60095
|
+
lastFetchedAt: number()
|
|
60096
|
+
});
|
|
60097
|
+
DeviceType.Sensor;
|
|
59778
60098
|
/**
|
|
59779
60099
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
59780
60100
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -64178,7 +64498,7 @@ object({
|
|
|
64178
64498
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
64179
64499
|
lastChangedAt: number()
|
|
64180
64500
|
});
|
|
64181
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
64501
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
64182
64502
|
deviceId: number(),
|
|
64183
64503
|
on: boolean()
|
|
64184
64504
|
}), _void(), {
|
|
@@ -65870,6 +66190,7 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
65870
66190
|
kind: "mutation",
|
|
65871
66191
|
auth: "admin"
|
|
65872
66192
|
});
|
|
66193
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
65873
66194
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
65874
66195
|
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;
|
|
65875
66196
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
@@ -69245,6 +69566,13 @@ Object.freeze({
|
|
|
69245
69566
|
access: "view",
|
|
69246
69567
|
role: "viewer"
|
|
69247
69568
|
},
|
|
69569
|
+
"groupActive.getStatus": {
|
|
69570
|
+
capName: "group-active",
|
|
69571
|
+
capScope: "device",
|
|
69572
|
+
addonId: null,
|
|
69573
|
+
access: "view",
|
|
69574
|
+
role: "viewer"
|
|
69575
|
+
},
|
|
69248
69576
|
"groupCommands.getStatus": {
|
|
69249
69577
|
capName: "group-commands",
|
|
69250
69578
|
capScope: "device",
|
|
@@ -70211,6 +70539,13 @@ Object.freeze({
|
|
|
70211
70539
|
access: "create",
|
|
70212
70540
|
role: "admin"
|
|
70213
70541
|
},
|
|
70542
|
+
"meter.getStatus": {
|
|
70543
|
+
capName: "meter",
|
|
70544
|
+
capScope: "device",
|
|
70545
|
+
addonId: null,
|
|
70546
|
+
access: "view",
|
|
70547
|
+
role: "viewer"
|
|
70548
|
+
},
|
|
70214
70549
|
"metricsProvider.collectSnapshot": {
|
|
70215
70550
|
capName: "metrics-provider",
|
|
70216
70551
|
capScope: "system",
|
|
@@ -79113,6 +79448,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79113
79448
|
icon: "flame"
|
|
79114
79449
|
}]
|
|
79115
79450
|
},
|
|
79451
|
+
"group-active": {
|
|
79452
|
+
scope: "device",
|
|
79453
|
+
noun: t("Group state", "Stato del gruppo")
|
|
79454
|
+
},
|
|
79116
79455
|
"group-commands": {
|
|
79117
79456
|
scope: "device",
|
|
79118
79457
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -79169,6 +79508,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79169
79508
|
}],
|
|
79170
79509
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
79171
79510
|
},
|
|
79511
|
+
meter: {
|
|
79512
|
+
scope: "device",
|
|
79513
|
+
noun: t("Meter", "Contatore"),
|
|
79514
|
+
state: [{
|
|
79515
|
+
kind: "numeric",
|
|
79516
|
+
field: "value",
|
|
79517
|
+
quantity: t("the total", "il totale"),
|
|
79518
|
+
label: t("Total", "Totale"),
|
|
79519
|
+
icon: "gauge"
|
|
79520
|
+
}]
|
|
79521
|
+
},
|
|
79172
79522
|
"numeric-sensor": {
|
|
79173
79523
|
scope: "device",
|
|
79174
79524
|
noun: t("Sensor", "Sensore"),
|
|
@@ -80648,6 +80998,11 @@ Object.freeze({
|
|
|
80648
80998
|
form: "single",
|
|
80649
80999
|
optional: false
|
|
80650
81000
|
}],
|
|
81001
|
+
"groupActive.getStatus": [{
|
|
81002
|
+
name: "deviceId",
|
|
81003
|
+
form: "single",
|
|
81004
|
+
optional: false
|
|
81005
|
+
}],
|
|
80651
81006
|
"groupCommands.getStatus": [{
|
|
80652
81007
|
name: "deviceId",
|
|
80653
81008
|
form: "single",
|
|
@@ -80858,6 +81213,11 @@ Object.freeze({
|
|
|
80858
81213
|
form: "single",
|
|
80859
81214
|
optional: false
|
|
80860
81215
|
}],
|
|
81216
|
+
"meter.getStatus": [{
|
|
81217
|
+
name: "deviceId",
|
|
81218
|
+
form: "single",
|
|
81219
|
+
optional: false
|
|
81220
|
+
}],
|
|
80861
81221
|
"motion.getStatus": [{
|
|
80862
81222
|
name: "deviceId",
|
|
80863
81223
|
form: "single",
|
|
@@ -82465,7 +82825,6 @@ Object.freeze({
|
|
|
82465
82825
|
"network-access": "ingress",
|
|
82466
82826
|
"smtp-provider": "email"
|
|
82467
82827
|
});
|
|
82468
|
-
DeviceType.Camera;
|
|
82469
82828
|
/**
|
|
82470
82829
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
82471
82830
|
* `z.infer`, they do not restate the shape.
|