@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
|
@@ -5811,7 +5811,7 @@ var ZodIssueCode = {
|
|
|
5811
5811
|
var ZodFirstPartyTypeKind;
|
|
5812
5812
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5813
5813
|
//#endregion
|
|
5814
|
-
//#region ../types/dist/sleep
|
|
5814
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5815
5815
|
/**
|
|
5816
5816
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5817
5817
|
* window to float samples (D455).
|
|
@@ -9014,6 +9014,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9014
9014
|
"filesystem-browse",
|
|
9015
9015
|
"flood",
|
|
9016
9016
|
"gas",
|
|
9017
|
+
"group-active",
|
|
9017
9018
|
"group-commands",
|
|
9018
9019
|
"group-status",
|
|
9019
9020
|
"heating-valve",
|
|
@@ -9036,6 +9037,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9036
9037
|
"login-method",
|
|
9037
9038
|
"media-player",
|
|
9038
9039
|
"mesh-network",
|
|
9040
|
+
"meter",
|
|
9039
9041
|
"metrics-provider",
|
|
9040
9042
|
"model-convert",
|
|
9041
9043
|
"model-distributor",
|
|
@@ -9834,6 +9836,10 @@ Object.freeze({
|
|
|
9834
9836
|
"path": "detected",
|
|
9835
9837
|
"valueType": "boolean"
|
|
9836
9838
|
}],
|
|
9839
|
+
"group-active": [{
|
|
9840
|
+
"path": "active",
|
|
9841
|
+
"valueType": "boolean"
|
|
9842
|
+
}],
|
|
9837
9843
|
"group-status": [
|
|
9838
9844
|
{
|
|
9839
9845
|
"path": "included",
|
|
@@ -10093,6 +10099,10 @@ Object.freeze({
|
|
|
10093
10099
|
]
|
|
10094
10100
|
}
|
|
10095
10101
|
],
|
|
10102
|
+
"meter": [{
|
|
10103
|
+
"path": "value",
|
|
10104
|
+
"valueType": "number"
|
|
10105
|
+
}],
|
|
10096
10106
|
"motion": [
|
|
10097
10107
|
{
|
|
10098
10108
|
"path": "detected",
|
|
@@ -11185,7 +11195,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11185
11195
|
return DeviceRole;
|
|
11186
11196
|
}({});
|
|
11187
11197
|
//#endregion
|
|
11188
|
-
//#region ../types/dist/composition-
|
|
11198
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
11189
11199
|
/**
|
|
11190
11200
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11191
11201
|
*
|
|
@@ -11500,6 +11510,13 @@ var table = {
|
|
|
11500
11510
|
apply: () => {
|
|
11501
11511
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11502
11512
|
}
|
|
11513
|
+
},
|
|
11514
|
+
schmitt: {
|
|
11515
|
+
minArgs: 3,
|
|
11516
|
+
maxArgs: 5,
|
|
11517
|
+
apply: () => {
|
|
11518
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11519
|
+
}
|
|
11503
11520
|
}
|
|
11504
11521
|
};
|
|
11505
11522
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11961,6 +11978,79 @@ var APPLIANCE_KINDS = [
|
|
|
11961
11978
|
];
|
|
11962
11979
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11963
11980
|
/**
|
|
11981
|
+
* Statistics and integrals over a history read (D944).
|
|
11982
|
+
*
|
|
11983
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11984
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11985
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11986
|
+
* as zero. A truncated read is not published.
|
|
11987
|
+
*/
|
|
11988
|
+
var STATISTIC_STATS = [
|
|
11989
|
+
"min",
|
|
11990
|
+
"max",
|
|
11991
|
+
"mean",
|
|
11992
|
+
"sum",
|
|
11993
|
+
"count",
|
|
11994
|
+
"change"
|
|
11995
|
+
];
|
|
11996
|
+
/**
|
|
11997
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11998
|
+
*
|
|
11999
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
12000
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
12001
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
12002
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
12003
|
+
*/
|
|
12004
|
+
var MINUTE_MS = 6e4;
|
|
12005
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
12006
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
12007
|
+
var ROLLING_SPANS = [
|
|
12008
|
+
"1h",
|
|
12009
|
+
"24h",
|
|
12010
|
+
"2d",
|
|
12011
|
+
"7d",
|
|
12012
|
+
"30d",
|
|
12013
|
+
"custom"
|
|
12014
|
+
];
|
|
12015
|
+
var CALENDAR_PERIODS = [
|
|
12016
|
+
"today",
|
|
12017
|
+
"yesterday",
|
|
12018
|
+
"this-week",
|
|
12019
|
+
"this-month"
|
|
12020
|
+
];
|
|
12021
|
+
var RESET_PERIODS = [
|
|
12022
|
+
"never",
|
|
12023
|
+
"daily",
|
|
12024
|
+
"weekly",
|
|
12025
|
+
"monthly"
|
|
12026
|
+
];
|
|
12027
|
+
5 * MINUTE_MS;
|
|
12028
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
12029
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
12030
|
+
var rollingWindowObject = object({
|
|
12031
|
+
kind: literal("rolling"),
|
|
12032
|
+
span: _enum(ROLLING_SPANS),
|
|
12033
|
+
customMinutes: number().int().min(5).optional()
|
|
12034
|
+
}).check((payload) => {
|
|
12035
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
12036
|
+
code: "custom",
|
|
12037
|
+
message: "a custom range needs a duration in minutes",
|
|
12038
|
+
path: ["customMinutes"],
|
|
12039
|
+
input: payload.value
|
|
12040
|
+
});
|
|
12041
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
12042
|
+
code: "custom",
|
|
12043
|
+
message: "only a custom range carries a duration",
|
|
12044
|
+
path: ["customMinutes"],
|
|
12045
|
+
input: payload.value
|
|
12046
|
+
});
|
|
12047
|
+
});
|
|
12048
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
12049
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
12050
|
+
kind: literal("calendar"),
|
|
12051
|
+
period: _enum(CALENDAR_PERIODS)
|
|
12052
|
+
})]);
|
|
12053
|
+
/**
|
|
11964
12054
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11965
12055
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11966
12056
|
* `composition.ts` (D659).
|
|
@@ -11986,7 +12076,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11986
12076
|
"occupancy",
|
|
11987
12077
|
"binary",
|
|
11988
12078
|
"switch",
|
|
11989
|
-
"light"
|
|
12079
|
+
"light",
|
|
12080
|
+
"fan",
|
|
12081
|
+
"cover",
|
|
12082
|
+
"valve",
|
|
12083
|
+
"lock",
|
|
12084
|
+
"media-player",
|
|
12085
|
+
"climate"
|
|
11990
12086
|
];
|
|
11991
12087
|
var NUMERIC_AGGREGATES = [
|
|
11992
12088
|
"mean",
|
|
@@ -12016,22 +12112,73 @@ var HelperMemberSchema = object({
|
|
|
12016
12112
|
cap: string().min(1),
|
|
12017
12113
|
fieldPath: string().min(1)
|
|
12018
12114
|
});
|
|
12019
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12115
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
12116
|
+
object({
|
|
12117
|
+
kind: literal("group"),
|
|
12118
|
+
templateId: GroupTemplateIdSchema,
|
|
12119
|
+
aggregate: AggregateReducerSchema,
|
|
12120
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
12121
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
12122
|
+
active: ActiveCriterionSchema.optional()
|
|
12123
|
+
}),
|
|
12124
|
+
object({
|
|
12125
|
+
kind: literal("appliance"),
|
|
12126
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
12127
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
12128
|
+
thresholdWatts: number().positive(),
|
|
12129
|
+
startDwellMs: number().int().nonnegative(),
|
|
12130
|
+
stopDwellMs: number().int().nonnegative(),
|
|
12131
|
+
member: HelperMemberSchema
|
|
12132
|
+
}),
|
|
12133
|
+
object({
|
|
12134
|
+
kind: literal("statistic"),
|
|
12135
|
+
stat: _enum(STATISTIC_STATS),
|
|
12136
|
+
window: StatisticWindowSchema,
|
|
12137
|
+
source: HelperMemberSchema
|
|
12138
|
+
}),
|
|
12139
|
+
object({
|
|
12140
|
+
kind: literal("integral"),
|
|
12141
|
+
reset: _enum(RESET_PERIODS),
|
|
12142
|
+
output: _enum(["energy", "meter"]),
|
|
12143
|
+
source: HelperMemberSchema
|
|
12144
|
+
}),
|
|
12145
|
+
object({
|
|
12146
|
+
kind: literal("threshold"),
|
|
12147
|
+
source: HelperMemberSchema,
|
|
12148
|
+
high: number(),
|
|
12149
|
+
low: number(),
|
|
12150
|
+
onForMs: number().int().nonnegative(),
|
|
12151
|
+
offForMs: number().int().nonnegative()
|
|
12152
|
+
}),
|
|
12153
|
+
object({
|
|
12154
|
+
kind: literal("arithmetic"),
|
|
12155
|
+
op: _enum([
|
|
12156
|
+
"sum",
|
|
12157
|
+
"difference",
|
|
12158
|
+
"ratio"
|
|
12159
|
+
]),
|
|
12160
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
12161
|
+
}),
|
|
12162
|
+
object({
|
|
12163
|
+
kind: literal("expression"),
|
|
12164
|
+
expr: string().min(1),
|
|
12165
|
+
inputs: array(object({
|
|
12166
|
+
name: string().min(1),
|
|
12167
|
+
member: HelperMemberSchema
|
|
12168
|
+
})).min(1).max(64),
|
|
12169
|
+
output: _enum(["number", "boolean"])
|
|
12170
|
+
}),
|
|
12171
|
+
object({
|
|
12172
|
+
kind: literal("derivative"),
|
|
12173
|
+
window: RollingWindowSchema,
|
|
12174
|
+
per: _enum([
|
|
12175
|
+
"second",
|
|
12176
|
+
"minute",
|
|
12177
|
+
"hour"
|
|
12178
|
+
]),
|
|
12179
|
+
source: HelperMemberSchema
|
|
12180
|
+
})
|
|
12181
|
+
]);
|
|
12035
12182
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
12036
12183
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
12037
12184
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -12092,6 +12239,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12092
12239
|
"all"
|
|
12093
12240
|
]),
|
|
12094
12241
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12242
|
+
/**
|
|
12243
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
12244
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
12245
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
12246
|
+
*/
|
|
12247
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
12095
12248
|
/** `value` is the reading; the others are the member counts. */
|
|
12096
12249
|
publish: _enum([
|
|
12097
12250
|
"value",
|
|
@@ -12105,6 +12258,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
12105
12258
|
"omit",
|
|
12106
12259
|
"offline"
|
|
12107
12260
|
])
|
|
12261
|
+
}),
|
|
12262
|
+
object({
|
|
12263
|
+
kind: literal("series"),
|
|
12264
|
+
read: CompositionFieldReadSchema,
|
|
12265
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
12266
|
+
publish: _enum([
|
|
12267
|
+
"value",
|
|
12268
|
+
"included",
|
|
12269
|
+
"excluded",
|
|
12270
|
+
"total"
|
|
12271
|
+
]),
|
|
12272
|
+
/**
|
|
12273
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
12274
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
12275
|
+
*/
|
|
12276
|
+
empty: _enum([
|
|
12277
|
+
"null",
|
|
12278
|
+
"omit",
|
|
12279
|
+
"offline"
|
|
12280
|
+
])
|
|
12108
12281
|
})
|
|
12109
12282
|
]);
|
|
12110
12283
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -18419,7 +18592,8 @@ var CompositionProblemSchema = object({
|
|
|
18419
18592
|
"native-capability-replace",
|
|
18420
18593
|
"mixed-quantity",
|
|
18421
18594
|
"helper-mismatch",
|
|
18422
|
-
"member-constraint"
|
|
18595
|
+
"member-constraint",
|
|
18596
|
+
"retention"
|
|
18423
18597
|
]),
|
|
18424
18598
|
path: string(),
|
|
18425
18599
|
message: string()
|
|
@@ -18653,13 +18827,17 @@ Object.freeze({
|
|
|
18653
18827
|
latchedAt: {
|
|
18654
18828
|
kind: "fixed",
|
|
18655
18829
|
result: ["number", "null"]
|
|
18830
|
+
},
|
|
18831
|
+
schmitt: {
|
|
18832
|
+
kind: "fixed",
|
|
18833
|
+
result: ["boolean", "null"]
|
|
18656
18834
|
}
|
|
18657
18835
|
});
|
|
18658
18836
|
/**
|
|
18659
18837
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18660
18838
|
* Data, not a form default written into the block.
|
|
18661
18839
|
*/
|
|
18662
|
-
var NOW = {
|
|
18840
|
+
var NOW$2 = {
|
|
18663
18841
|
fieldPath: "lastFetchedAt",
|
|
18664
18842
|
expr: "now"
|
|
18665
18843
|
};
|
|
@@ -18673,6 +18851,8 @@ function numeric(input) {
|
|
|
18673
18851
|
family: "numeric",
|
|
18674
18852
|
deviceType: DeviceType.Sensor,
|
|
18675
18853
|
memberDeviceType: DeviceType.Sensor,
|
|
18854
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18855
|
+
activeWhen: void 0,
|
|
18676
18856
|
commandCaps: [],
|
|
18677
18857
|
baseUnit: baseUnitOf(input.quantity),
|
|
18678
18858
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18688,6 +18868,8 @@ function binary(input) {
|
|
|
18688
18868
|
family: "binary",
|
|
18689
18869
|
deviceType: DeviceType.Sensor,
|
|
18690
18870
|
memberDeviceType: DeviceType.Sensor,
|
|
18871
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18872
|
+
activeWhen: void 0,
|
|
18691
18873
|
commandCaps: [],
|
|
18692
18874
|
quantity: "none",
|
|
18693
18875
|
baseUnit: void 0,
|
|
@@ -18705,7 +18887,7 @@ var GROUP_TEMPLATES = [
|
|
|
18705
18887
|
quantity: "temperature",
|
|
18706
18888
|
defaultAggregate: "mean",
|
|
18707
18889
|
empty: "null",
|
|
18708
|
-
companions: [NOW]
|
|
18890
|
+
companions: [NOW$2]
|
|
18709
18891
|
}),
|
|
18710
18892
|
numeric({
|
|
18711
18893
|
id: "humidity",
|
|
@@ -18716,7 +18898,7 @@ var GROUP_TEMPLATES = [
|
|
|
18716
18898
|
quantity: "humidity",
|
|
18717
18899
|
defaultAggregate: "mean",
|
|
18718
18900
|
empty: "null",
|
|
18719
|
-
companions: [NOW]
|
|
18901
|
+
companions: [NOW$2]
|
|
18720
18902
|
}),
|
|
18721
18903
|
numeric({
|
|
18722
18904
|
id: "pressure",
|
|
@@ -18727,7 +18909,7 @@ var GROUP_TEMPLATES = [
|
|
|
18727
18909
|
quantity: "pressure",
|
|
18728
18910
|
defaultAggregate: "mean",
|
|
18729
18911
|
empty: "null",
|
|
18730
|
-
companions: [NOW]
|
|
18912
|
+
companions: [NOW$2]
|
|
18731
18913
|
}),
|
|
18732
18914
|
numeric({
|
|
18733
18915
|
id: "illuminance",
|
|
@@ -18738,7 +18920,7 @@ var GROUP_TEMPLATES = [
|
|
|
18738
18920
|
quantity: "illuminance",
|
|
18739
18921
|
defaultAggregate: "mean",
|
|
18740
18922
|
empty: "null",
|
|
18741
|
-
companions: [NOW]
|
|
18923
|
+
companions: [NOW$2]
|
|
18742
18924
|
}),
|
|
18743
18925
|
numeric({
|
|
18744
18926
|
id: "power",
|
|
@@ -18749,7 +18931,7 @@ var GROUP_TEMPLATES = [
|
|
|
18749
18931
|
quantity: "power",
|
|
18750
18932
|
defaultAggregate: "sum",
|
|
18751
18933
|
empty: "omit",
|
|
18752
|
-
companions: [NOW]
|
|
18934
|
+
companions: [NOW$2]
|
|
18753
18935
|
}),
|
|
18754
18936
|
numeric({
|
|
18755
18937
|
id: "energy",
|
|
@@ -18760,7 +18942,7 @@ var GROUP_TEMPLATES = [
|
|
|
18760
18942
|
quantity: "energy",
|
|
18761
18943
|
defaultAggregate: "sum",
|
|
18762
18944
|
empty: "omit",
|
|
18763
|
-
companions: [NOW]
|
|
18945
|
+
companions: [NOW$2]
|
|
18764
18946
|
}),
|
|
18765
18947
|
numeric({
|
|
18766
18948
|
id: "battery",
|
|
@@ -18795,7 +18977,7 @@ var GROUP_TEMPLATES = [
|
|
|
18795
18977
|
quantity: "device",
|
|
18796
18978
|
defaultAggregate: "mean",
|
|
18797
18979
|
empty: "null",
|
|
18798
|
-
companions: [NOW]
|
|
18980
|
+
companions: [NOW$2]
|
|
18799
18981
|
}),
|
|
18800
18982
|
binary({
|
|
18801
18983
|
id: "motion",
|
|
@@ -18889,6 +19071,11 @@ var GROUP_TEMPLATES = [
|
|
|
18889
19071
|
summary: "On when at least one switch is on, or when all of them are. Offline and unknown members are left out of that decision, never read as off, and still receive the command.",
|
|
18890
19072
|
deviceType: DeviceType.Switch,
|
|
18891
19073
|
outputCap: "switch",
|
|
19074
|
+
outputField: "on",
|
|
19075
|
+
member: {
|
|
19076
|
+
cap: "switch",
|
|
19077
|
+
fieldPath: "on"
|
|
19078
|
+
},
|
|
18892
19079
|
commandCaps: ["switch"]
|
|
18893
19080
|
}),
|
|
18894
19081
|
actuator({
|
|
@@ -18896,34 +19083,136 @@ var GROUP_TEMPLATES = [
|
|
|
18896
19083
|
summary: "On when at least one light is on, or when all of them are. Brightness and colour are offered only when every member has them. A command is not sent to a member that lacks it.",
|
|
18897
19084
|
deviceType: DeviceType.Light,
|
|
18898
19085
|
outputCap: "switch",
|
|
19086
|
+
outputField: "on",
|
|
19087
|
+
member: {
|
|
19088
|
+
cap: "switch",
|
|
19089
|
+
fieldPath: "on"
|
|
19090
|
+
},
|
|
18899
19091
|
commandCaps: [
|
|
18900
19092
|
"switch",
|
|
18901
19093
|
"brightness",
|
|
18902
19094
|
"color"
|
|
18903
19095
|
]
|
|
19096
|
+
}),
|
|
19097
|
+
actuator({
|
|
19098
|
+
id: "fan",
|
|
19099
|
+
summary: "On when at least one fan is on, or when all of them are. Speed, preset, direction and oscillation are offered only when every fan has them. A command is not sent to a fan that lacks it.",
|
|
19100
|
+
deviceType: DeviceType.Fan,
|
|
19101
|
+
outputCap: "switch",
|
|
19102
|
+
outputField: "on",
|
|
19103
|
+
member: {
|
|
19104
|
+
cap: "switch",
|
|
19105
|
+
fieldPath: "on"
|
|
19106
|
+
},
|
|
19107
|
+
commandCaps: ["switch", "fan-control"]
|
|
19108
|
+
}),
|
|
19109
|
+
actuator({
|
|
19110
|
+
id: "cover",
|
|
19111
|
+
summary: "Open when at least one cover is open or part-open, or only when all of them are. Position and tilt are offered only when every cover has them. A cover that reports nothing is left out, never read as closed.",
|
|
19112
|
+
deviceType: DeviceType.Cover,
|
|
19113
|
+
outputCap: "group-active",
|
|
19114
|
+
outputField: "active",
|
|
19115
|
+
member: {
|
|
19116
|
+
cap: "cover",
|
|
19117
|
+
fieldPath: "state"
|
|
19118
|
+
},
|
|
19119
|
+
activeWhen: [
|
|
19120
|
+
"open",
|
|
19121
|
+
"opening",
|
|
19122
|
+
"stopped"
|
|
19123
|
+
],
|
|
19124
|
+
commandCaps: ["cover"]
|
|
19125
|
+
}),
|
|
19126
|
+
actuator({
|
|
19127
|
+
id: "valve",
|
|
19128
|
+
summary: "Open when at least one valve is open or part-open, or only when all of them are. Position is offered only when every valve has it. A valve that reports nothing is left out, never read as closed.",
|
|
19129
|
+
deviceType: DeviceType.Valve,
|
|
19130
|
+
outputCap: "group-active",
|
|
19131
|
+
outputField: "active",
|
|
19132
|
+
member: {
|
|
19133
|
+
cap: "valve",
|
|
19134
|
+
fieldPath: "state"
|
|
19135
|
+
},
|
|
19136
|
+
activeWhen: [
|
|
19137
|
+
"open",
|
|
19138
|
+
"opening",
|
|
19139
|
+
"stopped"
|
|
19140
|
+
],
|
|
19141
|
+
commandCaps: ["valve"]
|
|
19142
|
+
}),
|
|
19143
|
+
actuator({
|
|
19144
|
+
id: "lock",
|
|
19145
|
+
summary: "Locked when at least one lock is locked, or only when all of them are. A jammed or moving lock is not locked. Locking is one tap; unlocking the group needs a confirmation every time, and nothing is sent without it.",
|
|
19146
|
+
deviceType: DeviceType.Lock,
|
|
19147
|
+
outputCap: "group-active",
|
|
19148
|
+
outputField: "active",
|
|
19149
|
+
member: {
|
|
19150
|
+
cap: "lock-control",
|
|
19151
|
+
fieldPath: "state"
|
|
19152
|
+
},
|
|
19153
|
+
activeWhen: ["locked"],
|
|
19154
|
+
commandCaps: ["lock-control"]
|
|
19155
|
+
}),
|
|
19156
|
+
actuator({
|
|
19157
|
+
id: "media-player",
|
|
19158
|
+
summary: "Playing when at least one player is playing, or only when all of them are. Volume is offered only when every player has it. A player that reports nothing is left out, never read as stopped.",
|
|
19159
|
+
deviceType: DeviceType.MediaPlayer,
|
|
19160
|
+
outputCap: "group-active",
|
|
19161
|
+
outputField: "active",
|
|
19162
|
+
member: {
|
|
19163
|
+
cap: "media-player",
|
|
19164
|
+
fieldPath: "state"
|
|
19165
|
+
},
|
|
19166
|
+
activeWhen: ["playing", "buffering"],
|
|
19167
|
+
commandCaps: ["media-player"]
|
|
19168
|
+
}),
|
|
19169
|
+
actuator({
|
|
19170
|
+
id: "climate",
|
|
19171
|
+
summary: "Running when at least one thermostat or air conditioner is not off, or only when all of them are. Target temperature and fan are offered only when every device has them. A device that reports nothing is left out, never read as off.",
|
|
19172
|
+
deviceType: DeviceType.Thermostat,
|
|
19173
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
19174
|
+
outputCap: "group-active",
|
|
19175
|
+
outputField: "active",
|
|
19176
|
+
member: {
|
|
19177
|
+
cap: "climate-control",
|
|
19178
|
+
fieldPath: "mode"
|
|
19179
|
+
},
|
|
19180
|
+
activeWhen: [
|
|
19181
|
+
"heat",
|
|
19182
|
+
"cool",
|
|
19183
|
+
"auto",
|
|
19184
|
+
"heat_cool",
|
|
19185
|
+
"fan_only",
|
|
19186
|
+
"dry"
|
|
19187
|
+
],
|
|
19188
|
+
commandCaps: ["climate-control"]
|
|
18904
19189
|
})
|
|
18905
19190
|
];
|
|
18906
19191
|
function actuator(input) {
|
|
18907
19192
|
return {
|
|
18908
|
-
|
|
19193
|
+
id: input.id,
|
|
19194
|
+
summary: input.summary,
|
|
19195
|
+
deviceType: input.deviceType,
|
|
19196
|
+
outputCap: input.outputCap,
|
|
19197
|
+
outputField: input.outputField,
|
|
19198
|
+
commandCaps: input.commandCaps,
|
|
18909
19199
|
family: "actuator",
|
|
18910
19200
|
role: void 0,
|
|
18911
19201
|
memberDeviceType: input.deviceType,
|
|
18912
|
-
|
|
19202
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
19203
|
+
activeWhen: input.activeWhen,
|
|
18913
19204
|
quantity: "none",
|
|
18914
19205
|
baseUnit: void 0,
|
|
18915
19206
|
aggregates: BINARY_AGGREGATES,
|
|
18916
19207
|
defaultAggregate: "any",
|
|
18917
19208
|
empty: "offline",
|
|
18918
|
-
accept: [
|
|
18919
|
-
cap: "switch",
|
|
18920
|
-
fieldPath: "on"
|
|
18921
|
-
}],
|
|
19209
|
+
accept: [input.member],
|
|
18922
19210
|
companions: [CHANGED]
|
|
18923
19211
|
};
|
|
18924
19212
|
}
|
|
18925
19213
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18926
19214
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
19215
|
+
DeviceType.Camera;
|
|
18927
19216
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18928
19217
|
/**
|
|
18929
19218
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -46615,7 +46904,20 @@ var NcRuleInputSchema = object({
|
|
|
46615
46904
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
46616
46905
|
* path does not run Zod defaults.
|
|
46617
46906
|
*/
|
|
46618
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46907
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46908
|
+
/**
|
|
46909
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46910
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46911
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46912
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46913
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46914
|
+
*
|
|
46915
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46916
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46917
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46918
|
+
* `false`, so it needs no `clear` key.
|
|
46919
|
+
*/
|
|
46920
|
+
askVerdict: boolean().optional()
|
|
46619
46921
|
});
|
|
46620
46922
|
/**
|
|
46621
46923
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -58816,7 +59118,13 @@ results: array(object({
|
|
|
58816
59118
|
/** Ms epoch of the attempt. */
|
|
58817
59119
|
at: number()
|
|
58818
59120
|
})) });
|
|
58819
|
-
DeviceType.Switch, DeviceType.Light;
|
|
59121
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
59122
|
+
object({
|
|
59123
|
+
active: boolean().meta({ label: "Active" }),
|
|
59124
|
+
/** Ms epoch when the slice was last updated. */
|
|
59125
|
+
lastChangedAt: number()
|
|
59126
|
+
});
|
|
59127
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
58820
59128
|
object({
|
|
58821
59129
|
/** Members whose current value entered the aggregate. */
|
|
58822
59130
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -58834,7 +59142,7 @@ object({
|
|
|
58834
59142
|
label: "Members"
|
|
58835
59143
|
}))
|
|
58836
59144
|
});
|
|
58837
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
59145
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58838
59146
|
object({
|
|
58839
59147
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58840
59148
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -59741,7 +60049,14 @@ DeviceType.Lock, method(object({
|
|
|
59741
60049
|
auth: "protected"
|
|
59742
60050
|
}), method(object({
|
|
59743
60051
|
deviceId: number().int().nonnegative(),
|
|
59744
|
-
code: string().min(1).optional()
|
|
60052
|
+
code: string().min(1).optional(),
|
|
60053
|
+
/**
|
|
60054
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
60055
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
60056
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
60057
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
60058
|
+
*/
|
|
60059
|
+
confirm: boolean().optional()
|
|
59745
60060
|
}), _void(), {
|
|
59746
60061
|
kind: "mutation",
|
|
59747
60062
|
auth: "protected"
|
|
@@ -59749,6 +60064,11 @@ DeviceType.Lock, method(object({
|
|
|
59749
60064
|
kind: "mutation",
|
|
59750
60065
|
auth: "protected"
|
|
59751
60066
|
});
|
|
60067
|
+
object({
|
|
60068
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
60069
|
+
lastFetchedAt: number()
|
|
60070
|
+
});
|
|
60071
|
+
DeviceType.Sensor;
|
|
59752
60072
|
/**
|
|
59753
60073
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
59754
60074
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -64152,7 +64472,7 @@ object({
|
|
|
64152
64472
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
64153
64473
|
lastChangedAt: number()
|
|
64154
64474
|
});
|
|
64155
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
64475
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
64156
64476
|
deviceId: number(),
|
|
64157
64477
|
on: boolean()
|
|
64158
64478
|
}), _void(), {
|
|
@@ -65844,6 +66164,7 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
65844
66164
|
kind: "mutation",
|
|
65845
66165
|
auth: "admin"
|
|
65846
66166
|
});
|
|
66167
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
65847
66168
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
65848
66169
|
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;
|
|
65849
66170
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
@@ -69219,6 +69540,13 @@ Object.freeze({
|
|
|
69219
69540
|
access: "view",
|
|
69220
69541
|
role: "viewer"
|
|
69221
69542
|
},
|
|
69543
|
+
"groupActive.getStatus": {
|
|
69544
|
+
capName: "group-active",
|
|
69545
|
+
capScope: "device",
|
|
69546
|
+
addonId: null,
|
|
69547
|
+
access: "view",
|
|
69548
|
+
role: "viewer"
|
|
69549
|
+
},
|
|
69222
69550
|
"groupCommands.getStatus": {
|
|
69223
69551
|
capName: "group-commands",
|
|
69224
69552
|
capScope: "device",
|
|
@@ -70185,6 +70513,13 @@ Object.freeze({
|
|
|
70185
70513
|
access: "create",
|
|
70186
70514
|
role: "admin"
|
|
70187
70515
|
},
|
|
70516
|
+
"meter.getStatus": {
|
|
70517
|
+
capName: "meter",
|
|
70518
|
+
capScope: "device",
|
|
70519
|
+
addonId: null,
|
|
70520
|
+
access: "view",
|
|
70521
|
+
role: "viewer"
|
|
70522
|
+
},
|
|
70188
70523
|
"metricsProvider.collectSnapshot": {
|
|
70189
70524
|
capName: "metrics-provider",
|
|
70190
70525
|
capScope: "system",
|
|
@@ -79087,6 +79422,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79087
79422
|
icon: "flame"
|
|
79088
79423
|
}]
|
|
79089
79424
|
},
|
|
79425
|
+
"group-active": {
|
|
79426
|
+
scope: "device",
|
|
79427
|
+
noun: t("Group state", "Stato del gruppo")
|
|
79428
|
+
},
|
|
79090
79429
|
"group-commands": {
|
|
79091
79430
|
scope: "device",
|
|
79092
79431
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -79143,6 +79482,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79143
79482
|
}],
|
|
79144
79483
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
79145
79484
|
},
|
|
79485
|
+
meter: {
|
|
79486
|
+
scope: "device",
|
|
79487
|
+
noun: t("Meter", "Contatore"),
|
|
79488
|
+
state: [{
|
|
79489
|
+
kind: "numeric",
|
|
79490
|
+
field: "value",
|
|
79491
|
+
quantity: t("the total", "il totale"),
|
|
79492
|
+
label: t("Total", "Totale"),
|
|
79493
|
+
icon: "gauge"
|
|
79494
|
+
}]
|
|
79495
|
+
},
|
|
79146
79496
|
"numeric-sensor": {
|
|
79147
79497
|
scope: "device",
|
|
79148
79498
|
noun: t("Sensor", "Sensore"),
|
|
@@ -80622,6 +80972,11 @@ Object.freeze({
|
|
|
80622
80972
|
form: "single",
|
|
80623
80973
|
optional: false
|
|
80624
80974
|
}],
|
|
80975
|
+
"groupActive.getStatus": [{
|
|
80976
|
+
name: "deviceId",
|
|
80977
|
+
form: "single",
|
|
80978
|
+
optional: false
|
|
80979
|
+
}],
|
|
80625
80980
|
"groupCommands.getStatus": [{
|
|
80626
80981
|
name: "deviceId",
|
|
80627
80982
|
form: "single",
|
|
@@ -80832,6 +81187,11 @@ Object.freeze({
|
|
|
80832
81187
|
form: "single",
|
|
80833
81188
|
optional: false
|
|
80834
81189
|
}],
|
|
81190
|
+
"meter.getStatus": [{
|
|
81191
|
+
name: "deviceId",
|
|
81192
|
+
form: "single",
|
|
81193
|
+
optional: false
|
|
81194
|
+
}],
|
|
80835
81195
|
"motion.getStatus": [{
|
|
80836
81196
|
name: "deviceId",
|
|
80837
81197
|
form: "single",
|
|
@@ -82439,7 +82799,6 @@ Object.freeze({
|
|
|
82439
82799
|
"network-access": "ingress",
|
|
82440
82800
|
"smtp-provider": "email"
|
|
82441
82801
|
});
|
|
82442
|
-
DeviceType.Camera;
|
|
82443
82802
|
/**
|
|
82444
82803
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
82445
82804
|
* `z.infer`, they do not restate the shape.
|