@camstack/addon-provider-homeassistant 1.2.626 → 1.2.627
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 +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/{dist-B7nW5y58.mjs → dist-BFnk4bwH.mjs} +437 -14
- package/dist/{dist-1tLY30OG.js → dist-CRwUHjY7.js} +437 -14
- package/dist/ha-export/ha-export.addon.js +5 -1
- package/dist/ha-export/ha-export.addon.mjs +5 -1
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-CRwUHjY7.js");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let node_zlib = require("node:zlib");
|
|
5
5
|
//#region src/ha-admin-link.ts
|
package/dist/addon.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as lockControlCapability, $t as unknown, A as calendarSourceCapability, At as DeviceFeature, B as deviceAdminLinkCapability, Bt as entryBody, C as bestLocationMatch, Ct as tryConvertUnit, D as buildAddonRouteProvider, Dt as vibrationCapability, E as brokerCapability, Et as valveCapability, Ft as RecordSecretUnavailableError, G as fanControlCapability, Gt as boolean, It as baseUnitOf, J as humidifierCapability, Jt as number, K as floodCapability, Kt as discriminatedUnion, L as contactCapability, Lt as createEvent, M as climateControlCapability, Mt as DeviceType, N as colorCapability, Nt as errMsg, O as buildDeviceAdminUrl, Ot as waterHeaterCapability, P as connectivityCapability, Q as lawnMowerControlCapability, Qt as union, R as controlCapability, Rt as defineEntryKind, S as batteryCapability, St as tryConvertDelta, T as brightnessCapability, Tt as vacuumControlCapability, U as enumSensorCapability, Ut as _enum, V as deviceAdoptionCapability, W as eventEmitterCapability, Wt as array, X as imageCapability, Xt as record, Y as humiditySensorCapability, Yt as object, Z as ingestReading, Zt as string, _ as addonRoutesCapability, _t as scriptRunnerCapability, at as numericSensorCapability, b as ambientLightSensorCapability, bt as tamperCapability, ct as powerMeterCapability, dt as pressureSensorCapability, en as url, et as mediaPlayerCapability, ft as quantityFromUnit, g as accessoriesCapability, gt as runningStateCapability, h as TargetSchema, ht as runningFromVacuumState, it as notifierCapability, j as carbonMonoxideCapability, jt as DeviceRole, k as buttonCapability, kt as weatherCapability, lt as prepareNotification, m as RUNNING_STATE_COLD, mt as runningFromMediaPlayer, n as BaseDevice, nt as normalizeUnit, pt as runningFromLawnMower, q as gasCapability, qt as literal, r as BaseDeviceProvider, rt as notificationOutputCapability, st as parseAdminBase, tn as EventCategory, tt as motionCapability, u as EnumSensorDateTimeFormatSchema, ut as presenceCapability, v as airQualitySensorCapability, vt as smokeCapability, w as binaryCapability, wt as updateCapability, x as automationControlCapability, xt as temperatureSensorCapability, y as alarmPanelCapability, yt as switchCapability, z as coverCapability, zt as defineRecordKinds } from "./dist-
|
|
1
|
+
import { $ as lockControlCapability, $t as unknown, A as calendarSourceCapability, At as DeviceFeature, B as deviceAdminLinkCapability, Bt as entryBody, C as bestLocationMatch, Ct as tryConvertUnit, D as buildAddonRouteProvider, Dt as vibrationCapability, E as brokerCapability, Et as valveCapability, Ft as RecordSecretUnavailableError, G as fanControlCapability, Gt as boolean, It as baseUnitOf, J as humidifierCapability, Jt as number, K as floodCapability, Kt as discriminatedUnion, L as contactCapability, Lt as createEvent, M as climateControlCapability, Mt as DeviceType, N as colorCapability, Nt as errMsg, O as buildDeviceAdminUrl, Ot as waterHeaterCapability, P as connectivityCapability, Q as lawnMowerControlCapability, Qt as union, R as controlCapability, Rt as defineEntryKind, S as batteryCapability, St as tryConvertDelta, T as brightnessCapability, Tt as vacuumControlCapability, U as enumSensorCapability, Ut as _enum, V as deviceAdoptionCapability, W as eventEmitterCapability, Wt as array, X as imageCapability, Xt as record, Y as humiditySensorCapability, Yt as object, Z as ingestReading, Zt as string, _ as addonRoutesCapability, _t as scriptRunnerCapability, at as numericSensorCapability, b as ambientLightSensorCapability, bt as tamperCapability, ct as powerMeterCapability, dt as pressureSensorCapability, en as url, et as mediaPlayerCapability, ft as quantityFromUnit, g as accessoriesCapability, gt as runningStateCapability, h as TargetSchema, ht as runningFromVacuumState, it as notifierCapability, j as carbonMonoxideCapability, jt as DeviceRole, k as buttonCapability, kt as weatherCapability, lt as prepareNotification, m as RUNNING_STATE_COLD, mt as runningFromMediaPlayer, n as BaseDevice, nt as normalizeUnit, pt as runningFromLawnMower, q as gasCapability, qt as literal, r as BaseDeviceProvider, rt as notificationOutputCapability, st as parseAdminBase, tn as EventCategory, tt as motionCapability, u as EnumSensorDateTimeFormatSchema, ut as presenceCapability, v as airQualitySensorCapability, vt as smokeCapability, w as binaryCapability, wt as updateCapability, x as automationControlCapability, xt as temperatureSensorCapability, y as alarmPanelCapability, yt as switchCapability, z as coverCapability, zt as defineRecordKinds } from "./dist-BFnk4bwH.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
|
|
4
4
|
//#region src/ha-admin-link.ts
|
|
@@ -5566,7 +5566,7 @@ var ZodIssueCode = {
|
|
|
5566
5566
|
var ZodFirstPartyTypeKind;
|
|
5567
5567
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5568
5568
|
//#endregion
|
|
5569
|
-
//#region ../types/dist/sleep-
|
|
5569
|
+
//#region ../types/dist/sleep-B81gwQuR.mjs
|
|
5570
5570
|
/**
|
|
5571
5571
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5572
5572
|
* window to float samples (D455).
|
|
@@ -9009,6 +9009,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9009
9009
|
"filesystem-browse",
|
|
9010
9010
|
"flood",
|
|
9011
9011
|
"gas",
|
|
9012
|
+
"group-status",
|
|
9012
9013
|
"heating-valve",
|
|
9013
9014
|
"humidifier",
|
|
9014
9015
|
"humidity-sensor",
|
|
@@ -9827,6 +9828,20 @@ Object.freeze({
|
|
|
9827
9828
|
"path": "detected",
|
|
9828
9829
|
"valueType": "boolean"
|
|
9829
9830
|
}],
|
|
9831
|
+
"group-status": [
|
|
9832
|
+
{
|
|
9833
|
+
"path": "included",
|
|
9834
|
+
"valueType": "number"
|
|
9835
|
+
},
|
|
9836
|
+
{
|
|
9837
|
+
"path": "excluded",
|
|
9838
|
+
"valueType": "number"
|
|
9839
|
+
},
|
|
9840
|
+
{
|
|
9841
|
+
"path": "total",
|
|
9842
|
+
"valueType": "number"
|
|
9843
|
+
}
|
|
9844
|
+
],
|
|
9830
9845
|
"heating-valve": [{
|
|
9831
9846
|
"path": "position",
|
|
9832
9847
|
"valueType": "number"
|
|
@@ -11168,7 +11183,7 @@ function errMsg(err) {
|
|
|
11168
11183
|
return String(err);
|
|
11169
11184
|
}
|
|
11170
11185
|
//#endregion
|
|
11171
|
-
//#region ../types/dist/composition-
|
|
11186
|
+
//#region ../types/dist/composition-B85l9j1M.mjs
|
|
11172
11187
|
/**
|
|
11173
11188
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11174
11189
|
*
|
|
@@ -11923,15 +11938,67 @@ function validateExpressionSource(src) {
|
|
|
11923
11938
|
}
|
|
11924
11939
|
return null;
|
|
11925
11940
|
}
|
|
11926
|
-
/**
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11941
|
+
/**
|
|
11942
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11943
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11944
|
+
* `composition.ts` (D659).
|
|
11945
|
+
*/
|
|
11930
11946
|
var CompositionSourceRefSchema = object({
|
|
11931
11947
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11932
11948
|
addonId: string().min(1),
|
|
11933
11949
|
stableId: string().min(1)
|
|
11934
11950
|
});
|
|
11951
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11952
|
+
"temperature",
|
|
11953
|
+
"humidity",
|
|
11954
|
+
"pressure",
|
|
11955
|
+
"illuminance",
|
|
11956
|
+
"power",
|
|
11957
|
+
"energy",
|
|
11958
|
+
"battery",
|
|
11959
|
+
"numeric",
|
|
11960
|
+
"motion",
|
|
11961
|
+
"contact",
|
|
11962
|
+
"leak",
|
|
11963
|
+
"smoke",
|
|
11964
|
+
"occupancy",
|
|
11965
|
+
"binary"
|
|
11966
|
+
];
|
|
11967
|
+
var NUMERIC_AGGREGATES = [
|
|
11968
|
+
"mean",
|
|
11969
|
+
"median",
|
|
11970
|
+
"min",
|
|
11971
|
+
"max",
|
|
11972
|
+
"sum"
|
|
11973
|
+
];
|
|
11974
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11975
|
+
var AGGREGATE_REDUCERS = [
|
|
11976
|
+
"mean",
|
|
11977
|
+
"median",
|
|
11978
|
+
"min",
|
|
11979
|
+
"max",
|
|
11980
|
+
"sum",
|
|
11981
|
+
"any",
|
|
11982
|
+
"all"
|
|
11983
|
+
];
|
|
11984
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11985
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11986
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11987
|
+
var HelperMemberSchema = object({
|
|
11988
|
+
source: CompositionSourceRefSchema,
|
|
11989
|
+
cap: string().min(1),
|
|
11990
|
+
fieldPath: string().min(1)
|
|
11991
|
+
});
|
|
11992
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11993
|
+
kind: literal("group"),
|
|
11994
|
+
templateId: GroupTemplateIdSchema,
|
|
11995
|
+
aggregate: AggregateReducerSchema,
|
|
11996
|
+
members: array(HelperMemberSchema).min(1).max(64)
|
|
11997
|
+
})]);
|
|
11998
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11999
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
12000
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
12001
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11935
12002
|
/** One field of one capability of one source device. */
|
|
11936
12003
|
var CompositionFieldReadSchema = object({
|
|
11937
12004
|
source: CompositionSourceRefSchema,
|
|
@@ -11975,7 +12042,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11975
12042
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11976
12043
|
CompositionFromSourceSchema,
|
|
11977
12044
|
CompositionExpressionSourceSchema,
|
|
11978
|
-
CompositionCodeSourceSchema
|
|
12045
|
+
CompositionCodeSourceSchema,
|
|
12046
|
+
object({
|
|
12047
|
+
kind: literal("aggregate"),
|
|
12048
|
+
reducer: _enum([
|
|
12049
|
+
"mean",
|
|
12050
|
+
"median",
|
|
12051
|
+
"min",
|
|
12052
|
+
"max",
|
|
12053
|
+
"sum",
|
|
12054
|
+
"any",
|
|
12055
|
+
"all"
|
|
12056
|
+
]),
|
|
12057
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12058
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12059
|
+
publish: _enum([
|
|
12060
|
+
"value",
|
|
12061
|
+
"included",
|
|
12062
|
+
"excluded",
|
|
12063
|
+
"total"
|
|
12064
|
+
]),
|
|
12065
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12066
|
+
empty: _enum([
|
|
12067
|
+
"null",
|
|
12068
|
+
"omit",
|
|
12069
|
+
"offline"
|
|
12070
|
+
])
|
|
12071
|
+
})
|
|
11979
12072
|
]);
|
|
11980
12073
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11981
12074
|
kind: literal("forward"),
|
|
@@ -12021,7 +12114,13 @@ var CompositionSchema = object({
|
|
|
12021
12114
|
kind: literal("existing"),
|
|
12022
12115
|
device: CompositionSourceRefSchema
|
|
12023
12116
|
})]),
|
|
12024
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12117
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12118
|
+
/**
|
|
12119
|
+
* Present when the block is a helper template. Absent on a free
|
|
12120
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12121
|
+
* never the compiled features.
|
|
12122
|
+
*/
|
|
12123
|
+
helper: HelperSpecSchema.optional()
|
|
12025
12124
|
}).superRefine((composition, ctx) => {
|
|
12026
12125
|
const seen = /* @__PURE__ */ new Set();
|
|
12027
12126
|
composition.features.forEach((feature, index) => {
|
|
@@ -18442,7 +18541,10 @@ var CompositionProblemSchema = object({
|
|
|
18442
18541
|
"target-missing",
|
|
18443
18542
|
"target-unreadable",
|
|
18444
18543
|
"not-replaceable",
|
|
18445
|
-
"native-capability-replace"
|
|
18544
|
+
"native-capability-replace",
|
|
18545
|
+
"mixed-quantity",
|
|
18546
|
+
"helper-mismatch",
|
|
18547
|
+
"member-constraint"
|
|
18446
18548
|
]),
|
|
18447
18549
|
path: string(),
|
|
18448
18550
|
message: string()
|
|
@@ -18463,7 +18565,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18463
18565
|
"null",
|
|
18464
18566
|
"offline",
|
|
18465
18567
|
"unknown",
|
|
18466
|
-
"release"
|
|
18568
|
+
"release",
|
|
18569
|
+
"omit"
|
|
18467
18570
|
]);
|
|
18468
18571
|
/**
|
|
18469
18572
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18677,6 +18780,235 @@ Object.freeze({
|
|
|
18677
18780
|
result: ["number", "null"]
|
|
18678
18781
|
}
|
|
18679
18782
|
});
|
|
18783
|
+
/**
|
|
18784
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18785
|
+
* Data, not a form default written into the block.
|
|
18786
|
+
*/
|
|
18787
|
+
var NOW = {
|
|
18788
|
+
fieldPath: "lastFetchedAt",
|
|
18789
|
+
expr: "now"
|
|
18790
|
+
};
|
|
18791
|
+
var CHANGED = {
|
|
18792
|
+
fieldPath: "lastChangedAt",
|
|
18793
|
+
expr: "now"
|
|
18794
|
+
};
|
|
18795
|
+
function numeric(input) {
|
|
18796
|
+
return {
|
|
18797
|
+
...input,
|
|
18798
|
+
family: "numeric",
|
|
18799
|
+
deviceType: DeviceType.Sensor,
|
|
18800
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18801
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18802
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18803
|
+
accept: [{
|
|
18804
|
+
cap: input.outputCap,
|
|
18805
|
+
fieldPath: input.outputField
|
|
18806
|
+
}]
|
|
18807
|
+
};
|
|
18808
|
+
}
|
|
18809
|
+
function binary(input) {
|
|
18810
|
+
return {
|
|
18811
|
+
...input,
|
|
18812
|
+
family: "binary",
|
|
18813
|
+
deviceType: DeviceType.Sensor,
|
|
18814
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18815
|
+
quantity: "none",
|
|
18816
|
+
baseUnit: void 0,
|
|
18817
|
+
aggregates: BINARY_AGGREGATES,
|
|
18818
|
+
empty: "offline"
|
|
18819
|
+
};
|
|
18820
|
+
}
|
|
18821
|
+
var GROUP_TEMPLATES = [
|
|
18822
|
+
numeric({
|
|
18823
|
+
id: "temperature",
|
|
18824
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18825
|
+
role: DeviceRole.TemperatureSensor,
|
|
18826
|
+
outputCap: "temperature-sensor",
|
|
18827
|
+
outputField: "celsius",
|
|
18828
|
+
quantity: "temperature",
|
|
18829
|
+
defaultAggregate: "mean",
|
|
18830
|
+
empty: "null",
|
|
18831
|
+
companions: [NOW]
|
|
18832
|
+
}),
|
|
18833
|
+
numeric({
|
|
18834
|
+
id: "humidity",
|
|
18835
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18836
|
+
role: DeviceRole.HumiditySensor,
|
|
18837
|
+
outputCap: "humidity-sensor",
|
|
18838
|
+
outputField: "percent",
|
|
18839
|
+
quantity: "humidity",
|
|
18840
|
+
defaultAggregate: "mean",
|
|
18841
|
+
empty: "null",
|
|
18842
|
+
companions: [NOW]
|
|
18843
|
+
}),
|
|
18844
|
+
numeric({
|
|
18845
|
+
id: "pressure",
|
|
18846
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18847
|
+
role: DeviceRole.PressureSensor,
|
|
18848
|
+
outputCap: "pressure-sensor",
|
|
18849
|
+
outputField: "hpa",
|
|
18850
|
+
quantity: "pressure",
|
|
18851
|
+
defaultAggregate: "mean",
|
|
18852
|
+
empty: "null",
|
|
18853
|
+
companions: [NOW]
|
|
18854
|
+
}),
|
|
18855
|
+
numeric({
|
|
18856
|
+
id: "illuminance",
|
|
18857
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18858
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18859
|
+
outputCap: "ambient-light-sensor",
|
|
18860
|
+
outputField: "lux",
|
|
18861
|
+
quantity: "illuminance",
|
|
18862
|
+
defaultAggregate: "mean",
|
|
18863
|
+
empty: "null",
|
|
18864
|
+
companions: [NOW]
|
|
18865
|
+
}),
|
|
18866
|
+
numeric({
|
|
18867
|
+
id: "power",
|
|
18868
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18869
|
+
role: DeviceRole.PowerSensor,
|
|
18870
|
+
outputCap: "power-meter",
|
|
18871
|
+
outputField: "watts",
|
|
18872
|
+
quantity: "power",
|
|
18873
|
+
defaultAggregate: "sum",
|
|
18874
|
+
empty: "omit",
|
|
18875
|
+
companions: [NOW]
|
|
18876
|
+
}),
|
|
18877
|
+
numeric({
|
|
18878
|
+
id: "energy",
|
|
18879
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18880
|
+
role: DeviceRole.EnergySensor,
|
|
18881
|
+
outputCap: "power-meter",
|
|
18882
|
+
outputField: "kwhTotal",
|
|
18883
|
+
quantity: "energy",
|
|
18884
|
+
defaultAggregate: "sum",
|
|
18885
|
+
empty: "omit",
|
|
18886
|
+
companions: [NOW]
|
|
18887
|
+
}),
|
|
18888
|
+
numeric({
|
|
18889
|
+
id: "battery",
|
|
18890
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18891
|
+
role: DeviceRole.BatterySensor,
|
|
18892
|
+
outputCap: "battery",
|
|
18893
|
+
outputField: "percentage",
|
|
18894
|
+
quantity: "percentage",
|
|
18895
|
+
defaultAggregate: "mean",
|
|
18896
|
+
empty: "null",
|
|
18897
|
+
companions: [
|
|
18898
|
+
{
|
|
18899
|
+
fieldPath: "charging",
|
|
18900
|
+
expr: "\"unknown\""
|
|
18901
|
+
},
|
|
18902
|
+
{
|
|
18903
|
+
fieldPath: "sleeping",
|
|
18904
|
+
expr: "false"
|
|
18905
|
+
},
|
|
18906
|
+
{
|
|
18907
|
+
fieldPath: "lastUpdated",
|
|
18908
|
+
expr: "now"
|
|
18909
|
+
}
|
|
18910
|
+
]
|
|
18911
|
+
}),
|
|
18912
|
+
numeric({
|
|
18913
|
+
id: "numeric",
|
|
18914
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18915
|
+
role: DeviceRole.NumericSensor,
|
|
18916
|
+
outputCap: "numeric-sensor",
|
|
18917
|
+
outputField: "value",
|
|
18918
|
+
quantity: "device",
|
|
18919
|
+
defaultAggregate: "mean",
|
|
18920
|
+
empty: "null",
|
|
18921
|
+
companions: [NOW]
|
|
18922
|
+
}),
|
|
18923
|
+
binary({
|
|
18924
|
+
id: "motion",
|
|
18925
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18926
|
+
role: DeviceRole.MotionSensor,
|
|
18927
|
+
outputCap: "motion",
|
|
18928
|
+
outputField: "detected",
|
|
18929
|
+
defaultAggregate: "any",
|
|
18930
|
+
accept: [{
|
|
18931
|
+
cap: "motion",
|
|
18932
|
+
fieldPath: "detected"
|
|
18933
|
+
}],
|
|
18934
|
+
companions: [{
|
|
18935
|
+
fieldPath: "lastDetectedAt",
|
|
18936
|
+
expr: "null"
|
|
18937
|
+
}, {
|
|
18938
|
+
fieldPath: "autoClearAfterMs",
|
|
18939
|
+
expr: "null"
|
|
18940
|
+
}]
|
|
18941
|
+
}),
|
|
18942
|
+
binary({
|
|
18943
|
+
id: "contact",
|
|
18944
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18945
|
+
role: DeviceRole.ContactSensor,
|
|
18946
|
+
outputCap: "contact",
|
|
18947
|
+
outputField: "entryOpen",
|
|
18948
|
+
defaultAggregate: "any",
|
|
18949
|
+
accept: [{
|
|
18950
|
+
cap: "contact",
|
|
18951
|
+
fieldPath: "entryOpen"
|
|
18952
|
+
}],
|
|
18953
|
+
companions: [CHANGED]
|
|
18954
|
+
}),
|
|
18955
|
+
binary({
|
|
18956
|
+
id: "leak",
|
|
18957
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18958
|
+
role: DeviceRole.LeakSensor,
|
|
18959
|
+
outputCap: "flood",
|
|
18960
|
+
outputField: "flooded",
|
|
18961
|
+
defaultAggregate: "any",
|
|
18962
|
+
accept: [{
|
|
18963
|
+
cap: "flood",
|
|
18964
|
+
fieldPath: "flooded"
|
|
18965
|
+
}],
|
|
18966
|
+
companions: [CHANGED]
|
|
18967
|
+
}),
|
|
18968
|
+
binary({
|
|
18969
|
+
id: "smoke",
|
|
18970
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18971
|
+
role: DeviceRole.SmokeSensor,
|
|
18972
|
+
outputCap: "smoke",
|
|
18973
|
+
outputField: "detected",
|
|
18974
|
+
defaultAggregate: "any",
|
|
18975
|
+
accept: [{
|
|
18976
|
+
cap: "smoke",
|
|
18977
|
+
fieldPath: "detected"
|
|
18978
|
+
}],
|
|
18979
|
+
companions: [CHANGED]
|
|
18980
|
+
}),
|
|
18981
|
+
binary({
|
|
18982
|
+
id: "occupancy",
|
|
18983
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18984
|
+
role: DeviceRole.BinarySensor,
|
|
18985
|
+
outputCap: "binary",
|
|
18986
|
+
outputField: "on",
|
|
18987
|
+
defaultAggregate: "any",
|
|
18988
|
+
accept: [{
|
|
18989
|
+
cap: "motion",
|
|
18990
|
+
fieldPath: "detected"
|
|
18991
|
+
}, {
|
|
18992
|
+
cap: "binary",
|
|
18993
|
+
fieldPath: "on"
|
|
18994
|
+
}],
|
|
18995
|
+
companions: [CHANGED]
|
|
18996
|
+
}),
|
|
18997
|
+
binary({
|
|
18998
|
+
id: "binary",
|
|
18999
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
19000
|
+
role: DeviceRole.BinarySensor,
|
|
19001
|
+
outputCap: "binary",
|
|
19002
|
+
outputField: "on",
|
|
19003
|
+
defaultAggregate: "any",
|
|
19004
|
+
accept: [{
|
|
19005
|
+
cap: "binary",
|
|
19006
|
+
fieldPath: "on"
|
|
19007
|
+
}],
|
|
19008
|
+
companions: [CHANGED]
|
|
19009
|
+
})
|
|
19010
|
+
];
|
|
19011
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18680
19012
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18681
19013
|
/**
|
|
18682
19014
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -60531,6 +60863,51 @@ var gasCapability = {
|
|
|
60531
60863
|
* whether persisting is worth a SQLite commit. */
|
|
60532
60864
|
volatileStateFields: ["lastChangedAt"]
|
|
60533
60865
|
};
|
|
60866
|
+
/**
|
|
60867
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60868
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60869
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60870
|
+
* series that later statistics read is the output cap's own history block.
|
|
60871
|
+
*/
|
|
60872
|
+
var GroupStatusSchema = object({
|
|
60873
|
+
/** Members whose current value entered the aggregate. */
|
|
60874
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60875
|
+
precision: 0,
|
|
60876
|
+
label: "Reporting"
|
|
60877
|
+
})),
|
|
60878
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60879
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60880
|
+
precision: 0,
|
|
60881
|
+
label: "Excluded"
|
|
60882
|
+
})),
|
|
60883
|
+
/** `included` + `excluded`. */
|
|
60884
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60885
|
+
precision: 0,
|
|
60886
|
+
label: "Members"
|
|
60887
|
+
}))
|
|
60888
|
+
});
|
|
60889
|
+
var groupStatusCapability = {
|
|
60890
|
+
name: "group-status",
|
|
60891
|
+
scope: "device",
|
|
60892
|
+
deviceNative: true,
|
|
60893
|
+
mode: "singleton",
|
|
60894
|
+
deviceTypes: [DeviceType.Sensor],
|
|
60895
|
+
methods: {},
|
|
60896
|
+
status: {
|
|
60897
|
+
schema: GroupStatusSchema,
|
|
60898
|
+
kind: "push"
|
|
60899
|
+
},
|
|
60900
|
+
runtimeState: GroupStatusSchema,
|
|
60901
|
+
/**
|
|
60902
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60903
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60904
|
+
*
|
|
60905
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60906
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60907
|
+
*/
|
|
60908
|
+
durability: "session",
|
|
60909
|
+
history: "none"
|
|
60910
|
+
};
|
|
60534
60911
|
var HeatingValveStatusSchema = object({
|
|
60535
60912
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60536
60913
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -62300,12 +62677,18 @@ var motionCapability = {
|
|
|
62300
62677
|
methods: {
|
|
62301
62678
|
/**
|
|
62302
62679
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
62303
|
-
* for consumers that don't need the full status object
|
|
62304
|
-
*
|
|
62305
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
62306
|
-
* consumer.
|
|
62680
|
+
* for consumers that don't need the full status object. A composed
|
|
62681
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
62307
62682
|
*/
|
|
62308
62683
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62684
|
+
/**
|
|
62685
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62686
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62687
|
+
*/
|
|
62688
|
+
composedMethods: { isDetected: {
|
|
62689
|
+
kind: "slice",
|
|
62690
|
+
field: "detected"
|
|
62691
|
+
} },
|
|
62309
62692
|
events: {
|
|
62310
62693
|
/**
|
|
62311
62694
|
* Fires every time the runner transitions a camera between
|
|
@@ -70556,6 +70939,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70556
70939
|
featureProbe: featureProbeCapability,
|
|
70557
70940
|
flood: floodCapability,
|
|
70558
70941
|
gas: gasCapability,
|
|
70942
|
+
groupStatus: groupStatusCapability,
|
|
70559
70943
|
heatingValve: heatingValveCapability,
|
|
70560
70944
|
humidifier: humidifierCapability,
|
|
70561
70945
|
humiditySensor: humiditySensorCapability,
|
|
@@ -75040,6 +75424,13 @@ Object.freeze({
|
|
|
75040
75424
|
access: "view",
|
|
75041
75425
|
role: "viewer"
|
|
75042
75426
|
},
|
|
75427
|
+
"groupStatus.getStatus": {
|
|
75428
|
+
capName: "group-status",
|
|
75429
|
+
capScope: "device",
|
|
75430
|
+
addonId: null,
|
|
75431
|
+
access: "view",
|
|
75432
|
+
role: "viewer"
|
|
75433
|
+
},
|
|
75043
75434
|
"heatingValve.getStatus": {
|
|
75044
75435
|
capName: "heating-valve",
|
|
75045
75436
|
capScope: "device",
|
|
@@ -84862,6 +85253,33 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84862
85253
|
icon: "flame"
|
|
84863
85254
|
}]
|
|
84864
85255
|
},
|
|
85256
|
+
"group-status": {
|
|
85257
|
+
scope: "device",
|
|
85258
|
+
noun: t("Group", "Gruppo"),
|
|
85259
|
+
state: [
|
|
85260
|
+
{
|
|
85261
|
+
kind: "numeric",
|
|
85262
|
+
field: "included",
|
|
85263
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
85264
|
+
label: t("Reporting", "Rispondono"),
|
|
85265
|
+
icon: "users"
|
|
85266
|
+
},
|
|
85267
|
+
{
|
|
85268
|
+
kind: "numeric",
|
|
85269
|
+
field: "excluded",
|
|
85270
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
85271
|
+
label: t("Excluded", "Esclusi"),
|
|
85272
|
+
icon: "users"
|
|
85273
|
+
},
|
|
85274
|
+
{
|
|
85275
|
+
kind: "numeric",
|
|
85276
|
+
field: "total",
|
|
85277
|
+
quantity: t("the member count", "il numero di membri"),
|
|
85278
|
+
label: t("Members", "Membri"),
|
|
85279
|
+
icon: "sigma"
|
|
85280
|
+
}
|
|
85281
|
+
]
|
|
85282
|
+
},
|
|
84865
85283
|
"humidity-sensor": {
|
|
84866
85284
|
scope: "device",
|
|
84867
85285
|
noun: t("Humidity", "Umidità"),
|
|
@@ -86327,6 +86745,11 @@ Object.freeze({
|
|
|
86327
86745
|
form: "single",
|
|
86328
86746
|
optional: false
|
|
86329
86747
|
}],
|
|
86748
|
+
"groupStatus.getStatus": [{
|
|
86749
|
+
name: "deviceId",
|
|
86750
|
+
form: "single",
|
|
86751
|
+
optional: false
|
|
86752
|
+
}],
|
|
86330
86753
|
"heatingValve.getStatus": [{
|
|
86331
86754
|
name: "deviceId",
|
|
86332
86755
|
form: "single",
|
|
@@ -5567,7 +5567,7 @@ var ZodIssueCode = {
|
|
|
5567
5567
|
var ZodFirstPartyTypeKind;
|
|
5568
5568
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5569
5569
|
//#endregion
|
|
5570
|
-
//#region ../types/dist/sleep-
|
|
5570
|
+
//#region ../types/dist/sleep-B81gwQuR.mjs
|
|
5571
5571
|
/**
|
|
5572
5572
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5573
5573
|
* window to float samples (D455).
|
|
@@ -9010,6 +9010,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9010
9010
|
"filesystem-browse",
|
|
9011
9011
|
"flood",
|
|
9012
9012
|
"gas",
|
|
9013
|
+
"group-status",
|
|
9013
9014
|
"heating-valve",
|
|
9014
9015
|
"humidifier",
|
|
9015
9016
|
"humidity-sensor",
|
|
@@ -9828,6 +9829,20 @@ Object.freeze({
|
|
|
9828
9829
|
"path": "detected",
|
|
9829
9830
|
"valueType": "boolean"
|
|
9830
9831
|
}],
|
|
9832
|
+
"group-status": [
|
|
9833
|
+
{
|
|
9834
|
+
"path": "included",
|
|
9835
|
+
"valueType": "number"
|
|
9836
|
+
},
|
|
9837
|
+
{
|
|
9838
|
+
"path": "excluded",
|
|
9839
|
+
"valueType": "number"
|
|
9840
|
+
},
|
|
9841
|
+
{
|
|
9842
|
+
"path": "total",
|
|
9843
|
+
"valueType": "number"
|
|
9844
|
+
}
|
|
9845
|
+
],
|
|
9831
9846
|
"heating-valve": [{
|
|
9832
9847
|
"path": "position",
|
|
9833
9848
|
"valueType": "number"
|
|
@@ -11169,7 +11184,7 @@ function errMsg(err) {
|
|
|
11169
11184
|
return String(err);
|
|
11170
11185
|
}
|
|
11171
11186
|
//#endregion
|
|
11172
|
-
//#region ../types/dist/composition-
|
|
11187
|
+
//#region ../types/dist/composition-B85l9j1M.mjs
|
|
11173
11188
|
/**
|
|
11174
11189
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11175
11190
|
*
|
|
@@ -11924,15 +11939,67 @@ function validateExpressionSource(src) {
|
|
|
11924
11939
|
}
|
|
11925
11940
|
return null;
|
|
11926
11941
|
}
|
|
11927
|
-
/**
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11942
|
+
/**
|
|
11943
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11944
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11945
|
+
* `composition.ts` (D659).
|
|
11946
|
+
*/
|
|
11931
11947
|
var CompositionSourceRefSchema = object({
|
|
11932
11948
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11933
11949
|
addonId: string().min(1),
|
|
11934
11950
|
stableId: string().min(1)
|
|
11935
11951
|
});
|
|
11952
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11953
|
+
"temperature",
|
|
11954
|
+
"humidity",
|
|
11955
|
+
"pressure",
|
|
11956
|
+
"illuminance",
|
|
11957
|
+
"power",
|
|
11958
|
+
"energy",
|
|
11959
|
+
"battery",
|
|
11960
|
+
"numeric",
|
|
11961
|
+
"motion",
|
|
11962
|
+
"contact",
|
|
11963
|
+
"leak",
|
|
11964
|
+
"smoke",
|
|
11965
|
+
"occupancy",
|
|
11966
|
+
"binary"
|
|
11967
|
+
];
|
|
11968
|
+
var NUMERIC_AGGREGATES = [
|
|
11969
|
+
"mean",
|
|
11970
|
+
"median",
|
|
11971
|
+
"min",
|
|
11972
|
+
"max",
|
|
11973
|
+
"sum"
|
|
11974
|
+
];
|
|
11975
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11976
|
+
var AGGREGATE_REDUCERS = [
|
|
11977
|
+
"mean",
|
|
11978
|
+
"median",
|
|
11979
|
+
"min",
|
|
11980
|
+
"max",
|
|
11981
|
+
"sum",
|
|
11982
|
+
"any",
|
|
11983
|
+
"all"
|
|
11984
|
+
];
|
|
11985
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11986
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11987
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11988
|
+
var HelperMemberSchema = object({
|
|
11989
|
+
source: CompositionSourceRefSchema,
|
|
11990
|
+
cap: string().min(1),
|
|
11991
|
+
fieldPath: string().min(1)
|
|
11992
|
+
});
|
|
11993
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11994
|
+
kind: literal("group"),
|
|
11995
|
+
templateId: GroupTemplateIdSchema,
|
|
11996
|
+
aggregate: AggregateReducerSchema,
|
|
11997
|
+
members: array(HelperMemberSchema).min(1).max(64)
|
|
11998
|
+
})]);
|
|
11999
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
12000
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
12001
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
12002
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11936
12003
|
/** One field of one capability of one source device. */
|
|
11937
12004
|
var CompositionFieldReadSchema = object({
|
|
11938
12005
|
source: CompositionSourceRefSchema,
|
|
@@ -11976,7 +12043,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11976
12043
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11977
12044
|
CompositionFromSourceSchema,
|
|
11978
12045
|
CompositionExpressionSourceSchema,
|
|
11979
|
-
CompositionCodeSourceSchema
|
|
12046
|
+
CompositionCodeSourceSchema,
|
|
12047
|
+
object({
|
|
12048
|
+
kind: literal("aggregate"),
|
|
12049
|
+
reducer: _enum([
|
|
12050
|
+
"mean",
|
|
12051
|
+
"median",
|
|
12052
|
+
"min",
|
|
12053
|
+
"max",
|
|
12054
|
+
"sum",
|
|
12055
|
+
"any",
|
|
12056
|
+
"all"
|
|
12057
|
+
]),
|
|
12058
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12059
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12060
|
+
publish: _enum([
|
|
12061
|
+
"value",
|
|
12062
|
+
"included",
|
|
12063
|
+
"excluded",
|
|
12064
|
+
"total"
|
|
12065
|
+
]),
|
|
12066
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12067
|
+
empty: _enum([
|
|
12068
|
+
"null",
|
|
12069
|
+
"omit",
|
|
12070
|
+
"offline"
|
|
12071
|
+
])
|
|
12072
|
+
})
|
|
11980
12073
|
]);
|
|
11981
12074
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11982
12075
|
kind: literal("forward"),
|
|
@@ -12022,7 +12115,13 @@ var CompositionSchema = object({
|
|
|
12022
12115
|
kind: literal("existing"),
|
|
12023
12116
|
device: CompositionSourceRefSchema
|
|
12024
12117
|
})]),
|
|
12025
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12118
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12119
|
+
/**
|
|
12120
|
+
* Present when the block is a helper template. Absent on a free
|
|
12121
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12122
|
+
* never the compiled features.
|
|
12123
|
+
*/
|
|
12124
|
+
helper: HelperSpecSchema.optional()
|
|
12026
12125
|
}).superRefine((composition, ctx) => {
|
|
12027
12126
|
const seen = /* @__PURE__ */ new Set();
|
|
12028
12127
|
composition.features.forEach((feature, index) => {
|
|
@@ -18443,7 +18542,10 @@ var CompositionProblemSchema = object({
|
|
|
18443
18542
|
"target-missing",
|
|
18444
18543
|
"target-unreadable",
|
|
18445
18544
|
"not-replaceable",
|
|
18446
|
-
"native-capability-replace"
|
|
18545
|
+
"native-capability-replace",
|
|
18546
|
+
"mixed-quantity",
|
|
18547
|
+
"helper-mismatch",
|
|
18548
|
+
"member-constraint"
|
|
18447
18549
|
]),
|
|
18448
18550
|
path: string(),
|
|
18449
18551
|
message: string()
|
|
@@ -18464,7 +18566,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18464
18566
|
"null",
|
|
18465
18567
|
"offline",
|
|
18466
18568
|
"unknown",
|
|
18467
|
-
"release"
|
|
18569
|
+
"release",
|
|
18570
|
+
"omit"
|
|
18468
18571
|
]);
|
|
18469
18572
|
/**
|
|
18470
18573
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18678,6 +18781,235 @@ Object.freeze({
|
|
|
18678
18781
|
result: ["number", "null"]
|
|
18679
18782
|
}
|
|
18680
18783
|
});
|
|
18784
|
+
/**
|
|
18785
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18786
|
+
* Data, not a form default written into the block.
|
|
18787
|
+
*/
|
|
18788
|
+
var NOW = {
|
|
18789
|
+
fieldPath: "lastFetchedAt",
|
|
18790
|
+
expr: "now"
|
|
18791
|
+
};
|
|
18792
|
+
var CHANGED = {
|
|
18793
|
+
fieldPath: "lastChangedAt",
|
|
18794
|
+
expr: "now"
|
|
18795
|
+
};
|
|
18796
|
+
function numeric(input) {
|
|
18797
|
+
return {
|
|
18798
|
+
...input,
|
|
18799
|
+
family: "numeric",
|
|
18800
|
+
deviceType: DeviceType.Sensor,
|
|
18801
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18802
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18803
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18804
|
+
accept: [{
|
|
18805
|
+
cap: input.outputCap,
|
|
18806
|
+
fieldPath: input.outputField
|
|
18807
|
+
}]
|
|
18808
|
+
};
|
|
18809
|
+
}
|
|
18810
|
+
function binary(input) {
|
|
18811
|
+
return {
|
|
18812
|
+
...input,
|
|
18813
|
+
family: "binary",
|
|
18814
|
+
deviceType: DeviceType.Sensor,
|
|
18815
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18816
|
+
quantity: "none",
|
|
18817
|
+
baseUnit: void 0,
|
|
18818
|
+
aggregates: BINARY_AGGREGATES,
|
|
18819
|
+
empty: "offline"
|
|
18820
|
+
};
|
|
18821
|
+
}
|
|
18822
|
+
var GROUP_TEMPLATES = [
|
|
18823
|
+
numeric({
|
|
18824
|
+
id: "temperature",
|
|
18825
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18826
|
+
role: DeviceRole.TemperatureSensor,
|
|
18827
|
+
outputCap: "temperature-sensor",
|
|
18828
|
+
outputField: "celsius",
|
|
18829
|
+
quantity: "temperature",
|
|
18830
|
+
defaultAggregate: "mean",
|
|
18831
|
+
empty: "null",
|
|
18832
|
+
companions: [NOW]
|
|
18833
|
+
}),
|
|
18834
|
+
numeric({
|
|
18835
|
+
id: "humidity",
|
|
18836
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18837
|
+
role: DeviceRole.HumiditySensor,
|
|
18838
|
+
outputCap: "humidity-sensor",
|
|
18839
|
+
outputField: "percent",
|
|
18840
|
+
quantity: "humidity",
|
|
18841
|
+
defaultAggregate: "mean",
|
|
18842
|
+
empty: "null",
|
|
18843
|
+
companions: [NOW]
|
|
18844
|
+
}),
|
|
18845
|
+
numeric({
|
|
18846
|
+
id: "pressure",
|
|
18847
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18848
|
+
role: DeviceRole.PressureSensor,
|
|
18849
|
+
outputCap: "pressure-sensor",
|
|
18850
|
+
outputField: "hpa",
|
|
18851
|
+
quantity: "pressure",
|
|
18852
|
+
defaultAggregate: "mean",
|
|
18853
|
+
empty: "null",
|
|
18854
|
+
companions: [NOW]
|
|
18855
|
+
}),
|
|
18856
|
+
numeric({
|
|
18857
|
+
id: "illuminance",
|
|
18858
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18859
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18860
|
+
outputCap: "ambient-light-sensor",
|
|
18861
|
+
outputField: "lux",
|
|
18862
|
+
quantity: "illuminance",
|
|
18863
|
+
defaultAggregate: "mean",
|
|
18864
|
+
empty: "null",
|
|
18865
|
+
companions: [NOW]
|
|
18866
|
+
}),
|
|
18867
|
+
numeric({
|
|
18868
|
+
id: "power",
|
|
18869
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18870
|
+
role: DeviceRole.PowerSensor,
|
|
18871
|
+
outputCap: "power-meter",
|
|
18872
|
+
outputField: "watts",
|
|
18873
|
+
quantity: "power",
|
|
18874
|
+
defaultAggregate: "sum",
|
|
18875
|
+
empty: "omit",
|
|
18876
|
+
companions: [NOW]
|
|
18877
|
+
}),
|
|
18878
|
+
numeric({
|
|
18879
|
+
id: "energy",
|
|
18880
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18881
|
+
role: DeviceRole.EnergySensor,
|
|
18882
|
+
outputCap: "power-meter",
|
|
18883
|
+
outputField: "kwhTotal",
|
|
18884
|
+
quantity: "energy",
|
|
18885
|
+
defaultAggregate: "sum",
|
|
18886
|
+
empty: "omit",
|
|
18887
|
+
companions: [NOW]
|
|
18888
|
+
}),
|
|
18889
|
+
numeric({
|
|
18890
|
+
id: "battery",
|
|
18891
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18892
|
+
role: DeviceRole.BatterySensor,
|
|
18893
|
+
outputCap: "battery",
|
|
18894
|
+
outputField: "percentage",
|
|
18895
|
+
quantity: "percentage",
|
|
18896
|
+
defaultAggregate: "mean",
|
|
18897
|
+
empty: "null",
|
|
18898
|
+
companions: [
|
|
18899
|
+
{
|
|
18900
|
+
fieldPath: "charging",
|
|
18901
|
+
expr: "\"unknown\""
|
|
18902
|
+
},
|
|
18903
|
+
{
|
|
18904
|
+
fieldPath: "sleeping",
|
|
18905
|
+
expr: "false"
|
|
18906
|
+
},
|
|
18907
|
+
{
|
|
18908
|
+
fieldPath: "lastUpdated",
|
|
18909
|
+
expr: "now"
|
|
18910
|
+
}
|
|
18911
|
+
]
|
|
18912
|
+
}),
|
|
18913
|
+
numeric({
|
|
18914
|
+
id: "numeric",
|
|
18915
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18916
|
+
role: DeviceRole.NumericSensor,
|
|
18917
|
+
outputCap: "numeric-sensor",
|
|
18918
|
+
outputField: "value",
|
|
18919
|
+
quantity: "device",
|
|
18920
|
+
defaultAggregate: "mean",
|
|
18921
|
+
empty: "null",
|
|
18922
|
+
companions: [NOW]
|
|
18923
|
+
}),
|
|
18924
|
+
binary({
|
|
18925
|
+
id: "motion",
|
|
18926
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18927
|
+
role: DeviceRole.MotionSensor,
|
|
18928
|
+
outputCap: "motion",
|
|
18929
|
+
outputField: "detected",
|
|
18930
|
+
defaultAggregate: "any",
|
|
18931
|
+
accept: [{
|
|
18932
|
+
cap: "motion",
|
|
18933
|
+
fieldPath: "detected"
|
|
18934
|
+
}],
|
|
18935
|
+
companions: [{
|
|
18936
|
+
fieldPath: "lastDetectedAt",
|
|
18937
|
+
expr: "null"
|
|
18938
|
+
}, {
|
|
18939
|
+
fieldPath: "autoClearAfterMs",
|
|
18940
|
+
expr: "null"
|
|
18941
|
+
}]
|
|
18942
|
+
}),
|
|
18943
|
+
binary({
|
|
18944
|
+
id: "contact",
|
|
18945
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18946
|
+
role: DeviceRole.ContactSensor,
|
|
18947
|
+
outputCap: "contact",
|
|
18948
|
+
outputField: "entryOpen",
|
|
18949
|
+
defaultAggregate: "any",
|
|
18950
|
+
accept: [{
|
|
18951
|
+
cap: "contact",
|
|
18952
|
+
fieldPath: "entryOpen"
|
|
18953
|
+
}],
|
|
18954
|
+
companions: [CHANGED]
|
|
18955
|
+
}),
|
|
18956
|
+
binary({
|
|
18957
|
+
id: "leak",
|
|
18958
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18959
|
+
role: DeviceRole.LeakSensor,
|
|
18960
|
+
outputCap: "flood",
|
|
18961
|
+
outputField: "flooded",
|
|
18962
|
+
defaultAggregate: "any",
|
|
18963
|
+
accept: [{
|
|
18964
|
+
cap: "flood",
|
|
18965
|
+
fieldPath: "flooded"
|
|
18966
|
+
}],
|
|
18967
|
+
companions: [CHANGED]
|
|
18968
|
+
}),
|
|
18969
|
+
binary({
|
|
18970
|
+
id: "smoke",
|
|
18971
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18972
|
+
role: DeviceRole.SmokeSensor,
|
|
18973
|
+
outputCap: "smoke",
|
|
18974
|
+
outputField: "detected",
|
|
18975
|
+
defaultAggregate: "any",
|
|
18976
|
+
accept: [{
|
|
18977
|
+
cap: "smoke",
|
|
18978
|
+
fieldPath: "detected"
|
|
18979
|
+
}],
|
|
18980
|
+
companions: [CHANGED]
|
|
18981
|
+
}),
|
|
18982
|
+
binary({
|
|
18983
|
+
id: "occupancy",
|
|
18984
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18985
|
+
role: DeviceRole.BinarySensor,
|
|
18986
|
+
outputCap: "binary",
|
|
18987
|
+
outputField: "on",
|
|
18988
|
+
defaultAggregate: "any",
|
|
18989
|
+
accept: [{
|
|
18990
|
+
cap: "motion",
|
|
18991
|
+
fieldPath: "detected"
|
|
18992
|
+
}, {
|
|
18993
|
+
cap: "binary",
|
|
18994
|
+
fieldPath: "on"
|
|
18995
|
+
}],
|
|
18996
|
+
companions: [CHANGED]
|
|
18997
|
+
}),
|
|
18998
|
+
binary({
|
|
18999
|
+
id: "binary",
|
|
19000
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
19001
|
+
role: DeviceRole.BinarySensor,
|
|
19002
|
+
outputCap: "binary",
|
|
19003
|
+
outputField: "on",
|
|
19004
|
+
defaultAggregate: "any",
|
|
19005
|
+
accept: [{
|
|
19006
|
+
cap: "binary",
|
|
19007
|
+
fieldPath: "on"
|
|
19008
|
+
}],
|
|
19009
|
+
companions: [CHANGED]
|
|
19010
|
+
})
|
|
19011
|
+
];
|
|
19012
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18681
19013
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18682
19014
|
/**
|
|
18683
19015
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -60532,6 +60864,51 @@ var gasCapability = {
|
|
|
60532
60864
|
* whether persisting is worth a SQLite commit. */
|
|
60533
60865
|
volatileStateFields: ["lastChangedAt"]
|
|
60534
60866
|
};
|
|
60867
|
+
/**
|
|
60868
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60869
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60870
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60871
|
+
* series that later statistics read is the output cap's own history block.
|
|
60872
|
+
*/
|
|
60873
|
+
var GroupStatusSchema = object({
|
|
60874
|
+
/** Members whose current value entered the aggregate. */
|
|
60875
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60876
|
+
precision: 0,
|
|
60877
|
+
label: "Reporting"
|
|
60878
|
+
})),
|
|
60879
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60880
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60881
|
+
precision: 0,
|
|
60882
|
+
label: "Excluded"
|
|
60883
|
+
})),
|
|
60884
|
+
/** `included` + `excluded`. */
|
|
60885
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60886
|
+
precision: 0,
|
|
60887
|
+
label: "Members"
|
|
60888
|
+
}))
|
|
60889
|
+
});
|
|
60890
|
+
var groupStatusCapability = {
|
|
60891
|
+
name: "group-status",
|
|
60892
|
+
scope: "device",
|
|
60893
|
+
deviceNative: true,
|
|
60894
|
+
mode: "singleton",
|
|
60895
|
+
deviceTypes: [DeviceType.Sensor],
|
|
60896
|
+
methods: {},
|
|
60897
|
+
status: {
|
|
60898
|
+
schema: GroupStatusSchema,
|
|
60899
|
+
kind: "push"
|
|
60900
|
+
},
|
|
60901
|
+
runtimeState: GroupStatusSchema,
|
|
60902
|
+
/**
|
|
60903
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60904
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60905
|
+
*
|
|
60906
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60907
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60908
|
+
*/
|
|
60909
|
+
durability: "session",
|
|
60910
|
+
history: "none"
|
|
60911
|
+
};
|
|
60535
60912
|
var HeatingValveStatusSchema = object({
|
|
60536
60913
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60537
60914
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -62301,12 +62678,18 @@ var motionCapability = {
|
|
|
62301
62678
|
methods: {
|
|
62302
62679
|
/**
|
|
62303
62680
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
62304
|
-
* for consumers that don't need the full status object
|
|
62305
|
-
*
|
|
62306
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
62307
|
-
* consumer.
|
|
62681
|
+
* for consumers that don't need the full status object. A composed
|
|
62682
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
62308
62683
|
*/
|
|
62309
62684
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62685
|
+
/**
|
|
62686
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62687
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62688
|
+
*/
|
|
62689
|
+
composedMethods: { isDetected: {
|
|
62690
|
+
kind: "slice",
|
|
62691
|
+
field: "detected"
|
|
62692
|
+
} },
|
|
62310
62693
|
events: {
|
|
62311
62694
|
/**
|
|
62312
62695
|
* Fires every time the runner transitions a camera between
|
|
@@ -70557,6 +70940,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70557
70940
|
featureProbe: featureProbeCapability,
|
|
70558
70941
|
flood: floodCapability,
|
|
70559
70942
|
gas: gasCapability,
|
|
70943
|
+
groupStatus: groupStatusCapability,
|
|
70560
70944
|
heatingValve: heatingValveCapability,
|
|
70561
70945
|
humidifier: humidifierCapability,
|
|
70562
70946
|
humiditySensor: humiditySensorCapability,
|
|
@@ -75041,6 +75425,13 @@ Object.freeze({
|
|
|
75041
75425
|
access: "view",
|
|
75042
75426
|
role: "viewer"
|
|
75043
75427
|
},
|
|
75428
|
+
"groupStatus.getStatus": {
|
|
75429
|
+
capName: "group-status",
|
|
75430
|
+
capScope: "device",
|
|
75431
|
+
addonId: null,
|
|
75432
|
+
access: "view",
|
|
75433
|
+
role: "viewer"
|
|
75434
|
+
},
|
|
75044
75435
|
"heatingValve.getStatus": {
|
|
75045
75436
|
capName: "heating-valve",
|
|
75046
75437
|
capScope: "device",
|
|
@@ -84863,6 +85254,33 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84863
85254
|
icon: "flame"
|
|
84864
85255
|
}]
|
|
84865
85256
|
},
|
|
85257
|
+
"group-status": {
|
|
85258
|
+
scope: "device",
|
|
85259
|
+
noun: t("Group", "Gruppo"),
|
|
85260
|
+
state: [
|
|
85261
|
+
{
|
|
85262
|
+
kind: "numeric",
|
|
85263
|
+
field: "included",
|
|
85264
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
85265
|
+
label: t("Reporting", "Rispondono"),
|
|
85266
|
+
icon: "users"
|
|
85267
|
+
},
|
|
85268
|
+
{
|
|
85269
|
+
kind: "numeric",
|
|
85270
|
+
field: "excluded",
|
|
85271
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
85272
|
+
label: t("Excluded", "Esclusi"),
|
|
85273
|
+
icon: "users"
|
|
85274
|
+
},
|
|
85275
|
+
{
|
|
85276
|
+
kind: "numeric",
|
|
85277
|
+
field: "total",
|
|
85278
|
+
quantity: t("the member count", "il numero di membri"),
|
|
85279
|
+
label: t("Members", "Membri"),
|
|
85280
|
+
icon: "sigma"
|
|
85281
|
+
}
|
|
85282
|
+
]
|
|
85283
|
+
},
|
|
84866
85284
|
"humidity-sensor": {
|
|
84867
85285
|
scope: "device",
|
|
84868
85286
|
noun: t("Humidity", "Umidità"),
|
|
@@ -86328,6 +86746,11 @@ Object.freeze({
|
|
|
86328
86746
|
form: "single",
|
|
86329
86747
|
optional: false
|
|
86330
86748
|
}],
|
|
86749
|
+
"groupStatus.getStatus": [{
|
|
86750
|
+
name: "deviceId",
|
|
86751
|
+
form: "single",
|
|
86752
|
+
optional: false
|
|
86753
|
+
}],
|
|
86331
86754
|
"heatingValve.getStatus": [{
|
|
86332
86755
|
name: "deviceId",
|
|
86333
86756
|
form: "single",
|
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
enumerable: true
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
//#endregion
|
|
27
|
-
const require_dist = require("../dist-
|
|
27
|
+
const require_dist = require("../dist-CRwUHjY7.js");
|
|
28
28
|
let node_crypto = require("node:crypto");
|
|
29
29
|
require("node:zlib");
|
|
30
30
|
let node_fs = require("node:fs");
|
|
@@ -3488,6 +3488,10 @@ function controlEntitySpecs(slice, quantity) {
|
|
|
3488
3488
|
}, kindExtra];
|
|
3489
3489
|
}
|
|
3490
3490
|
var CAPS_NOT_EXPORTED = [
|
|
3491
|
+
{
|
|
3492
|
+
cap: "group-status",
|
|
3493
|
+
reason: "Bookkeeping for a helper group (D944): how many members were included, excluded, or named. The value an operator automates on is the output capability (the temperature, the motion, the watts). These counts are session-only, have no history, and would publish a second entity that never means the reading."
|
|
3494
|
+
},
|
|
3491
3495
|
{
|
|
3492
3496
|
cap: "recording-onboard",
|
|
3493
3497
|
reason: "An EDITOR of the CAMERA’s own recorder: a weekly schedule of windows per trigger, plus the facts about the card it writes to. The schedule is a document an operator authors, not a reading — an entity would publish 168 slots as a state and nothing in Home Assistant could act on it. The storage side is a reading, but it belongs to the camera’s own health rather than to this cap’s editor surface, and publishing capacity here would put the same number in two places the day a health cap carries it. ONE thing here is arguably a real binary sensor: `recordingToNowhere` — scheduled to record with no usable card. It is deliberately NOT exported yet, because exporting half a cap needs the split decided first, and the two cameras it fires on today are already a danger banner and a WARN."
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $t as unknown, D as buildAddonRouteProvider, F as consumableFormOf, H as deviceExportCapability, Ht as nodePin, I as consumableKindOf, It as baseUnitOf, Pt as BaseAddon, Vt as isReadingQuantity, Wt as array, Yt as object, Zt as string, _ as addonRoutesCapability, a as COCO_TO_MACRO, c as ConsumableItemSchema, d as FanDirectionSchema, f as HvacModeSchema, i as CAMERA_SWITCH_ORDER, l as ConsumableStatusSchema, o as CameraSwitchIdSchema, ot as oauthIntegrationCapability, p as MediaPlayerRepeatSchema, s as ConsumableFormSchema, t as AlarmArmModeSchema, tn as EventCategory } from "../dist-
|
|
1
|
+
import { $t as unknown, D as buildAddonRouteProvider, F as consumableFormOf, H as deviceExportCapability, Ht as nodePin, I as consumableKindOf, It as baseUnitOf, Pt as BaseAddon, Vt as isReadingQuantity, Wt as array, Yt as object, Zt as string, _ as addonRoutesCapability, a as COCO_TO_MACRO, c as ConsumableItemSchema, d as FanDirectionSchema, f as HvacModeSchema, i as CAMERA_SWITCH_ORDER, l as ConsumableStatusSchema, o as CameraSwitchIdSchema, ot as oauthIntegrationCapability, p as MediaPlayerRepeatSchema, s as ConsumableFormSchema, t as AlarmArmModeSchema, tn as EventCategory } from "../dist-BFnk4bwH.mjs";
|
|
2
2
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
3
3
|
import "node:zlib";
|
|
4
4
|
import "node:fs";
|
|
@@ -3453,6 +3453,10 @@ function controlEntitySpecs(slice, quantity) {
|
|
|
3453
3453
|
}, kindExtra];
|
|
3454
3454
|
}
|
|
3455
3455
|
var CAPS_NOT_EXPORTED = [
|
|
3456
|
+
{
|
|
3457
|
+
cap: "group-status",
|
|
3458
|
+
reason: "Bookkeeping for a helper group (D944): how many members were included, excluded, or named. The value an operator automates on is the output capability (the temperature, the motion, the watts). These counts are session-only, have no history, and would publish a second entity that never means the reading."
|
|
3459
|
+
},
|
|
3456
3460
|
{
|
|
3457
3461
|
cap: "recording-onboard",
|
|
3458
3462
|
reason: "An EDITOR of the CAMERA’s own recorder: a weekly schedule of windows per trigger, plus the facts about the card it writes to. The schedule is a document an operator authors, not a reading — an entity would publish 168 slots as a state and nothing in Home Assistant could act on it. The storage side is a reading, but it belongs to the camera’s own health rather than to this cap’s editor surface, and publishing capacity here would put the same number in two places the day a health cap carries it. ONE thing here is arguably a real binary sensor: `recordingToNowhere` — scheduled to record with no usable card. It is deliberately NOT exported yet, because exporting half a cap needs the split decided first, and the two cameras it fires on today are already a danger banner and a WARN."
|