@camstack/addon-agent-ui 1.2.276 → 1.2.278
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/addon.js +400 -41
- package/dist/assets/{MotionZonesSettings-B23u6ol9.js → MotionZonesSettings-Dgi9UrKL.js} +1 -1
- package/dist/assets/{PrivacyMaskSettings-qEzemBbJ.js → PrivacyMaskSettings-BX9fG-ou.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-7f_5a0G1.js → SceneMonitorEditor-BFSsQU7D.js} +1 -1
- package/dist/assets/index-Cf9eOmk0.js +112 -0
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/dist/assets/index-BrlSy67F.js +0 -112
package/dist/addon.js
CHANGED
|
@@ -5443,7 +5443,7 @@ var ZodIssueCode = {
|
|
|
5443
5443
|
var ZodFirstPartyTypeKind;
|
|
5444
5444
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5445
5445
|
//#endregion
|
|
5446
|
-
//#region ../types/dist/sleep
|
|
5446
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5447
5447
|
/**
|
|
5448
5448
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5449
5449
|
* window to float samples (D455).
|
|
@@ -8583,6 +8583,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8583
8583
|
"filesystem-browse",
|
|
8584
8584
|
"flood",
|
|
8585
8585
|
"gas",
|
|
8586
|
+
"group-active",
|
|
8586
8587
|
"group-commands",
|
|
8587
8588
|
"group-status",
|
|
8588
8589
|
"heating-valve",
|
|
@@ -8605,6 +8606,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8605
8606
|
"login-method",
|
|
8606
8607
|
"media-player",
|
|
8607
8608
|
"mesh-network",
|
|
8609
|
+
"meter",
|
|
8608
8610
|
"metrics-provider",
|
|
8609
8611
|
"model-convert",
|
|
8610
8612
|
"model-distributor",
|
|
@@ -9403,6 +9405,10 @@ Object.freeze({
|
|
|
9403
9405
|
"path": "detected",
|
|
9404
9406
|
"valueType": "boolean"
|
|
9405
9407
|
}],
|
|
9408
|
+
"group-active": [{
|
|
9409
|
+
"path": "active",
|
|
9410
|
+
"valueType": "boolean"
|
|
9411
|
+
}],
|
|
9406
9412
|
"group-status": [
|
|
9407
9413
|
{
|
|
9408
9414
|
"path": "included",
|
|
@@ -9662,6 +9668,10 @@ Object.freeze({
|
|
|
9662
9668
|
]
|
|
9663
9669
|
}
|
|
9664
9670
|
],
|
|
9671
|
+
"meter": [{
|
|
9672
|
+
"path": "value",
|
|
9673
|
+
"valueType": "number"
|
|
9674
|
+
}],
|
|
9665
9675
|
"motion": [
|
|
9666
9676
|
{
|
|
9667
9677
|
"path": "detected",
|
|
@@ -10754,7 +10764,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10754
10764
|
return DeviceRole;
|
|
10755
10765
|
}({});
|
|
10756
10766
|
//#endregion
|
|
10757
|
-
//#region ../types/dist/composition-
|
|
10767
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
10758
10768
|
/**
|
|
10759
10769
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10760
10770
|
*
|
|
@@ -11069,6 +11079,13 @@ var table = {
|
|
|
11069
11079
|
apply: () => {
|
|
11070
11080
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11071
11081
|
}
|
|
11082
|
+
},
|
|
11083
|
+
schmitt: {
|
|
11084
|
+
minArgs: 3,
|
|
11085
|
+
maxArgs: 5,
|
|
11086
|
+
apply: () => {
|
|
11087
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11088
|
+
}
|
|
11072
11089
|
}
|
|
11073
11090
|
};
|
|
11074
11091
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11530,6 +11547,79 @@ var APPLIANCE_KINDS = [
|
|
|
11530
11547
|
];
|
|
11531
11548
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11532
11549
|
/**
|
|
11550
|
+
* Statistics and integrals over a history read (D944).
|
|
11551
|
+
*
|
|
11552
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11553
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11554
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11555
|
+
* as zero. A truncated read is not published.
|
|
11556
|
+
*/
|
|
11557
|
+
var STATISTIC_STATS = [
|
|
11558
|
+
"min",
|
|
11559
|
+
"max",
|
|
11560
|
+
"mean",
|
|
11561
|
+
"sum",
|
|
11562
|
+
"count",
|
|
11563
|
+
"change"
|
|
11564
|
+
];
|
|
11565
|
+
/**
|
|
11566
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11567
|
+
*
|
|
11568
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11569
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11570
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11571
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11572
|
+
*/
|
|
11573
|
+
var MINUTE_MS = 6e4;
|
|
11574
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11575
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11576
|
+
var ROLLING_SPANS = [
|
|
11577
|
+
"1h",
|
|
11578
|
+
"24h",
|
|
11579
|
+
"2d",
|
|
11580
|
+
"7d",
|
|
11581
|
+
"30d",
|
|
11582
|
+
"custom"
|
|
11583
|
+
];
|
|
11584
|
+
var CALENDAR_PERIODS = [
|
|
11585
|
+
"today",
|
|
11586
|
+
"yesterday",
|
|
11587
|
+
"this-week",
|
|
11588
|
+
"this-month"
|
|
11589
|
+
];
|
|
11590
|
+
var RESET_PERIODS = [
|
|
11591
|
+
"never",
|
|
11592
|
+
"daily",
|
|
11593
|
+
"weekly",
|
|
11594
|
+
"monthly"
|
|
11595
|
+
];
|
|
11596
|
+
5 * MINUTE_MS;
|
|
11597
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11598
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11599
|
+
var rollingWindowObject = object({
|
|
11600
|
+
kind: literal("rolling"),
|
|
11601
|
+
span: _enum(ROLLING_SPANS),
|
|
11602
|
+
customMinutes: number().int().min(5).optional()
|
|
11603
|
+
}).check((payload) => {
|
|
11604
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11605
|
+
code: "custom",
|
|
11606
|
+
message: "a custom range needs a duration in minutes",
|
|
11607
|
+
path: ["customMinutes"],
|
|
11608
|
+
input: payload.value
|
|
11609
|
+
});
|
|
11610
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11611
|
+
code: "custom",
|
|
11612
|
+
message: "only a custom range carries a duration",
|
|
11613
|
+
path: ["customMinutes"],
|
|
11614
|
+
input: payload.value
|
|
11615
|
+
});
|
|
11616
|
+
});
|
|
11617
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
11618
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
11619
|
+
kind: literal("calendar"),
|
|
11620
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11621
|
+
})]);
|
|
11622
|
+
/**
|
|
11533
11623
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11534
11624
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11535
11625
|
* `composition.ts` (D659).
|
|
@@ -11555,7 +11645,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11555
11645
|
"occupancy",
|
|
11556
11646
|
"binary",
|
|
11557
11647
|
"switch",
|
|
11558
|
-
"light"
|
|
11648
|
+
"light",
|
|
11649
|
+
"fan",
|
|
11650
|
+
"cover",
|
|
11651
|
+
"valve",
|
|
11652
|
+
"lock",
|
|
11653
|
+
"media-player",
|
|
11654
|
+
"climate"
|
|
11559
11655
|
];
|
|
11560
11656
|
var NUMERIC_AGGREGATES = [
|
|
11561
11657
|
"mean",
|
|
@@ -11585,22 +11681,73 @@ var HelperMemberSchema = object({
|
|
|
11585
11681
|
cap: string().min(1),
|
|
11586
11682
|
fieldPath: string().min(1)
|
|
11587
11683
|
});
|
|
11588
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11602
|
-
|
|
11603
|
-
|
|
11684
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11685
|
+
object({
|
|
11686
|
+
kind: literal("group"),
|
|
11687
|
+
templateId: GroupTemplateIdSchema,
|
|
11688
|
+
aggregate: AggregateReducerSchema,
|
|
11689
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11690
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11691
|
+
active: ActiveCriterionSchema.optional()
|
|
11692
|
+
}),
|
|
11693
|
+
object({
|
|
11694
|
+
kind: literal("appliance"),
|
|
11695
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
11696
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
11697
|
+
thresholdWatts: number().positive(),
|
|
11698
|
+
startDwellMs: number().int().nonnegative(),
|
|
11699
|
+
stopDwellMs: number().int().nonnegative(),
|
|
11700
|
+
member: HelperMemberSchema
|
|
11701
|
+
}),
|
|
11702
|
+
object({
|
|
11703
|
+
kind: literal("statistic"),
|
|
11704
|
+
stat: _enum(STATISTIC_STATS),
|
|
11705
|
+
window: StatisticWindowSchema,
|
|
11706
|
+
source: HelperMemberSchema
|
|
11707
|
+
}),
|
|
11708
|
+
object({
|
|
11709
|
+
kind: literal("integral"),
|
|
11710
|
+
reset: _enum(RESET_PERIODS),
|
|
11711
|
+
output: _enum(["energy", "meter"]),
|
|
11712
|
+
source: HelperMemberSchema
|
|
11713
|
+
}),
|
|
11714
|
+
object({
|
|
11715
|
+
kind: literal("threshold"),
|
|
11716
|
+
source: HelperMemberSchema,
|
|
11717
|
+
high: number(),
|
|
11718
|
+
low: number(),
|
|
11719
|
+
onForMs: number().int().nonnegative(),
|
|
11720
|
+
offForMs: number().int().nonnegative()
|
|
11721
|
+
}),
|
|
11722
|
+
object({
|
|
11723
|
+
kind: literal("arithmetic"),
|
|
11724
|
+
op: _enum([
|
|
11725
|
+
"sum",
|
|
11726
|
+
"difference",
|
|
11727
|
+
"ratio"
|
|
11728
|
+
]),
|
|
11729
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
11730
|
+
}),
|
|
11731
|
+
object({
|
|
11732
|
+
kind: literal("expression"),
|
|
11733
|
+
expr: string().min(1),
|
|
11734
|
+
inputs: array(object({
|
|
11735
|
+
name: string().min(1),
|
|
11736
|
+
member: HelperMemberSchema
|
|
11737
|
+
})).min(1).max(64),
|
|
11738
|
+
output: _enum(["number", "boolean"])
|
|
11739
|
+
}),
|
|
11740
|
+
object({
|
|
11741
|
+
kind: literal("derivative"),
|
|
11742
|
+
window: RollingWindowSchema,
|
|
11743
|
+
per: _enum([
|
|
11744
|
+
"second",
|
|
11745
|
+
"minute",
|
|
11746
|
+
"hour"
|
|
11747
|
+
]),
|
|
11748
|
+
source: HelperMemberSchema
|
|
11749
|
+
})
|
|
11750
|
+
]);
|
|
11604
11751
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11605
11752
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11606
11753
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -11661,6 +11808,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11661
11808
|
"all"
|
|
11662
11809
|
]),
|
|
11663
11810
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11811
|
+
/**
|
|
11812
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
11813
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
11814
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
11815
|
+
*/
|
|
11816
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
11664
11817
|
/** `value` is the reading; the others are the member counts. */
|
|
11665
11818
|
publish: _enum([
|
|
11666
11819
|
"value",
|
|
@@ -11674,6 +11827,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11674
11827
|
"omit",
|
|
11675
11828
|
"offline"
|
|
11676
11829
|
])
|
|
11830
|
+
}),
|
|
11831
|
+
object({
|
|
11832
|
+
kind: literal("series"),
|
|
11833
|
+
read: CompositionFieldReadSchema,
|
|
11834
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
11835
|
+
publish: _enum([
|
|
11836
|
+
"value",
|
|
11837
|
+
"included",
|
|
11838
|
+
"excluded",
|
|
11839
|
+
"total"
|
|
11840
|
+
]),
|
|
11841
|
+
/**
|
|
11842
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
11843
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
11844
|
+
*/
|
|
11845
|
+
empty: _enum([
|
|
11846
|
+
"null",
|
|
11847
|
+
"omit",
|
|
11848
|
+
"offline"
|
|
11849
|
+
])
|
|
11677
11850
|
})
|
|
11678
11851
|
]);
|
|
11679
11852
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -17832,7 +18005,8 @@ var CompositionProblemSchema = object({
|
|
|
17832
18005
|
"native-capability-replace",
|
|
17833
18006
|
"mixed-quantity",
|
|
17834
18007
|
"helper-mismatch",
|
|
17835
|
-
"member-constraint"
|
|
18008
|
+
"member-constraint",
|
|
18009
|
+
"retention"
|
|
17836
18010
|
]),
|
|
17837
18011
|
path: string(),
|
|
17838
18012
|
message: string()
|
|
@@ -18066,13 +18240,17 @@ Object.freeze({
|
|
|
18066
18240
|
latchedAt: {
|
|
18067
18241
|
kind: "fixed",
|
|
18068
18242
|
result: ["number", "null"]
|
|
18243
|
+
},
|
|
18244
|
+
schmitt: {
|
|
18245
|
+
kind: "fixed",
|
|
18246
|
+
result: ["boolean", "null"]
|
|
18069
18247
|
}
|
|
18070
18248
|
});
|
|
18071
18249
|
/**
|
|
18072
18250
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18073
18251
|
* Data, not a form default written into the block.
|
|
18074
18252
|
*/
|
|
18075
|
-
var NOW = {
|
|
18253
|
+
var NOW$2 = {
|
|
18076
18254
|
fieldPath: "lastFetchedAt",
|
|
18077
18255
|
expr: "now"
|
|
18078
18256
|
};
|
|
@@ -18086,6 +18264,8 @@ function numeric(input) {
|
|
|
18086
18264
|
family: "numeric",
|
|
18087
18265
|
deviceType: DeviceType.Sensor,
|
|
18088
18266
|
memberDeviceType: DeviceType.Sensor,
|
|
18267
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18268
|
+
activeWhen: void 0,
|
|
18089
18269
|
commandCaps: [],
|
|
18090
18270
|
baseUnit: baseUnitOf(input.quantity),
|
|
18091
18271
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18101,6 +18281,8 @@ function binary(input) {
|
|
|
18101
18281
|
family: "binary",
|
|
18102
18282
|
deviceType: DeviceType.Sensor,
|
|
18103
18283
|
memberDeviceType: DeviceType.Sensor,
|
|
18284
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18285
|
+
activeWhen: void 0,
|
|
18104
18286
|
commandCaps: [],
|
|
18105
18287
|
quantity: "none",
|
|
18106
18288
|
baseUnit: void 0,
|
|
@@ -18118,7 +18300,7 @@ var GROUP_TEMPLATES = [
|
|
|
18118
18300
|
quantity: "temperature",
|
|
18119
18301
|
defaultAggregate: "mean",
|
|
18120
18302
|
empty: "null",
|
|
18121
|
-
companions: [NOW]
|
|
18303
|
+
companions: [NOW$2]
|
|
18122
18304
|
}),
|
|
18123
18305
|
numeric({
|
|
18124
18306
|
id: "humidity",
|
|
@@ -18129,7 +18311,7 @@ var GROUP_TEMPLATES = [
|
|
|
18129
18311
|
quantity: "humidity",
|
|
18130
18312
|
defaultAggregate: "mean",
|
|
18131
18313
|
empty: "null",
|
|
18132
|
-
companions: [NOW]
|
|
18314
|
+
companions: [NOW$2]
|
|
18133
18315
|
}),
|
|
18134
18316
|
numeric({
|
|
18135
18317
|
id: "pressure",
|
|
@@ -18140,7 +18322,7 @@ var GROUP_TEMPLATES = [
|
|
|
18140
18322
|
quantity: "pressure",
|
|
18141
18323
|
defaultAggregate: "mean",
|
|
18142
18324
|
empty: "null",
|
|
18143
|
-
companions: [NOW]
|
|
18325
|
+
companions: [NOW$2]
|
|
18144
18326
|
}),
|
|
18145
18327
|
numeric({
|
|
18146
18328
|
id: "illuminance",
|
|
@@ -18151,7 +18333,7 @@ var GROUP_TEMPLATES = [
|
|
|
18151
18333
|
quantity: "illuminance",
|
|
18152
18334
|
defaultAggregate: "mean",
|
|
18153
18335
|
empty: "null",
|
|
18154
|
-
companions: [NOW]
|
|
18336
|
+
companions: [NOW$2]
|
|
18155
18337
|
}),
|
|
18156
18338
|
numeric({
|
|
18157
18339
|
id: "power",
|
|
@@ -18162,7 +18344,7 @@ var GROUP_TEMPLATES = [
|
|
|
18162
18344
|
quantity: "power",
|
|
18163
18345
|
defaultAggregate: "sum",
|
|
18164
18346
|
empty: "omit",
|
|
18165
|
-
companions: [NOW]
|
|
18347
|
+
companions: [NOW$2]
|
|
18166
18348
|
}),
|
|
18167
18349
|
numeric({
|
|
18168
18350
|
id: "energy",
|
|
@@ -18173,7 +18355,7 @@ var GROUP_TEMPLATES = [
|
|
|
18173
18355
|
quantity: "energy",
|
|
18174
18356
|
defaultAggregate: "sum",
|
|
18175
18357
|
empty: "omit",
|
|
18176
|
-
companions: [NOW]
|
|
18358
|
+
companions: [NOW$2]
|
|
18177
18359
|
}),
|
|
18178
18360
|
numeric({
|
|
18179
18361
|
id: "battery",
|
|
@@ -18208,7 +18390,7 @@ var GROUP_TEMPLATES = [
|
|
|
18208
18390
|
quantity: "device",
|
|
18209
18391
|
defaultAggregate: "mean",
|
|
18210
18392
|
empty: "null",
|
|
18211
|
-
companions: [NOW]
|
|
18393
|
+
companions: [NOW$2]
|
|
18212
18394
|
}),
|
|
18213
18395
|
binary({
|
|
18214
18396
|
id: "motion",
|
|
@@ -18302,6 +18484,11 @@ var GROUP_TEMPLATES = [
|
|
|
18302
18484
|
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.",
|
|
18303
18485
|
deviceType: DeviceType.Switch,
|
|
18304
18486
|
outputCap: "switch",
|
|
18487
|
+
outputField: "on",
|
|
18488
|
+
member: {
|
|
18489
|
+
cap: "switch",
|
|
18490
|
+
fieldPath: "on"
|
|
18491
|
+
},
|
|
18305
18492
|
commandCaps: ["switch"]
|
|
18306
18493
|
}),
|
|
18307
18494
|
actuator({
|
|
@@ -18309,34 +18496,136 @@ var GROUP_TEMPLATES = [
|
|
|
18309
18496
|
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.",
|
|
18310
18497
|
deviceType: DeviceType.Light,
|
|
18311
18498
|
outputCap: "switch",
|
|
18499
|
+
outputField: "on",
|
|
18500
|
+
member: {
|
|
18501
|
+
cap: "switch",
|
|
18502
|
+
fieldPath: "on"
|
|
18503
|
+
},
|
|
18312
18504
|
commandCaps: [
|
|
18313
18505
|
"switch",
|
|
18314
18506
|
"brightness",
|
|
18315
18507
|
"color"
|
|
18316
18508
|
]
|
|
18509
|
+
}),
|
|
18510
|
+
actuator({
|
|
18511
|
+
id: "fan",
|
|
18512
|
+
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.",
|
|
18513
|
+
deviceType: DeviceType.Fan,
|
|
18514
|
+
outputCap: "switch",
|
|
18515
|
+
outputField: "on",
|
|
18516
|
+
member: {
|
|
18517
|
+
cap: "switch",
|
|
18518
|
+
fieldPath: "on"
|
|
18519
|
+
},
|
|
18520
|
+
commandCaps: ["switch", "fan-control"]
|
|
18521
|
+
}),
|
|
18522
|
+
actuator({
|
|
18523
|
+
id: "cover",
|
|
18524
|
+
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.",
|
|
18525
|
+
deviceType: DeviceType.Cover,
|
|
18526
|
+
outputCap: "group-active",
|
|
18527
|
+
outputField: "active",
|
|
18528
|
+
member: {
|
|
18529
|
+
cap: "cover",
|
|
18530
|
+
fieldPath: "state"
|
|
18531
|
+
},
|
|
18532
|
+
activeWhen: [
|
|
18533
|
+
"open",
|
|
18534
|
+
"opening",
|
|
18535
|
+
"stopped"
|
|
18536
|
+
],
|
|
18537
|
+
commandCaps: ["cover"]
|
|
18538
|
+
}),
|
|
18539
|
+
actuator({
|
|
18540
|
+
id: "valve",
|
|
18541
|
+
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.",
|
|
18542
|
+
deviceType: DeviceType.Valve,
|
|
18543
|
+
outputCap: "group-active",
|
|
18544
|
+
outputField: "active",
|
|
18545
|
+
member: {
|
|
18546
|
+
cap: "valve",
|
|
18547
|
+
fieldPath: "state"
|
|
18548
|
+
},
|
|
18549
|
+
activeWhen: [
|
|
18550
|
+
"open",
|
|
18551
|
+
"opening",
|
|
18552
|
+
"stopped"
|
|
18553
|
+
],
|
|
18554
|
+
commandCaps: ["valve"]
|
|
18555
|
+
}),
|
|
18556
|
+
actuator({
|
|
18557
|
+
id: "lock",
|
|
18558
|
+
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.",
|
|
18559
|
+
deviceType: DeviceType.Lock,
|
|
18560
|
+
outputCap: "group-active",
|
|
18561
|
+
outputField: "active",
|
|
18562
|
+
member: {
|
|
18563
|
+
cap: "lock-control",
|
|
18564
|
+
fieldPath: "state"
|
|
18565
|
+
},
|
|
18566
|
+
activeWhen: ["locked"],
|
|
18567
|
+
commandCaps: ["lock-control"]
|
|
18568
|
+
}),
|
|
18569
|
+
actuator({
|
|
18570
|
+
id: "media-player",
|
|
18571
|
+
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.",
|
|
18572
|
+
deviceType: DeviceType.MediaPlayer,
|
|
18573
|
+
outputCap: "group-active",
|
|
18574
|
+
outputField: "active",
|
|
18575
|
+
member: {
|
|
18576
|
+
cap: "media-player",
|
|
18577
|
+
fieldPath: "state"
|
|
18578
|
+
},
|
|
18579
|
+
activeWhen: ["playing", "buffering"],
|
|
18580
|
+
commandCaps: ["media-player"]
|
|
18581
|
+
}),
|
|
18582
|
+
actuator({
|
|
18583
|
+
id: "climate",
|
|
18584
|
+
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.",
|
|
18585
|
+
deviceType: DeviceType.Thermostat,
|
|
18586
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
18587
|
+
outputCap: "group-active",
|
|
18588
|
+
outputField: "active",
|
|
18589
|
+
member: {
|
|
18590
|
+
cap: "climate-control",
|
|
18591
|
+
fieldPath: "mode"
|
|
18592
|
+
},
|
|
18593
|
+
activeWhen: [
|
|
18594
|
+
"heat",
|
|
18595
|
+
"cool",
|
|
18596
|
+
"auto",
|
|
18597
|
+
"heat_cool",
|
|
18598
|
+
"fan_only",
|
|
18599
|
+
"dry"
|
|
18600
|
+
],
|
|
18601
|
+
commandCaps: ["climate-control"]
|
|
18317
18602
|
})
|
|
18318
18603
|
];
|
|
18319
18604
|
function actuator(input) {
|
|
18320
18605
|
return {
|
|
18321
|
-
|
|
18606
|
+
id: input.id,
|
|
18607
|
+
summary: input.summary,
|
|
18608
|
+
deviceType: input.deviceType,
|
|
18609
|
+
outputCap: input.outputCap,
|
|
18610
|
+
outputField: input.outputField,
|
|
18611
|
+
commandCaps: input.commandCaps,
|
|
18322
18612
|
family: "actuator",
|
|
18323
18613
|
role: void 0,
|
|
18324
18614
|
memberDeviceType: input.deviceType,
|
|
18325
|
-
|
|
18615
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
18616
|
+
activeWhen: input.activeWhen,
|
|
18326
18617
|
quantity: "none",
|
|
18327
18618
|
baseUnit: void 0,
|
|
18328
18619
|
aggregates: BINARY_AGGREGATES,
|
|
18329
18620
|
defaultAggregate: "any",
|
|
18330
18621
|
empty: "offline",
|
|
18331
|
-
accept: [
|
|
18332
|
-
cap: "switch",
|
|
18333
|
-
fieldPath: "on"
|
|
18334
|
-
}],
|
|
18622
|
+
accept: [input.member],
|
|
18335
18623
|
companions: [CHANGED]
|
|
18336
18624
|
};
|
|
18337
18625
|
}
|
|
18338
18626
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18339
18627
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18628
|
+
DeviceType.Camera;
|
|
18340
18629
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18341
18630
|
/**
|
|
18342
18631
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -45994,7 +46283,20 @@ var NcRuleInputSchema = object({
|
|
|
45994
46283
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
45995
46284
|
* path does not run Zod defaults.
|
|
45996
46285
|
*/
|
|
45997
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46286
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46287
|
+
/**
|
|
46288
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46289
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46290
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46291
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46292
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46293
|
+
*
|
|
46294
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46295
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46296
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46297
|
+
* `false`, so it needs no `clear` key.
|
|
46298
|
+
*/
|
|
46299
|
+
askVerdict: boolean().optional()
|
|
45998
46300
|
});
|
|
45999
46301
|
/**
|
|
46000
46302
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -58195,7 +58497,13 @@ results: array(object({
|
|
|
58195
58497
|
/** Ms epoch of the attempt. */
|
|
58196
58498
|
at: number()
|
|
58197
58499
|
})) });
|
|
58198
|
-
DeviceType.Switch, DeviceType.Light;
|
|
58500
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58501
|
+
object({
|
|
58502
|
+
active: boolean().meta({ label: "Active" }),
|
|
58503
|
+
/** Ms epoch when the slice was last updated. */
|
|
58504
|
+
lastChangedAt: number()
|
|
58505
|
+
});
|
|
58506
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
58199
58507
|
object({
|
|
58200
58508
|
/** Members whose current value entered the aggregate. */
|
|
58201
58509
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -58213,7 +58521,7 @@ object({
|
|
|
58213
58521
|
label: "Members"
|
|
58214
58522
|
}))
|
|
58215
58523
|
});
|
|
58216
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58524
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58217
58525
|
object({
|
|
58218
58526
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58219
58527
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -59120,7 +59428,14 @@ DeviceType.Lock, method(object({
|
|
|
59120
59428
|
auth: "protected"
|
|
59121
59429
|
}), method(object({
|
|
59122
59430
|
deviceId: number().int().nonnegative(),
|
|
59123
|
-
code: string().min(1).optional()
|
|
59431
|
+
code: string().min(1).optional(),
|
|
59432
|
+
/**
|
|
59433
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
59434
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
59435
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
59436
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
59437
|
+
*/
|
|
59438
|
+
confirm: boolean().optional()
|
|
59124
59439
|
}), _void(), {
|
|
59125
59440
|
kind: "mutation",
|
|
59126
59441
|
auth: "protected"
|
|
@@ -59128,6 +59443,11 @@ DeviceType.Lock, method(object({
|
|
|
59128
59443
|
kind: "mutation",
|
|
59129
59444
|
auth: "protected"
|
|
59130
59445
|
});
|
|
59446
|
+
object({
|
|
59447
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
59448
|
+
lastFetchedAt: number()
|
|
59449
|
+
});
|
|
59450
|
+
DeviceType.Sensor;
|
|
59131
59451
|
/**
|
|
59132
59452
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
59133
59453
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -63531,7 +63851,7 @@ object({
|
|
|
63531
63851
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
63532
63852
|
lastChangedAt: number()
|
|
63533
63853
|
});
|
|
63534
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
63854
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
63535
63855
|
deviceId: number(),
|
|
63536
63856
|
on: boolean()
|
|
63537
63857
|
}), _void(), {
|
|
@@ -65223,6 +65543,7 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
65223
65543
|
kind: "mutation",
|
|
65224
65544
|
auth: "admin"
|
|
65225
65545
|
});
|
|
65546
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
65226
65547
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
65227
65548
|
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;
|
|
65228
65549
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
@@ -68500,6 +68821,13 @@ Object.freeze({
|
|
|
68500
68821
|
access: "view",
|
|
68501
68822
|
role: "viewer"
|
|
68502
68823
|
},
|
|
68824
|
+
"groupActive.getStatus": {
|
|
68825
|
+
capName: "group-active",
|
|
68826
|
+
capScope: "device",
|
|
68827
|
+
addonId: null,
|
|
68828
|
+
access: "view",
|
|
68829
|
+
role: "viewer"
|
|
68830
|
+
},
|
|
68503
68831
|
"groupCommands.getStatus": {
|
|
68504
68832
|
capName: "group-commands",
|
|
68505
68833
|
capScope: "device",
|
|
@@ -69466,6 +69794,13 @@ Object.freeze({
|
|
|
69466
69794
|
access: "create",
|
|
69467
69795
|
role: "admin"
|
|
69468
69796
|
},
|
|
69797
|
+
"meter.getStatus": {
|
|
69798
|
+
capName: "meter",
|
|
69799
|
+
capScope: "device",
|
|
69800
|
+
addonId: null,
|
|
69801
|
+
access: "view",
|
|
69802
|
+
role: "viewer"
|
|
69803
|
+
},
|
|
69469
69804
|
"metricsProvider.collectSnapshot": {
|
|
69470
69805
|
capName: "metrics-provider",
|
|
69471
69806
|
capScope: "system",
|
|
@@ -78368,6 +78703,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78368
78703
|
icon: "flame"
|
|
78369
78704
|
}]
|
|
78370
78705
|
},
|
|
78706
|
+
"group-active": {
|
|
78707
|
+
scope: "device",
|
|
78708
|
+
noun: t("Group state", "Stato del gruppo")
|
|
78709
|
+
},
|
|
78371
78710
|
"group-commands": {
|
|
78372
78711
|
scope: "device",
|
|
78373
78712
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -78424,6 +78763,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78424
78763
|
}],
|
|
78425
78764
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
78426
78765
|
},
|
|
78766
|
+
meter: {
|
|
78767
|
+
scope: "device",
|
|
78768
|
+
noun: t("Meter", "Contatore"),
|
|
78769
|
+
state: [{
|
|
78770
|
+
kind: "numeric",
|
|
78771
|
+
field: "value",
|
|
78772
|
+
quantity: t("the total", "il totale"),
|
|
78773
|
+
label: t("Total", "Totale"),
|
|
78774
|
+
icon: "gauge"
|
|
78775
|
+
}]
|
|
78776
|
+
},
|
|
78427
78777
|
"numeric-sensor": {
|
|
78428
78778
|
scope: "device",
|
|
78429
78779
|
noun: t("Sensor", "Sensore"),
|
|
@@ -79903,6 +80253,11 @@ Object.freeze({
|
|
|
79903
80253
|
form: "single",
|
|
79904
80254
|
optional: false
|
|
79905
80255
|
}],
|
|
80256
|
+
"groupActive.getStatus": [{
|
|
80257
|
+
name: "deviceId",
|
|
80258
|
+
form: "single",
|
|
80259
|
+
optional: false
|
|
80260
|
+
}],
|
|
79906
80261
|
"groupCommands.getStatus": [{
|
|
79907
80262
|
name: "deviceId",
|
|
79908
80263
|
form: "single",
|
|
@@ -80113,6 +80468,11 @@ Object.freeze({
|
|
|
80113
80468
|
form: "single",
|
|
80114
80469
|
optional: false
|
|
80115
80470
|
}],
|
|
80471
|
+
"meter.getStatus": [{
|
|
80472
|
+
name: "deviceId",
|
|
80473
|
+
form: "single",
|
|
80474
|
+
optional: false
|
|
80475
|
+
}],
|
|
80116
80476
|
"motion.getStatus": [{
|
|
80117
80477
|
name: "deviceId",
|
|
80118
80478
|
form: "single",
|
|
@@ -81720,7 +82080,6 @@ Object.freeze({
|
|
|
81720
82080
|
"network-access": "ingress",
|
|
81721
82081
|
"smtp-provider": "email"
|
|
81722
82082
|
});
|
|
81723
|
-
DeviceType.Camera;
|
|
81724
82083
|
/**
|
|
81725
82084
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
81726
82085
|
* `z.infer`, they do not restate the shape.
|
|
@@ -83047,7 +83406,7 @@ var AgentUIAddon = class extends BaseAddon {
|
|
|
83047
83406
|
capability: adminUiCapability,
|
|
83048
83407
|
provider: {
|
|
83049
83408
|
getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
|
|
83050
|
-
getVersion: async () => ({ version: "1.2.
|
|
83409
|
+
getVersion: async () => ({ version: "1.2.278" })
|
|
83051
83410
|
}
|
|
83052
83411
|
}];
|
|
83053
83412
|
}
|