@camstack/addon-smtp-nodemailer 1.2.142 → 1.2.143
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/CHANGELOG.md +10 -1
- package/README.md +11 -9
- package/dist/smtp.addon.js +540 -45
- package/dist/smtp.addon.mjs +540 -45
- package/package.json +3 -3
package/dist/smtp.addon.js
CHANGED
|
@@ -5479,7 +5479,7 @@ var ZodIssueCode = {
|
|
|
5479
5479
|
var ZodFirstPartyTypeKind;
|
|
5480
5480
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5481
5481
|
//#endregion
|
|
5482
|
-
//#region ../types/dist/sleep
|
|
5482
|
+
//#region ../types/dist/sleep--jXS9hWo.mjs
|
|
5483
5483
|
/**
|
|
5484
5484
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5485
5485
|
* window to float samples (D455).
|
|
@@ -8601,6 +8601,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8601
8601
|
"filesystem-browse",
|
|
8602
8602
|
"flood",
|
|
8603
8603
|
"gas",
|
|
8604
|
+
"group-active",
|
|
8604
8605
|
"group-commands",
|
|
8605
8606
|
"group-status",
|
|
8606
8607
|
"heating-valve",
|
|
@@ -8623,6 +8624,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8623
8624
|
"login-method",
|
|
8624
8625
|
"media-player",
|
|
8625
8626
|
"mesh-network",
|
|
8627
|
+
"meter",
|
|
8626
8628
|
"metrics-provider",
|
|
8627
8629
|
"model-convert",
|
|
8628
8630
|
"model-distributor",
|
|
@@ -9421,6 +9423,10 @@ Object.freeze({
|
|
|
9421
9423
|
"path": "detected",
|
|
9422
9424
|
"valueType": "boolean"
|
|
9423
9425
|
}],
|
|
9426
|
+
"group-active": [{
|
|
9427
|
+
"path": "active",
|
|
9428
|
+
"valueType": "boolean"
|
|
9429
|
+
}],
|
|
9424
9430
|
"group-status": [
|
|
9425
9431
|
{
|
|
9426
9432
|
"path": "included",
|
|
@@ -9680,6 +9686,10 @@ Object.freeze({
|
|
|
9680
9686
|
]
|
|
9681
9687
|
}
|
|
9682
9688
|
],
|
|
9689
|
+
"meter": [{
|
|
9690
|
+
"path": "value",
|
|
9691
|
+
"valueType": "number"
|
|
9692
|
+
}],
|
|
9683
9693
|
"motion": [
|
|
9684
9694
|
{
|
|
9685
9695
|
"path": "detected",
|
|
@@ -10423,7 +10433,7 @@ object({
|
|
|
10423
10433
|
params: record(string(), union([string(), number()])).optional()
|
|
10424
10434
|
});
|
|
10425
10435
|
//#endregion
|
|
10426
|
-
//#region ../types/dist/err-msg-
|
|
10436
|
+
//#region ../types/dist/err-msg-DIorGYeC.mjs
|
|
10427
10437
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
10428
10438
|
DeviceType["Camera"] = "camera";
|
|
10429
10439
|
DeviceType["Hub"] = "hub";
|
|
@@ -10517,8 +10527,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
10517
10527
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
10518
10528
|
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
10519
10529
|
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
10520
|
-
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10530
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations.
|
|
10531
|
+
* A plug-built dishwasher carries running-state and power instead. */
|
|
10521
10532
|
DeviceType["Dishwasher"] = "dishwasher";
|
|
10533
|
+
/** Washing machine. A plug-built one is running while its power stays
|
|
10534
|
+
* above a threshold. No program cap — that surface is the dishwasher's. */
|
|
10535
|
+
DeviceType["Washer"] = "washer";
|
|
10536
|
+
/** Tumble dryer. Same plug-built running surface as {@link Washer}. */
|
|
10537
|
+
DeviceType["Dryer"] = "dryer";
|
|
10522
10538
|
return DeviceType;
|
|
10523
10539
|
}({});
|
|
10524
10540
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -10766,7 +10782,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10766
10782
|
return DeviceRole;
|
|
10767
10783
|
}({});
|
|
10768
10784
|
//#endregion
|
|
10769
|
-
//#region ../types/dist/composition-
|
|
10785
|
+
//#region ../types/dist/composition-Bb8iwHEJ.mjs
|
|
10770
10786
|
/**
|
|
10771
10787
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10772
10788
|
*
|
|
@@ -11081,6 +11097,13 @@ var table = {
|
|
|
11081
11097
|
apply: () => {
|
|
11082
11098
|
throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
|
|
11083
11099
|
}
|
|
11100
|
+
},
|
|
11101
|
+
schmitt: {
|
|
11102
|
+
minArgs: 3,
|
|
11103
|
+
maxArgs: 5,
|
|
11104
|
+
apply: () => {
|
|
11105
|
+
throw new ExpressionEvalError("schmitt: stateful evaluation context is required");
|
|
11106
|
+
}
|
|
11084
11107
|
}
|
|
11085
11108
|
};
|
|
11086
11109
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -11522,6 +11545,99 @@ function validateExpressionSource(src) {
|
|
|
11522
11545
|
return null;
|
|
11523
11546
|
}
|
|
11524
11547
|
/**
|
|
11548
|
+
* One power reading becomes a washer, dryer or dishwasher (D944 helper).
|
|
11549
|
+
*
|
|
11550
|
+
* Standby of the control board is under 5 W; a motor or a heater is far
|
|
11551
|
+
* above that, so 5 W is the line. A door lock or a short pump spike is not
|
|
11552
|
+
* a cycle, so running starts only after 30 s above the line.
|
|
11553
|
+
*
|
|
11554
|
+
* A wash, dry or dishwasher pause (soak, heat-wait, heater off between
|
|
11555
|
+
* bursts) lasts several minutes. Ending the cycle on the first dip would
|
|
11556
|
+
* report "finished" in the middle of the program, so the stop dwell is
|
|
11557
|
+
* 10 minutes on every type. The number is stored per type so one machine
|
|
11558
|
+
* can move later without moving the others.
|
|
11559
|
+
*/
|
|
11560
|
+
var APPLIANCE_TEMPLATE_ID = "appliance";
|
|
11561
|
+
var APPLIANCE_KINDS = [
|
|
11562
|
+
"washer",
|
|
11563
|
+
"dryer",
|
|
11564
|
+
"dishwasher"
|
|
11565
|
+
];
|
|
11566
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
11567
|
+
/**
|
|
11568
|
+
* Statistics and integrals over a history read (D944).
|
|
11569
|
+
*
|
|
11570
|
+
* Pure: the same points always give the same answer, so a restart recomputes
|
|
11571
|
+
* rather than trusting a buffer. A gauge mean is time-weighted (value × ms),
|
|
11572
|
+
* never the mean of the samples. A hole with no held value is not integrated
|
|
11573
|
+
* as zero. A truncated read is not published.
|
|
11574
|
+
*/
|
|
11575
|
+
var STATISTIC_STATS = [
|
|
11576
|
+
"min",
|
|
11577
|
+
"max",
|
|
11578
|
+
"mean",
|
|
11579
|
+
"sum",
|
|
11580
|
+
"count",
|
|
11581
|
+
"change"
|
|
11582
|
+
];
|
|
11583
|
+
/**
|
|
11584
|
+
* The range a statistics or integral helper asks history for (D944).
|
|
11585
|
+
*
|
|
11586
|
+
* Calendar edges are the hub's timezone, never UTC midnight: a day is 23, 24
|
|
11587
|
+
* or 25 hours across a DST change. A tier is eligible only when its retention
|
|
11588
|
+
* is strictly longer than the longest that range can be. Forever qualifies.
|
|
11589
|
+
* Equal to a tier's retention is a refusal, not a short answer.
|
|
11590
|
+
*/
|
|
11591
|
+
var MINUTE_MS = 6e4;
|
|
11592
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
11593
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
11594
|
+
var ROLLING_SPANS = [
|
|
11595
|
+
"1h",
|
|
11596
|
+
"24h",
|
|
11597
|
+
"2d",
|
|
11598
|
+
"7d",
|
|
11599
|
+
"30d",
|
|
11600
|
+
"custom"
|
|
11601
|
+
];
|
|
11602
|
+
var CALENDAR_PERIODS = [
|
|
11603
|
+
"today",
|
|
11604
|
+
"yesterday",
|
|
11605
|
+
"this-week",
|
|
11606
|
+
"this-month"
|
|
11607
|
+
];
|
|
11608
|
+
var RESET_PERIODS = [
|
|
11609
|
+
"never",
|
|
11610
|
+
"daily",
|
|
11611
|
+
"weekly",
|
|
11612
|
+
"monthly"
|
|
11613
|
+
];
|
|
11614
|
+
5 * MINUTE_MS;
|
|
11615
|
+
24 * HOUR_MS, 2 * DAY_MS, 7 * DAY_MS, 30 * DAY_MS;
|
|
11616
|
+
7 * DAY_MS, 30 * DAY_MS, 365 * DAY_MS;
|
|
11617
|
+
var rollingWindowObject = object({
|
|
11618
|
+
kind: literal("rolling"),
|
|
11619
|
+
span: _enum(ROLLING_SPANS),
|
|
11620
|
+
customMinutes: number().int().min(5).optional()
|
|
11621
|
+
}).check((payload) => {
|
|
11622
|
+
if (payload.value.span === "custom" && payload.value.customMinutes === void 0) payload.issues.push({
|
|
11623
|
+
code: "custom",
|
|
11624
|
+
message: "a custom range needs a duration in minutes",
|
|
11625
|
+
path: ["customMinutes"],
|
|
11626
|
+
input: payload.value
|
|
11627
|
+
});
|
|
11628
|
+
if (payload.value.span !== "custom" && payload.value.customMinutes !== void 0) payload.issues.push({
|
|
11629
|
+
code: "custom",
|
|
11630
|
+
message: "only a custom range carries a duration",
|
|
11631
|
+
path: ["customMinutes"],
|
|
11632
|
+
input: payload.value
|
|
11633
|
+
});
|
|
11634
|
+
});
|
|
11635
|
+
var RollingWindowSchema = rollingWindowObject;
|
|
11636
|
+
var StatisticWindowSchema = discriminatedUnion("kind", [rollingWindowObject, object({
|
|
11637
|
+
kind: literal("calendar"),
|
|
11638
|
+
period: _enum(CALENDAR_PERIODS)
|
|
11639
|
+
})]);
|
|
11640
|
+
/**
|
|
11525
11641
|
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11526
11642
|
* id. Split out so helper schemas can name it without a cycle through
|
|
11527
11643
|
* `composition.ts` (D659).
|
|
@@ -11547,7 +11663,13 @@ var GROUP_TEMPLATE_IDS = [
|
|
|
11547
11663
|
"occupancy",
|
|
11548
11664
|
"binary",
|
|
11549
11665
|
"switch",
|
|
11550
|
-
"light"
|
|
11666
|
+
"light",
|
|
11667
|
+
"fan",
|
|
11668
|
+
"cover",
|
|
11669
|
+
"valve",
|
|
11670
|
+
"lock",
|
|
11671
|
+
"media-player",
|
|
11672
|
+
"climate"
|
|
11551
11673
|
];
|
|
11552
11674
|
var NUMERIC_AGGREGATES = [
|
|
11553
11675
|
"mean",
|
|
@@ -11577,14 +11699,73 @@ var HelperMemberSchema = object({
|
|
|
11577
11699
|
cap: string().min(1),
|
|
11578
11700
|
fieldPath: string().min(1)
|
|
11579
11701
|
});
|
|
11580
|
-
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11581
|
-
|
|
11582
|
-
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
11702
|
+
var HelperSpecSchema = discriminatedUnion("kind", [
|
|
11703
|
+
object({
|
|
11704
|
+
kind: literal("group"),
|
|
11705
|
+
templateId: GroupTemplateIdSchema,
|
|
11706
|
+
aggregate: AggregateReducerSchema,
|
|
11707
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11708
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11709
|
+
active: ActiveCriterionSchema.optional()
|
|
11710
|
+
}),
|
|
11711
|
+
object({
|
|
11712
|
+
kind: literal("appliance"),
|
|
11713
|
+
templateId: literal(APPLIANCE_TEMPLATE_ID),
|
|
11714
|
+
appliance: _enum(APPLIANCE_KINDS),
|
|
11715
|
+
thresholdWatts: number().positive(),
|
|
11716
|
+
startDwellMs: number().int().nonnegative(),
|
|
11717
|
+
stopDwellMs: number().int().nonnegative(),
|
|
11718
|
+
member: HelperMemberSchema
|
|
11719
|
+
}),
|
|
11720
|
+
object({
|
|
11721
|
+
kind: literal("statistic"),
|
|
11722
|
+
stat: _enum(STATISTIC_STATS),
|
|
11723
|
+
window: StatisticWindowSchema,
|
|
11724
|
+
source: HelperMemberSchema
|
|
11725
|
+
}),
|
|
11726
|
+
object({
|
|
11727
|
+
kind: literal("integral"),
|
|
11728
|
+
reset: _enum(RESET_PERIODS),
|
|
11729
|
+
output: _enum(["energy", "meter"]),
|
|
11730
|
+
source: HelperMemberSchema
|
|
11731
|
+
}),
|
|
11732
|
+
object({
|
|
11733
|
+
kind: literal("threshold"),
|
|
11734
|
+
source: HelperMemberSchema,
|
|
11735
|
+
high: number(),
|
|
11736
|
+
low: number(),
|
|
11737
|
+
onForMs: number().int().nonnegative(),
|
|
11738
|
+
offForMs: number().int().nonnegative()
|
|
11739
|
+
}),
|
|
11740
|
+
object({
|
|
11741
|
+
kind: literal("arithmetic"),
|
|
11742
|
+
op: _enum([
|
|
11743
|
+
"sum",
|
|
11744
|
+
"difference",
|
|
11745
|
+
"ratio"
|
|
11746
|
+
]),
|
|
11747
|
+
inputs: array(HelperMemberSchema).min(2).max(64)
|
|
11748
|
+
}),
|
|
11749
|
+
object({
|
|
11750
|
+
kind: literal("expression"),
|
|
11751
|
+
expr: string().min(1),
|
|
11752
|
+
inputs: array(object({
|
|
11753
|
+
name: string().min(1),
|
|
11754
|
+
member: HelperMemberSchema
|
|
11755
|
+
})).min(1).max(64),
|
|
11756
|
+
output: _enum(["number", "boolean"])
|
|
11757
|
+
}),
|
|
11758
|
+
object({
|
|
11759
|
+
kind: literal("derivative"),
|
|
11760
|
+
window: RollingWindowSchema,
|
|
11761
|
+
per: _enum([
|
|
11762
|
+
"second",
|
|
11763
|
+
"minute",
|
|
11764
|
+
"hour"
|
|
11765
|
+
]),
|
|
11766
|
+
source: HelperMemberSchema
|
|
11767
|
+
})
|
|
11768
|
+
]);
|
|
11588
11769
|
/** A composed device's stableId is this prefix plus the block id. */
|
|
11589
11770
|
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11590
11771
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
@@ -11645,6 +11826,12 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11645
11826
|
"all"
|
|
11646
11827
|
]),
|
|
11647
11828
|
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11829
|
+
/**
|
|
11830
|
+
* Set when the reads are an enum state, not a yes/no: the listed states
|
|
11831
|
+
* count as active (a cover is `open`). A state outside the list is inactive;
|
|
11832
|
+
* a read that is not a state at all is left out. Only `any` / `all` use it.
|
|
11833
|
+
*/
|
|
11834
|
+
activeWhen: array(string().min(1)).min(1).optional(),
|
|
11648
11835
|
/** `value` is the reading; the others are the member counts. */
|
|
11649
11836
|
publish: _enum([
|
|
11650
11837
|
"value",
|
|
@@ -11658,6 +11845,26 @@ var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
|
11658
11845
|
"omit",
|
|
11659
11846
|
"offline"
|
|
11660
11847
|
])
|
|
11848
|
+
}),
|
|
11849
|
+
object({
|
|
11850
|
+
kind: literal("series"),
|
|
11851
|
+
read: CompositionFieldReadSchema,
|
|
11852
|
+
/** `value` is the statistic or the integral. The others are the gap counts. */
|
|
11853
|
+
publish: _enum([
|
|
11854
|
+
"value",
|
|
11855
|
+
"included",
|
|
11856
|
+
"excluded",
|
|
11857
|
+
"total"
|
|
11858
|
+
]),
|
|
11859
|
+
/**
|
|
11860
|
+
* What an unanswered `value` does. Counts ignore this. `offline` leaves the
|
|
11861
|
+
* device unseeded until history answers, so a restart cannot publish 0.
|
|
11862
|
+
*/
|
|
11863
|
+
empty: _enum([
|
|
11864
|
+
"null",
|
|
11865
|
+
"omit",
|
|
11866
|
+
"offline"
|
|
11867
|
+
])
|
|
11661
11868
|
})
|
|
11662
11869
|
]);
|
|
11663
11870
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
@@ -16817,7 +17024,22 @@ var BrokerProviderInfoSchema = object({
|
|
|
16817
17024
|
*/
|
|
16818
17025
|
interactiveConnectPath: string().min(1).optional(),
|
|
16819
17026
|
/** Relative hub path to disconnect the linked account (same popup pattern). */
|
|
16820
|
-
interactiveDisconnectPath: string().min(1).optional()
|
|
17027
|
+
interactiveDisconnectPath: string().min(1).optional(),
|
|
17028
|
+
/**
|
|
17029
|
+
* The kind signs in through a server-held interactive session instead of
|
|
17030
|
+
* (or before) typed credentials. `basePath` is a hub-relative route set
|
|
17031
|
+
* served by the owning addon (`/addon/<id>/...`) speaking the sign-in
|
|
17032
|
+
* contract: `POST {basePath}/start` (body: the form's settings) answers
|
|
17033
|
+
* `{ sessionId, loginUrl }`; `GET {basePath}/status?sessionId=` answers
|
|
17034
|
+
* `{ phase: 'starting' | 'awaiting-login' | 'captured' | 'error' |
|
|
17035
|
+
* 'cancelled', loginUrl, error }`; `POST {basePath}/commit`
|
|
17036
|
+
* (`{ sessionId, name, brokerId? }`) stores the credentials on a new or
|
|
17037
|
+
* existing broker and answers `{ brokerId }`; `POST {basePath}/cancel`
|
|
17038
|
+
* (`{ sessionId }`) drops the session. The dialog that edits a broker
|
|
17039
|
+
* offers it as the default path; the fields the session fills are
|
|
17040
|
+
* marked `filledBySignIn` in the kind's settings schema.
|
|
17041
|
+
*/
|
|
17042
|
+
signIn: object({ basePath: string().min(1) }).optional()
|
|
16821
17043
|
}))
|
|
16822
17044
|
});
|
|
16823
17045
|
var ListInputSchema = object({
|
|
@@ -17816,7 +18038,8 @@ var CompositionProblemSchema = object({
|
|
|
17816
18038
|
"native-capability-replace",
|
|
17817
18039
|
"mixed-quantity",
|
|
17818
18040
|
"helper-mismatch",
|
|
17819
|
-
"member-constraint"
|
|
18041
|
+
"member-constraint",
|
|
18042
|
+
"retention"
|
|
17820
18043
|
]),
|
|
17821
18044
|
path: string(),
|
|
17822
18045
|
message: string()
|
|
@@ -18050,13 +18273,17 @@ Object.freeze({
|
|
|
18050
18273
|
latchedAt: {
|
|
18051
18274
|
kind: "fixed",
|
|
18052
18275
|
result: ["number", "null"]
|
|
18276
|
+
},
|
|
18277
|
+
schmitt: {
|
|
18278
|
+
kind: "fixed",
|
|
18279
|
+
result: ["boolean", "null"]
|
|
18053
18280
|
}
|
|
18054
18281
|
});
|
|
18055
18282
|
/**
|
|
18056
18283
|
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18057
18284
|
* Data, not a form default written into the block.
|
|
18058
18285
|
*/
|
|
18059
|
-
var NOW = {
|
|
18286
|
+
var NOW$2 = {
|
|
18060
18287
|
fieldPath: "lastFetchedAt",
|
|
18061
18288
|
expr: "now"
|
|
18062
18289
|
};
|
|
@@ -18070,6 +18297,8 @@ function numeric(input) {
|
|
|
18070
18297
|
family: "numeric",
|
|
18071
18298
|
deviceType: DeviceType.Sensor,
|
|
18072
18299
|
memberDeviceType: DeviceType.Sensor,
|
|
18300
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18301
|
+
activeWhen: void 0,
|
|
18073
18302
|
commandCaps: [],
|
|
18074
18303
|
baseUnit: baseUnitOf(input.quantity),
|
|
18075
18304
|
aggregates: NUMERIC_AGGREGATES,
|
|
@@ -18085,6 +18314,8 @@ function binary(input) {
|
|
|
18085
18314
|
family: "binary",
|
|
18086
18315
|
deviceType: DeviceType.Sensor,
|
|
18087
18316
|
memberDeviceType: DeviceType.Sensor,
|
|
18317
|
+
memberDeviceTypes: [DeviceType.Sensor],
|
|
18318
|
+
activeWhen: void 0,
|
|
18088
18319
|
commandCaps: [],
|
|
18089
18320
|
quantity: "none",
|
|
18090
18321
|
baseUnit: void 0,
|
|
@@ -18102,7 +18333,7 @@ var GROUP_TEMPLATES = [
|
|
|
18102
18333
|
quantity: "temperature",
|
|
18103
18334
|
defaultAggregate: "mean",
|
|
18104
18335
|
empty: "null",
|
|
18105
|
-
companions: [NOW]
|
|
18336
|
+
companions: [NOW$2]
|
|
18106
18337
|
}),
|
|
18107
18338
|
numeric({
|
|
18108
18339
|
id: "humidity",
|
|
@@ -18113,7 +18344,7 @@ var GROUP_TEMPLATES = [
|
|
|
18113
18344
|
quantity: "humidity",
|
|
18114
18345
|
defaultAggregate: "mean",
|
|
18115
18346
|
empty: "null",
|
|
18116
|
-
companions: [NOW]
|
|
18347
|
+
companions: [NOW$2]
|
|
18117
18348
|
}),
|
|
18118
18349
|
numeric({
|
|
18119
18350
|
id: "pressure",
|
|
@@ -18124,7 +18355,7 @@ var GROUP_TEMPLATES = [
|
|
|
18124
18355
|
quantity: "pressure",
|
|
18125
18356
|
defaultAggregate: "mean",
|
|
18126
18357
|
empty: "null",
|
|
18127
|
-
companions: [NOW]
|
|
18358
|
+
companions: [NOW$2]
|
|
18128
18359
|
}),
|
|
18129
18360
|
numeric({
|
|
18130
18361
|
id: "illuminance",
|
|
@@ -18135,7 +18366,7 @@ var GROUP_TEMPLATES = [
|
|
|
18135
18366
|
quantity: "illuminance",
|
|
18136
18367
|
defaultAggregate: "mean",
|
|
18137
18368
|
empty: "null",
|
|
18138
|
-
companions: [NOW]
|
|
18369
|
+
companions: [NOW$2]
|
|
18139
18370
|
}),
|
|
18140
18371
|
numeric({
|
|
18141
18372
|
id: "power",
|
|
@@ -18146,7 +18377,7 @@ var GROUP_TEMPLATES = [
|
|
|
18146
18377
|
quantity: "power",
|
|
18147
18378
|
defaultAggregate: "sum",
|
|
18148
18379
|
empty: "omit",
|
|
18149
|
-
companions: [NOW]
|
|
18380
|
+
companions: [NOW$2]
|
|
18150
18381
|
}),
|
|
18151
18382
|
numeric({
|
|
18152
18383
|
id: "energy",
|
|
@@ -18157,7 +18388,7 @@ var GROUP_TEMPLATES = [
|
|
|
18157
18388
|
quantity: "energy",
|
|
18158
18389
|
defaultAggregate: "sum",
|
|
18159
18390
|
empty: "omit",
|
|
18160
|
-
companions: [NOW]
|
|
18391
|
+
companions: [NOW$2]
|
|
18161
18392
|
}),
|
|
18162
18393
|
numeric({
|
|
18163
18394
|
id: "battery",
|
|
@@ -18192,7 +18423,7 @@ var GROUP_TEMPLATES = [
|
|
|
18192
18423
|
quantity: "device",
|
|
18193
18424
|
defaultAggregate: "mean",
|
|
18194
18425
|
empty: "null",
|
|
18195
|
-
companions: [NOW]
|
|
18426
|
+
companions: [NOW$2]
|
|
18196
18427
|
}),
|
|
18197
18428
|
binary({
|
|
18198
18429
|
id: "motion",
|
|
@@ -18286,6 +18517,11 @@ var GROUP_TEMPLATES = [
|
|
|
18286
18517
|
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.",
|
|
18287
18518
|
deviceType: DeviceType.Switch,
|
|
18288
18519
|
outputCap: "switch",
|
|
18520
|
+
outputField: "on",
|
|
18521
|
+
member: {
|
|
18522
|
+
cap: "switch",
|
|
18523
|
+
fieldPath: "on"
|
|
18524
|
+
},
|
|
18289
18525
|
commandCaps: ["switch"]
|
|
18290
18526
|
}),
|
|
18291
18527
|
actuator({
|
|
@@ -18293,34 +18529,136 @@ var GROUP_TEMPLATES = [
|
|
|
18293
18529
|
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.",
|
|
18294
18530
|
deviceType: DeviceType.Light,
|
|
18295
18531
|
outputCap: "switch",
|
|
18532
|
+
outputField: "on",
|
|
18533
|
+
member: {
|
|
18534
|
+
cap: "switch",
|
|
18535
|
+
fieldPath: "on"
|
|
18536
|
+
},
|
|
18296
18537
|
commandCaps: [
|
|
18297
18538
|
"switch",
|
|
18298
18539
|
"brightness",
|
|
18299
18540
|
"color"
|
|
18300
18541
|
]
|
|
18542
|
+
}),
|
|
18543
|
+
actuator({
|
|
18544
|
+
id: "fan",
|
|
18545
|
+
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.",
|
|
18546
|
+
deviceType: DeviceType.Fan,
|
|
18547
|
+
outputCap: "switch",
|
|
18548
|
+
outputField: "on",
|
|
18549
|
+
member: {
|
|
18550
|
+
cap: "switch",
|
|
18551
|
+
fieldPath: "on"
|
|
18552
|
+
},
|
|
18553
|
+
commandCaps: ["switch", "fan-control"]
|
|
18554
|
+
}),
|
|
18555
|
+
actuator({
|
|
18556
|
+
id: "cover",
|
|
18557
|
+
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.",
|
|
18558
|
+
deviceType: DeviceType.Cover,
|
|
18559
|
+
outputCap: "group-active",
|
|
18560
|
+
outputField: "active",
|
|
18561
|
+
member: {
|
|
18562
|
+
cap: "cover",
|
|
18563
|
+
fieldPath: "state"
|
|
18564
|
+
},
|
|
18565
|
+
activeWhen: [
|
|
18566
|
+
"open",
|
|
18567
|
+
"opening",
|
|
18568
|
+
"stopped"
|
|
18569
|
+
],
|
|
18570
|
+
commandCaps: ["cover"]
|
|
18571
|
+
}),
|
|
18572
|
+
actuator({
|
|
18573
|
+
id: "valve",
|
|
18574
|
+
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.",
|
|
18575
|
+
deviceType: DeviceType.Valve,
|
|
18576
|
+
outputCap: "group-active",
|
|
18577
|
+
outputField: "active",
|
|
18578
|
+
member: {
|
|
18579
|
+
cap: "valve",
|
|
18580
|
+
fieldPath: "state"
|
|
18581
|
+
},
|
|
18582
|
+
activeWhen: [
|
|
18583
|
+
"open",
|
|
18584
|
+
"opening",
|
|
18585
|
+
"stopped"
|
|
18586
|
+
],
|
|
18587
|
+
commandCaps: ["valve"]
|
|
18588
|
+
}),
|
|
18589
|
+
actuator({
|
|
18590
|
+
id: "lock",
|
|
18591
|
+
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.",
|
|
18592
|
+
deviceType: DeviceType.Lock,
|
|
18593
|
+
outputCap: "group-active",
|
|
18594
|
+
outputField: "active",
|
|
18595
|
+
member: {
|
|
18596
|
+
cap: "lock-control",
|
|
18597
|
+
fieldPath: "state"
|
|
18598
|
+
},
|
|
18599
|
+
activeWhen: ["locked"],
|
|
18600
|
+
commandCaps: ["lock-control"]
|
|
18601
|
+
}),
|
|
18602
|
+
actuator({
|
|
18603
|
+
id: "media-player",
|
|
18604
|
+
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.",
|
|
18605
|
+
deviceType: DeviceType.MediaPlayer,
|
|
18606
|
+
outputCap: "group-active",
|
|
18607
|
+
outputField: "active",
|
|
18608
|
+
member: {
|
|
18609
|
+
cap: "media-player",
|
|
18610
|
+
fieldPath: "state"
|
|
18611
|
+
},
|
|
18612
|
+
activeWhen: ["playing", "buffering"],
|
|
18613
|
+
commandCaps: ["media-player"]
|
|
18614
|
+
}),
|
|
18615
|
+
actuator({
|
|
18616
|
+
id: "climate",
|
|
18617
|
+
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.",
|
|
18618
|
+
deviceType: DeviceType.Thermostat,
|
|
18619
|
+
memberDeviceTypes: [DeviceType.Thermostat, DeviceType.Climate],
|
|
18620
|
+
outputCap: "group-active",
|
|
18621
|
+
outputField: "active",
|
|
18622
|
+
member: {
|
|
18623
|
+
cap: "climate-control",
|
|
18624
|
+
fieldPath: "mode"
|
|
18625
|
+
},
|
|
18626
|
+
activeWhen: [
|
|
18627
|
+
"heat",
|
|
18628
|
+
"cool",
|
|
18629
|
+
"auto",
|
|
18630
|
+
"heat_cool",
|
|
18631
|
+
"fan_only",
|
|
18632
|
+
"dry"
|
|
18633
|
+
],
|
|
18634
|
+
commandCaps: ["climate-control"]
|
|
18301
18635
|
})
|
|
18302
18636
|
];
|
|
18303
18637
|
function actuator(input) {
|
|
18304
18638
|
return {
|
|
18305
|
-
|
|
18639
|
+
id: input.id,
|
|
18640
|
+
summary: input.summary,
|
|
18641
|
+
deviceType: input.deviceType,
|
|
18642
|
+
outputCap: input.outputCap,
|
|
18643
|
+
outputField: input.outputField,
|
|
18644
|
+
commandCaps: input.commandCaps,
|
|
18306
18645
|
family: "actuator",
|
|
18307
18646
|
role: void 0,
|
|
18308
18647
|
memberDeviceType: input.deviceType,
|
|
18309
|
-
|
|
18648
|
+
memberDeviceTypes: input.memberDeviceTypes ?? [input.deviceType],
|
|
18649
|
+
activeWhen: input.activeWhen,
|
|
18310
18650
|
quantity: "none",
|
|
18311
18651
|
baseUnit: void 0,
|
|
18312
18652
|
aggregates: BINARY_AGGREGATES,
|
|
18313
18653
|
defaultAggregate: "any",
|
|
18314
18654
|
empty: "offline",
|
|
18315
|
-
accept: [
|
|
18316
|
-
cap: "switch",
|
|
18317
|
-
fieldPath: "on"
|
|
18318
|
-
}],
|
|
18655
|
+
accept: [input.member],
|
|
18319
18656
|
companions: [CHANGED]
|
|
18320
18657
|
};
|
|
18321
18658
|
}
|
|
18322
18659
|
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18323
18660
|
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18661
|
+
DeviceType.Camera;
|
|
18324
18662
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18325
18663
|
/**
|
|
18326
18664
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -43335,7 +43673,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
43335
43673
|
});
|
|
43336
43674
|
/**
|
|
43337
43675
|
* Optional, richer endpoint shape returned by providers that expose
|
|
43338
|
-
* MORE than one ingress concurrently (Tailscale
|
|
43676
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
43339
43677
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
43340
43678
|
* the originating provider config (mode + sourcePort) so the
|
|
43341
43679
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -45978,7 +46316,20 @@ var NcRuleInputSchema = object({
|
|
|
45978
46316
|
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
45979
46317
|
* path does not run Zod defaults.
|
|
45980
46318
|
*/
|
|
45981
|
-
groupingSec: number().int().min(5).max(60).optional()
|
|
46319
|
+
groupingSec: number().int().min(5).max(60).optional(),
|
|
46320
|
+
/**
|
|
46321
|
+
* ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
|
|
46322
|
+
* carries "Correct" / "Wrong" buttons (and, where the channel has room, a
|
|
46323
|
+
* "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
|
|
46324
|
+
* same mark the Library writes, and records whose notification it was and
|
|
46325
|
+
* when. A channel with no buttons gets the same two choices as links.
|
|
46326
|
+
*
|
|
46327
|
+
* `.optional()`, never `.default()` (a Zod default does not run on the addon
|
|
46328
|
+
* cap path): absent and `false` both mean off, which is what every rule
|
|
46329
|
+
* authored before this field meant. An editor turns it off by writing
|
|
46330
|
+
* `false`, so it needs no `clear` key.
|
|
46331
|
+
*/
|
|
46332
|
+
askVerdict: boolean().optional()
|
|
45982
46333
|
});
|
|
45983
46334
|
/**
|
|
45984
46335
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -56448,7 +56799,7 @@ var BatteryStatusSchema = object({
|
|
|
56448
56799
|
*/
|
|
56449
56800
|
binary: boolean().optional().meta({ label: "Binary indicator" })
|
|
56450
56801
|
});
|
|
56451
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
|
|
56802
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter;
|
|
56452
56803
|
method(object({
|
|
56453
56804
|
deviceId: number(),
|
|
56454
56805
|
/** Bound on the wait. Sensible range 3000–10000ms. */
|
|
@@ -58192,7 +58543,13 @@ results: array(object({
|
|
|
58192
58543
|
/** Ms epoch of the attempt. */
|
|
58193
58544
|
at: number()
|
|
58194
58545
|
})) });
|
|
58195
|
-
DeviceType.Switch, DeviceType.Light;
|
|
58546
|
+
DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58547
|
+
object({
|
|
58548
|
+
active: boolean().meta({ label: "Active" }),
|
|
58549
|
+
/** Ms epoch when the slice was last updated. */
|
|
58550
|
+
lastChangedAt: number()
|
|
58551
|
+
});
|
|
58552
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Climate, DeviceType.Thermostat;
|
|
58196
58553
|
object({
|
|
58197
58554
|
/** Members whose current value entered the aggregate. */
|
|
58198
58555
|
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
@@ -58210,7 +58567,7 @@ object({
|
|
|
58210
58567
|
label: "Members"
|
|
58211
58568
|
}))
|
|
58212
58569
|
});
|
|
58213
|
-
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58570
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Cover, DeviceType.Valve, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.Thermostat, DeviceType.Climate;
|
|
58214
58571
|
object({
|
|
58215
58572
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58216
58573
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -59117,7 +59474,14 @@ DeviceType.Lock, method(object({
|
|
|
59117
59474
|
auth: "protected"
|
|
59118
59475
|
}), method(object({
|
|
59119
59476
|
deviceId: number().int().nonnegative(),
|
|
59120
|
-
code: string().min(1).optional()
|
|
59477
|
+
code: string().min(1).optional(),
|
|
59478
|
+
/**
|
|
59479
|
+
* Honoured by a helper lock GROUP only (D944): unlocking several doors
|
|
59480
|
+
* with one call is refused unless the caller says it was confirmed. A
|
|
59481
|
+
* single lock ignores it. The refusal lives in the callee, so no
|
|
59482
|
+
* automation or API caller reaches the doors by skipping a dialog.
|
|
59483
|
+
*/
|
|
59484
|
+
confirm: boolean().optional()
|
|
59121
59485
|
}), _void(), {
|
|
59122
59486
|
kind: "mutation",
|
|
59123
59487
|
auth: "protected"
|
|
@@ -59125,6 +59489,11 @@ DeviceType.Lock, method(object({
|
|
|
59125
59489
|
kind: "mutation",
|
|
59126
59490
|
auth: "protected"
|
|
59127
59491
|
});
|
|
59492
|
+
object({
|
|
59493
|
+
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
59494
|
+
lastFetchedAt: number()
|
|
59495
|
+
});
|
|
59496
|
+
DeviceType.Sensor;
|
|
59128
59497
|
/**
|
|
59129
59498
|
* Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
|
|
59130
59499
|
* Apple TV, Spotify, Roku, generic OTT receivers, …) on
|
|
@@ -61032,9 +61401,9 @@ object({
|
|
|
61032
61401
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61033
61402
|
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61034
61403
|
/** Voltage in volts. */
|
|
61035
|
-
volts: number().optional().meta(readingMeta("voltage")),
|
|
61404
|
+
volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
61036
61405
|
/** Current in amperes. */
|
|
61037
|
-
amps: number().optional().meta(readingMeta("current")),
|
|
61406
|
+
amps: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
61038
61407
|
/** Apparent power in volt-amperes. */
|
|
61039
61408
|
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61040
61409
|
/** Power factor (0..1) if reported. */
|
|
@@ -61042,7 +61411,23 @@ object({
|
|
|
61042
61411
|
/** Ms epoch when the slice was last updated. */
|
|
61043
61412
|
lastFetchedAt: number()
|
|
61044
61413
|
});
|
|
61045
|
-
|
|
61414
|
+
[
|
|
61415
|
+
DeviceType.Sensor,
|
|
61416
|
+
DeviceType.Switch,
|
|
61417
|
+
DeviceType.Light,
|
|
61418
|
+
DeviceType.Fan,
|
|
61419
|
+
DeviceType.Climate,
|
|
61420
|
+
DeviceType.Thermostat,
|
|
61421
|
+
DeviceType.Humidifier,
|
|
61422
|
+
DeviceType.WaterHeater,
|
|
61423
|
+
DeviceType.MediaPlayer,
|
|
61424
|
+
DeviceType.Washer,
|
|
61425
|
+
DeviceType.Dryer,
|
|
61426
|
+
DeviceType.Dishwasher,
|
|
61427
|
+
DeviceType.Vacuum,
|
|
61428
|
+
DeviceType.LawnMower,
|
|
61429
|
+
DeviceType.PetFeeder
|
|
61430
|
+
].filter((type) => type !== DeviceType.Sensor);
|
|
61046
61431
|
/**
|
|
61047
61432
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
61048
61433
|
* on `DeviceType.Presence`. Read-only — no setters: presence is
|
|
@@ -61489,7 +61874,7 @@ object({
|
|
|
61489
61874
|
phase: string().nullable()
|
|
61490
61875
|
});
|
|
61491
61876
|
Object.values(DeviceType);
|
|
61492
|
-
DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
61877
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
61493
61878
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
|
|
61494
61879
|
kind: "mutation",
|
|
61495
61880
|
auth: "admin"
|
|
@@ -63528,7 +63913,7 @@ object({
|
|
|
63528
63913
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
63529
63914
|
lastChangedAt: number()
|
|
63530
63915
|
});
|
|
63531
|
-
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
63916
|
+
DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, method(object({
|
|
63532
63917
|
deviceId: number(),
|
|
63533
63918
|
on: boolean()
|
|
63534
63919
|
}), _void(), {
|
|
@@ -65220,8 +65605,9 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
65220
65605
|
kind: "mutation",
|
|
65221
65606
|
auth: "admin"
|
|
65222
65607
|
});
|
|
65608
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
65223
65609
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
65224
|
-
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.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
65610
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, 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.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
65225
65611
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
65226
65612
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
65227
65613
|
new Set(CAP_NAMES);
|
|
@@ -65274,7 +65660,7 @@ var AccessoryKind = {
|
|
|
65274
65660
|
PrivacyMask: DeviceRole.PrivacyMask
|
|
65275
65661
|
};
|
|
65276
65662
|
AccessoryKind.Siren, AccessoryKind.Floodlight, AccessoryKind.Spotlight, AccessoryKind.PirSensor, AccessoryKind.Chime, AccessoryKind.Autotrack, AccessoryKind.Nightvision, AccessoryKind.PrivacyMask;
|
|
65277
|
-
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher;
|
|
65663
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, 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;
|
|
65278
65664
|
new Set(Object.values(DeviceType));
|
|
65279
65665
|
Object.freeze({
|
|
65280
65666
|
"accessories.getStatus": {
|
|
@@ -68497,6 +68883,13 @@ Object.freeze({
|
|
|
68497
68883
|
access: "view",
|
|
68498
68884
|
role: "viewer"
|
|
68499
68885
|
},
|
|
68886
|
+
"groupActive.getStatus": {
|
|
68887
|
+
capName: "group-active",
|
|
68888
|
+
capScope: "device",
|
|
68889
|
+
addonId: null,
|
|
68890
|
+
access: "view",
|
|
68891
|
+
role: "viewer"
|
|
68892
|
+
},
|
|
68500
68893
|
"groupCommands.getStatus": {
|
|
68501
68894
|
capName: "group-commands",
|
|
68502
68895
|
capScope: "device",
|
|
@@ -69463,6 +69856,13 @@ Object.freeze({
|
|
|
69463
69856
|
access: "create",
|
|
69464
69857
|
role: "admin"
|
|
69465
69858
|
},
|
|
69859
|
+
"meter.getStatus": {
|
|
69860
|
+
capName: "meter",
|
|
69861
|
+
capScope: "device",
|
|
69862
|
+
addonId: null,
|
|
69863
|
+
access: "view",
|
|
69864
|
+
role: "viewer"
|
|
69865
|
+
},
|
|
69466
69866
|
"metricsProvider.collectSnapshot": {
|
|
69467
69867
|
capName: "metrics-provider",
|
|
69468
69868
|
capScope: "system",
|
|
@@ -77561,7 +77961,39 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
77561
77961
|
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
77562
77962
|
icon: "square"
|
|
77563
77963
|
}
|
|
77564
|
-
}
|
|
77964
|
+
},
|
|
77965
|
+
overrides: { byType: {
|
|
77966
|
+
[DeviceType.Washer]: {
|
|
77967
|
+
state: { running: {
|
|
77968
|
+
whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
|
|
77969
|
+
whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
|
|
77970
|
+
} },
|
|
77971
|
+
events: {
|
|
77972
|
+
onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
|
|
77973
|
+
onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
|
|
77974
|
+
}
|
|
77975
|
+
},
|
|
77976
|
+
[DeviceType.Dryer]: {
|
|
77977
|
+
state: { running: {
|
|
77978
|
+
whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
|
|
77979
|
+
whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
|
|
77980
|
+
} },
|
|
77981
|
+
events: {
|
|
77982
|
+
onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
|
|
77983
|
+
onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
|
|
77984
|
+
}
|
|
77985
|
+
},
|
|
77986
|
+
[DeviceType.Dishwasher]: {
|
|
77987
|
+
state: { running: {
|
|
77988
|
+
whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
|
|
77989
|
+
whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
|
|
77990
|
+
} },
|
|
77991
|
+
events: {
|
|
77992
|
+
onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
|
|
77993
|
+
onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
|
|
77994
|
+
}
|
|
77995
|
+
}
|
|
77996
|
+
} }
|
|
77565
77997
|
},
|
|
77566
77998
|
update: {
|
|
77567
77999
|
scope: "device",
|
|
@@ -78333,6 +78765,10 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78333
78765
|
icon: "flame"
|
|
78334
78766
|
}]
|
|
78335
78767
|
},
|
|
78768
|
+
"group-active": {
|
|
78769
|
+
scope: "device",
|
|
78770
|
+
noun: t("Group state", "Stato del gruppo")
|
|
78771
|
+
},
|
|
78336
78772
|
"group-commands": {
|
|
78337
78773
|
scope: "device",
|
|
78338
78774
|
noun: t("Group command", "Comando di gruppo")
|
|
@@ -78389,6 +78825,17 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78389
78825
|
}],
|
|
78390
78826
|
events: { onMotionChanged: { notOperatorFacing: "the `detected` state trigger phrases both edges, from the mirror that survives a dropped event (D49)" } }
|
|
78391
78827
|
},
|
|
78828
|
+
meter: {
|
|
78829
|
+
scope: "device",
|
|
78830
|
+
noun: t("Meter", "Contatore"),
|
|
78831
|
+
state: [{
|
|
78832
|
+
kind: "numeric",
|
|
78833
|
+
field: "value",
|
|
78834
|
+
quantity: t("the total", "il totale"),
|
|
78835
|
+
label: t("Total", "Totale"),
|
|
78836
|
+
icon: "gauge"
|
|
78837
|
+
}]
|
|
78838
|
+
},
|
|
78392
78839
|
"numeric-sensor": {
|
|
78393
78840
|
scope: "device",
|
|
78394
78841
|
noun: t("Sensor", "Sensore"),
|
|
@@ -78861,8 +79308,47 @@ function projectAction(cap, action) {
|
|
|
78861
79308
|
};
|
|
78862
79309
|
}
|
|
78863
79310
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
78864
|
-
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;
|
|
79311
|
+
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;
|
|
78865
79312
|
DeviceFeature.BatteryOperated;
|
|
79313
|
+
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
79314
|
+
var HA_AS = "a power sensor (device_class power). Home Assistant has no laundry domain. running-state stays unexported until a null reading can be published as unavailable.";
|
|
79315
|
+
var HOMEKIT_REASON = "HomeKit has no laundry-appliance service. The export tab would pair an accessory with nothing on it: running-state is withheld until a null reading can be unavailable, and power is not a HomeKit service this export honours.";
|
|
79316
|
+
var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
|
|
79317
|
+
var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
|
|
79318
|
+
var MATTER_REASON = "No Matter export is built. The closest device types are Laundry Washer (0x0073) and Laundry Dryer (0x0074); a power threshold is not the Laundry Washer Mode cluster.";
|
|
79319
|
+
function withheld(reason) {
|
|
79320
|
+
return {
|
|
79321
|
+
[DeviceType.Washer]: {
|
|
79322
|
+
exported: false,
|
|
79323
|
+
reason
|
|
79324
|
+
},
|
|
79325
|
+
[DeviceType.Dryer]: {
|
|
79326
|
+
exported: false,
|
|
79327
|
+
reason
|
|
79328
|
+
},
|
|
79329
|
+
[DeviceType.Dishwasher]: {
|
|
79330
|
+
exported: false,
|
|
79331
|
+
reason
|
|
79332
|
+
}
|
|
79333
|
+
};
|
|
79334
|
+
}
|
|
79335
|
+
function offered(received) {
|
|
79336
|
+
return {
|
|
79337
|
+
[DeviceType.Washer]: {
|
|
79338
|
+
exported: true,
|
|
79339
|
+
as: received
|
|
79340
|
+
},
|
|
79341
|
+
[DeviceType.Dryer]: {
|
|
79342
|
+
exported: true,
|
|
79343
|
+
as: received
|
|
79344
|
+
},
|
|
79345
|
+
[DeviceType.Dishwasher]: {
|
|
79346
|
+
exported: true,
|
|
79347
|
+
as: received
|
|
79348
|
+
}
|
|
79349
|
+
};
|
|
79350
|
+
}
|
|
79351
|
+
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
78866
79352
|
Object.freeze({
|
|
78867
79353
|
"accessories.getStatus": [{
|
|
78868
79354
|
name: "deviceId",
|
|
@@ -79829,6 +80315,11 @@ Object.freeze({
|
|
|
79829
80315
|
form: "single",
|
|
79830
80316
|
optional: false
|
|
79831
80317
|
}],
|
|
80318
|
+
"groupActive.getStatus": [{
|
|
80319
|
+
name: "deviceId",
|
|
80320
|
+
form: "single",
|
|
80321
|
+
optional: false
|
|
80322
|
+
}],
|
|
79832
80323
|
"groupCommands.getStatus": [{
|
|
79833
80324
|
name: "deviceId",
|
|
79834
80325
|
form: "single",
|
|
@@ -80039,6 +80530,11 @@ Object.freeze({
|
|
|
80039
80530
|
form: "single",
|
|
80040
80531
|
optional: false
|
|
80041
80532
|
}],
|
|
80533
|
+
"meter.getStatus": [{
|
|
80534
|
+
name: "deviceId",
|
|
80535
|
+
form: "single",
|
|
80536
|
+
optional: false
|
|
80537
|
+
}],
|
|
80042
80538
|
"motion.getStatus": [{
|
|
80043
80539
|
name: "deviceId",
|
|
80044
80540
|
form: "single",
|
|
@@ -81646,7 +82142,6 @@ Object.freeze({
|
|
|
81646
82142
|
"network-access": "ingress",
|
|
81647
82143
|
"smtp-provider": "email"
|
|
81648
82144
|
});
|
|
81649
|
-
DeviceType.Camera;
|
|
81650
82145
|
/**
|
|
81651
82146
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
81652
82147
|
* `z.infer`, they do not restate the shape.
|