@camstack/addon-provider-homeassistant 1.2.626 → 1.2.628

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.
@@ -1,4 +1,4 @@
1
- //#region ../types/dist/event-category-DHXxB8t9.mjs
1
+ //#region ../types/dist/event-category-CT-hz5Rb.mjs
2
2
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
3
3
  EventCategory["SystemBoot"] = "system.boot";
4
4
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -324,6 +324,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
324
324
  /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
325
325
  EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
326
326
  /**
327
+ * A camera's package LLM confirm has failed closed three times in a row
328
+ * (D931, 2026-10-26). One edge per camera until
329
+ * {@link PipelinePackageLlmAnswered}.
330
+ */
331
+ EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
332
+ /** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
333
+ EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
334
+ /**
327
335
  * Per-camera pipeline config was mutated by the orchestrator
328
336
  * (a settings change via `setAgentInferenceDevices` /
329
337
  * `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
@@ -5566,7 +5574,7 @@ var ZodIssueCode = {
5566
5574
  var ZodFirstPartyTypeKind;
5567
5575
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5568
5576
  //#endregion
5569
- //#region ../types/dist/sleep-CARd6wZF.mjs
5577
+ //#region ../types/dist/sleep-bykKrTgu.mjs
5570
5578
  /**
5571
5579
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5572
5580
  * window to float samples (D455).
@@ -9009,6 +9017,8 @@ var CAP_NAMES = Object.freeze([
9009
9017
  "filesystem-browse",
9010
9018
  "flood",
9011
9019
  "gas",
9020
+ "group-commands",
9021
+ "group-status",
9012
9022
  "heating-valve",
9013
9023
  "humidifier",
9014
9024
  "humidity-sensor",
@@ -9827,6 +9837,20 @@ Object.freeze({
9827
9837
  "path": "detected",
9828
9838
  "valueType": "boolean"
9829
9839
  }],
9840
+ "group-status": [
9841
+ {
9842
+ "path": "included",
9843
+ "valueType": "number"
9844
+ },
9845
+ {
9846
+ "path": "excluded",
9847
+ "valueType": "number"
9848
+ },
9849
+ {
9850
+ "path": "total",
9851
+ "valueType": "number"
9852
+ }
9853
+ ],
9830
9854
  "heating-valve": [{
9831
9855
  "path": "position",
9832
9856
  "valueType": "number"
@@ -11168,7 +11192,7 @@ function errMsg(err) {
11168
11192
  return String(err);
11169
11193
  }
11170
11194
  //#endregion
11171
- //#region ../types/dist/composition-kEl9mevu.mjs
11195
+ //#region ../types/dist/composition-OhpuespA.mjs
11172
11196
  /**
11173
11197
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11174
11198
  *
@@ -11923,15 +11947,74 @@ function validateExpressionSource(src) {
11923
11947
  }
11924
11948
  return null;
11925
11949
  }
11926
- /** A composed device's stableId is this prefix plus the block id. */
11927
- var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
11928
- /** Longest snippet a `code` source may carry (slice 4). */
11929
- var MAX_COMPOSITION_CODE_LENGTH = 2e4;
11950
+ /**
11951
+ * A composition source identity: `(addonId, stableId)`, never a numeric device
11952
+ * id. Split out so helper schemas can name it without a cycle through
11953
+ * `composition.ts` (D659).
11954
+ */
11930
11955
  var CompositionSourceRefSchema = object({
11931
11956
  /** The owning addon; `stableId` is unique only within it. */
11932
11957
  addonId: string().min(1),
11933
11958
  stableId: string().min(1)
11934
11959
  });
11960
+ var GROUP_TEMPLATE_IDS = [
11961
+ "temperature",
11962
+ "humidity",
11963
+ "pressure",
11964
+ "illuminance",
11965
+ "power",
11966
+ "energy",
11967
+ "battery",
11968
+ "numeric",
11969
+ "motion",
11970
+ "contact",
11971
+ "leak",
11972
+ "smoke",
11973
+ "occupancy",
11974
+ "binary",
11975
+ "switch",
11976
+ "light"
11977
+ ];
11978
+ var NUMERIC_AGGREGATES = [
11979
+ "mean",
11980
+ "median",
11981
+ "min",
11982
+ "max",
11983
+ "sum"
11984
+ ];
11985
+ var BINARY_AGGREGATES = ["any", "all"];
11986
+ /** How an actuator group decides it is on. Unknown members never count as off. */
11987
+ var ACTIVE_CRITERIA = ["at-least-one", "all"];
11988
+ var AGGREGATE_REDUCERS = [
11989
+ "mean",
11990
+ "median",
11991
+ "min",
11992
+ "max",
11993
+ "sum",
11994
+ "any",
11995
+ "all"
11996
+ ];
11997
+ var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
11998
+ var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
11999
+ var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
12000
+ /** One member. The field is stored so occupancy can name motion or binary. */
12001
+ var HelperMemberSchema = object({
12002
+ source: CompositionSourceRefSchema,
12003
+ cap: string().min(1),
12004
+ fieldPath: string().min(1)
12005
+ });
12006
+ var HelperSpecSchema = discriminatedUnion("kind", [object({
12007
+ kind: literal("group"),
12008
+ templateId: GroupTemplateIdSchema,
12009
+ aggregate: AggregateReducerSchema,
12010
+ members: array(HelperMemberSchema).min(1).max(64),
12011
+ /** Actuator groups only. Readings leave this unset. */
12012
+ active: ActiveCriterionSchema.optional()
12013
+ })]);
12014
+ /** A composed device's stableId is this prefix plus the block id. */
12015
+ var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
12016
+ /** Longest snippet a `code` source may carry (slice 4). */
12017
+ var MAX_COMPOSITION_CODE_LENGTH = 2e4;
11935
12018
  /** One field of one capability of one source device. */
11936
12019
  var CompositionFieldReadSchema = object({
11937
12020
  source: CompositionSourceRefSchema,
@@ -11975,7 +12058,33 @@ var CompositionCodeSourceSchema = object({
11975
12058
  var CompositionFieldSourceSchema = discriminatedUnion("kind", [
11976
12059
  CompositionFromSourceSchema,
11977
12060
  CompositionExpressionSourceSchema,
11978
- CompositionCodeSourceSchema
12061
+ CompositionCodeSourceSchema,
12062
+ object({
12063
+ kind: literal("aggregate"),
12064
+ reducer: _enum([
12065
+ "mean",
12066
+ "median",
12067
+ "min",
12068
+ "max",
12069
+ "sum",
12070
+ "any",
12071
+ "all"
12072
+ ]),
12073
+ reads: array(CompositionFieldReadSchema).min(1).max(64),
12074
+ /** `value` is the reading; the others are the member counts. */
12075
+ publish: _enum([
12076
+ "value",
12077
+ "included",
12078
+ "excluded",
12079
+ "total"
12080
+ ]),
12081
+ /** What a `value` publish does when nobody is included. Counts ignore this. */
12082
+ empty: _enum([
12083
+ "null",
12084
+ "omit",
12085
+ "offline"
12086
+ ])
12087
+ })
11979
12088
  ]);
11980
12089
  var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
11981
12090
  kind: literal("forward"),
@@ -12021,7 +12130,13 @@ var CompositionSchema = object({
12021
12130
  kind: literal("existing"),
12022
12131
  device: CompositionSourceRefSchema
12023
12132
  })]),
12024
- features: array(CompositionFeatureSchema).min(1).max(16)
12133
+ features: array(CompositionFeatureSchema).min(1).max(16),
12134
+ /**
12135
+ * Present when the block is a helper template. Absent on a free
12136
+ * composition (the room example, device 4603). The editor reads this,
12137
+ * never the compiled features.
12138
+ */
12139
+ helper: HelperSpecSchema.optional()
12025
12140
  }).superRefine((composition, ctx) => {
12026
12141
  const seen = /* @__PURE__ */ new Set();
12027
12142
  composition.features.forEach((feature, index) => {
@@ -18442,7 +18557,10 @@ var CompositionProblemSchema = object({
18442
18557
  "target-missing",
18443
18558
  "target-unreadable",
18444
18559
  "not-replaceable",
18445
- "native-capability-replace"
18560
+ "native-capability-replace",
18561
+ "mixed-quantity",
18562
+ "helper-mismatch",
18563
+ "member-constraint"
18446
18564
  ]),
18447
18565
  path: string(),
18448
18566
  message: string()
@@ -18463,7 +18581,8 @@ var CompositionUnavailableModeSchema = _enum([
18463
18581
  "null",
18464
18582
  "offline",
18465
18583
  "unknown",
18466
- "release"
18584
+ "release",
18585
+ "omit"
18467
18586
  ]);
18468
18587
  /**
18469
18588
  * `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
@@ -18677,6 +18796,275 @@ Object.freeze({
18677
18796
  result: ["number", "null"]
18678
18797
  }
18679
18798
  });
18799
+ /**
18800
+ * One catalog row per base reading a group helper can build (D944 §3).
18801
+ * Data, not a form default written into the block.
18802
+ */
18803
+ var NOW = {
18804
+ fieldPath: "lastFetchedAt",
18805
+ expr: "now"
18806
+ };
18807
+ var CHANGED = {
18808
+ fieldPath: "lastChangedAt",
18809
+ expr: "now"
18810
+ };
18811
+ function numeric(input) {
18812
+ return {
18813
+ ...input,
18814
+ family: "numeric",
18815
+ deviceType: DeviceType.Sensor,
18816
+ memberDeviceType: DeviceType.Sensor,
18817
+ commandCaps: [],
18818
+ baseUnit: baseUnitOf(input.quantity),
18819
+ aggregates: NUMERIC_AGGREGATES,
18820
+ accept: [{
18821
+ cap: input.outputCap,
18822
+ fieldPath: input.outputField
18823
+ }]
18824
+ };
18825
+ }
18826
+ function binary(input) {
18827
+ return {
18828
+ ...input,
18829
+ family: "binary",
18830
+ deviceType: DeviceType.Sensor,
18831
+ memberDeviceType: DeviceType.Sensor,
18832
+ commandCaps: [],
18833
+ quantity: "none",
18834
+ baseUnit: void 0,
18835
+ aggregates: BINARY_AGGREGATES,
18836
+ empty: "offline"
18837
+ };
18838
+ }
18839
+ var GROUP_TEMPLATES = [
18840
+ numeric({
18841
+ id: "temperature",
18842
+ summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
18843
+ role: DeviceRole.TemperatureSensor,
18844
+ outputCap: "temperature-sensor",
18845
+ outputField: "celsius",
18846
+ quantity: "temperature",
18847
+ defaultAggregate: "mean",
18848
+ empty: "null",
18849
+ companions: [NOW]
18850
+ }),
18851
+ numeric({
18852
+ id: "humidity",
18853
+ summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
18854
+ role: DeviceRole.HumiditySensor,
18855
+ outputCap: "humidity-sensor",
18856
+ outputField: "percent",
18857
+ quantity: "humidity",
18858
+ defaultAggregate: "mean",
18859
+ empty: "null",
18860
+ companions: [NOW]
18861
+ }),
18862
+ numeric({
18863
+ id: "pressure",
18864
+ summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
18865
+ role: DeviceRole.PressureSensor,
18866
+ outputCap: "pressure-sensor",
18867
+ outputField: "hpa",
18868
+ quantity: "pressure",
18869
+ defaultAggregate: "mean",
18870
+ empty: "null",
18871
+ companions: [NOW]
18872
+ }),
18873
+ numeric({
18874
+ id: "illuminance",
18875
+ summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
18876
+ role: DeviceRole.AmbientLightSensor,
18877
+ outputCap: "ambient-light-sensor",
18878
+ outputField: "lux",
18879
+ quantity: "illuminance",
18880
+ defaultAggregate: "mean",
18881
+ empty: "null",
18882
+ companions: [NOW]
18883
+ }),
18884
+ numeric({
18885
+ id: "power",
18886
+ summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
18887
+ role: DeviceRole.PowerSensor,
18888
+ outputCap: "power-meter",
18889
+ outputField: "watts",
18890
+ quantity: "power",
18891
+ defaultAggregate: "sum",
18892
+ empty: "omit",
18893
+ companions: [NOW]
18894
+ }),
18895
+ numeric({
18896
+ id: "energy",
18897
+ summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
18898
+ role: DeviceRole.EnergySensor,
18899
+ outputCap: "power-meter",
18900
+ outputField: "kwhTotal",
18901
+ quantity: "energy",
18902
+ defaultAggregate: "sum",
18903
+ empty: "omit",
18904
+ companions: [NOW]
18905
+ }),
18906
+ numeric({
18907
+ id: "battery",
18908
+ summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
18909
+ role: DeviceRole.BatterySensor,
18910
+ outputCap: "battery",
18911
+ outputField: "percentage",
18912
+ quantity: "percentage",
18913
+ defaultAggregate: "mean",
18914
+ empty: "null",
18915
+ companions: [
18916
+ {
18917
+ fieldPath: "charging",
18918
+ expr: "\"unknown\""
18919
+ },
18920
+ {
18921
+ fieldPath: "sleeping",
18922
+ expr: "false"
18923
+ },
18924
+ {
18925
+ fieldPath: "lastUpdated",
18926
+ expr: "now"
18927
+ }
18928
+ ]
18929
+ }),
18930
+ numeric({
18931
+ id: "numeric",
18932
+ summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
18933
+ role: DeviceRole.NumericSensor,
18934
+ outputCap: "numeric-sensor",
18935
+ outputField: "value",
18936
+ quantity: "device",
18937
+ defaultAggregate: "mean",
18938
+ empty: "null",
18939
+ companions: [NOW]
18940
+ }),
18941
+ binary({
18942
+ id: "motion",
18943
+ summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
18944
+ role: DeviceRole.MotionSensor,
18945
+ outputCap: "motion",
18946
+ outputField: "detected",
18947
+ defaultAggregate: "any",
18948
+ accept: [{
18949
+ cap: "motion",
18950
+ fieldPath: "detected"
18951
+ }],
18952
+ companions: [{
18953
+ fieldPath: "lastDetectedAt",
18954
+ expr: "null"
18955
+ }, {
18956
+ fieldPath: "autoClearAfterMs",
18957
+ expr: "null"
18958
+ }]
18959
+ }),
18960
+ binary({
18961
+ id: "contact",
18962
+ summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
18963
+ role: DeviceRole.ContactSensor,
18964
+ outputCap: "contact",
18965
+ outputField: "entryOpen",
18966
+ defaultAggregate: "any",
18967
+ accept: [{
18968
+ cap: "contact",
18969
+ fieldPath: "entryOpen"
18970
+ }],
18971
+ companions: [CHANGED]
18972
+ }),
18973
+ binary({
18974
+ id: "leak",
18975
+ summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
18976
+ role: DeviceRole.LeakSensor,
18977
+ outputCap: "flood",
18978
+ outputField: "flooded",
18979
+ defaultAggregate: "any",
18980
+ accept: [{
18981
+ cap: "flood",
18982
+ fieldPath: "flooded"
18983
+ }],
18984
+ companions: [CHANGED]
18985
+ }),
18986
+ binary({
18987
+ id: "smoke",
18988
+ summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
18989
+ role: DeviceRole.SmokeSensor,
18990
+ outputCap: "smoke",
18991
+ outputField: "detected",
18992
+ defaultAggregate: "any",
18993
+ accept: [{
18994
+ cap: "smoke",
18995
+ fieldPath: "detected"
18996
+ }],
18997
+ companions: [CHANGED]
18998
+ }),
18999
+ binary({
19000
+ id: "occupancy",
19001
+ summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
19002
+ role: DeviceRole.BinarySensor,
19003
+ outputCap: "binary",
19004
+ outputField: "on",
19005
+ defaultAggregate: "any",
19006
+ accept: [{
19007
+ cap: "motion",
19008
+ fieldPath: "detected"
19009
+ }, {
19010
+ cap: "binary",
19011
+ fieldPath: "on"
19012
+ }],
19013
+ companions: [CHANGED]
19014
+ }),
19015
+ binary({
19016
+ id: "binary",
19017
+ summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
19018
+ role: DeviceRole.BinarySensor,
19019
+ outputCap: "binary",
19020
+ outputField: "on",
19021
+ defaultAggregate: "any",
19022
+ accept: [{
19023
+ cap: "binary",
19024
+ fieldPath: "on"
19025
+ }],
19026
+ companions: [CHANGED]
19027
+ }),
19028
+ actuator({
19029
+ id: "switch",
19030
+ 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.",
19031
+ deviceType: DeviceType.Switch,
19032
+ outputCap: "switch",
19033
+ commandCaps: ["switch"]
19034
+ }),
19035
+ actuator({
19036
+ id: "light",
19037
+ 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.",
19038
+ deviceType: DeviceType.Light,
19039
+ outputCap: "switch",
19040
+ commandCaps: [
19041
+ "switch",
19042
+ "brightness",
19043
+ "color"
19044
+ ]
19045
+ })
19046
+ ];
19047
+ function actuator(input) {
19048
+ return {
19049
+ ...input,
19050
+ family: "actuator",
19051
+ role: void 0,
19052
+ memberDeviceType: input.deviceType,
19053
+ outputField: "on",
19054
+ quantity: "none",
19055
+ baseUnit: void 0,
19056
+ aggregates: BINARY_AGGREGATES,
19057
+ defaultAggregate: "any",
19058
+ empty: "offline",
19059
+ accept: [{
19060
+ cap: "switch",
19061
+ fieldPath: "on"
19062
+ }],
19063
+ companions: [CHANGED]
19064
+ };
19065
+ }
19066
+ new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
19067
+ DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
18680
19068
  `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
18681
19069
  /**
18682
19070
  * What a composition may BUILD on a device type (G2, D676): the caps a new
@@ -45764,6 +46152,8 @@ var NcSystemEventKindSchema = _enum([
45764
46152
  "detection-blind",
45765
46153
  "motion-noisy",
45766
46154
  "motion-calm",
46155
+ "package-llm-silent",
46156
+ "package-llm-answered",
45767
46157
  "recording-stalled",
45768
46158
  "recording-healthy",
45769
46159
  "recording-degraded",
@@ -56943,6 +57333,28 @@ var PackageVersionInfoSchema = object({
56943
57333
  deprecated: string().optional(),
56944
57334
  distTags: array(string()).readonly()
56945
57335
  });
57336
+ /**
57337
+ * One published document. `ok` is markdown from the registry. `missing` means
57338
+ * the registry answered and the file was not there. `error` is a registry or
57339
+ * tarball failure — never an empty string standing in for either.
57340
+ */
57341
+ var PackageDocBodySchema = discriminatedUnion("status", [
57342
+ object({
57343
+ status: literal("ok"),
57344
+ markdown: string()
57345
+ }),
57346
+ object({ status: literal("missing") }),
57347
+ object({
57348
+ status: literal("error"),
57349
+ message: string()
57350
+ })
57351
+ ]);
57352
+ var PackageDocsSchema = object({
57353
+ name: string(),
57354
+ version: string(),
57355
+ readme: PackageDocBodySchema,
57356
+ changelog: PackageDocBodySchema
57357
+ });
56946
57358
  var SearchResultSchema = object({
56947
57359
  name: string(),
56948
57360
  version: string(),
@@ -57161,7 +57573,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
57161
57573
  }), object({ success: literal(true) }), {
57162
57574
  kind: "mutation",
57163
57575
  auth: "admin"
57164
- }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
57576
+ }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
57577
+ name: string().min(1),
57578
+ version: string().min(1).optional()
57579
+ }), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
57165
57580
  kind: "mutation",
57166
57581
  auth: "admin"
57167
57582
  }), method(object({ packageName: string() }), object({ success: literal(true) }), {
@@ -60531,6 +60946,88 @@ var gasCapability = {
60531
60946
  * whether persisting is worth a SQLite commit. */
60532
60947
  volatileStateFields: ["lastChangedAt"]
60533
60948
  };
60949
+ var GroupCommandsSchema = object({
60950
+ /** One row per member that has been commanded. A later command replaces that member's row. */
60951
+ results: array(object({
60952
+ deviceId: number().int().nonnegative(),
60953
+ cap: string().min(1),
60954
+ method: string().min(1),
60955
+ ok: boolean(),
60956
+ error: string().optional(),
60957
+ /** Ms epoch of the attempt. */
60958
+ at: number()
60959
+ })) });
60960
+ var groupCommandsCapability = {
60961
+ name: "group-commands",
60962
+ scope: "device",
60963
+ deviceNative: true,
60964
+ mode: "singleton",
60965
+ deviceTypes: [DeviceType.Switch, DeviceType.Light],
60966
+ methods: {},
60967
+ status: {
60968
+ schema: GroupCommandsSchema,
60969
+ kind: "push"
60970
+ },
60971
+ runtimeState: GroupCommandsSchema,
60972
+ /**
60973
+ * Runtime-state durability: **session** — the last attempt. A restored
60974
+ * failure would outlive the command that caused it.
60975
+ *
60976
+ * See `RuntimeStateDurability`. Enforced by
60977
+ * `scripts/check-runtime-state-durability.ts`.
60978
+ */
60979
+ durability: "session",
60980
+ history: "none"
60981
+ };
60982
+ /**
60983
+ * How many members of a helper group answered (D944). Counts are integers,
60984
+ * not measurements: zero included is a real count, never a stand-in reading.
60985
+ * The reading itself stays on the output capability. History is none — the
60986
+ * series that later statistics read is the output cap's own history block.
60987
+ */
60988
+ var GroupStatusSchema = object({
60989
+ /** Members whose current value entered the aggregate. */
60990
+ included: number().int().nonnegative().meta(readingMeta("count", {
60991
+ precision: 0,
60992
+ label: "Reporting"
60993
+ })),
60994
+ /** Members left out: offline, unknown, or not a finite reading (D393). */
60995
+ excluded: number().int().nonnegative().meta(readingMeta("count", {
60996
+ precision: 0,
60997
+ label: "Excluded"
60998
+ })),
60999
+ /** `included` + `excluded`. */
61000
+ total: number().int().nonnegative().meta(readingMeta("count", {
61001
+ precision: 0,
61002
+ label: "Members"
61003
+ }))
61004
+ });
61005
+ var groupStatusCapability = {
61006
+ name: "group-status",
61007
+ scope: "device",
61008
+ deviceNative: true,
61009
+ mode: "singleton",
61010
+ deviceTypes: [
61011
+ DeviceType.Sensor,
61012
+ DeviceType.Switch,
61013
+ DeviceType.Light
61014
+ ],
61015
+ methods: {},
61016
+ status: {
61017
+ schema: GroupStatusSchema,
61018
+ kind: "push"
61019
+ },
61020
+ runtimeState: GroupStatusSchema,
61021
+ /**
61022
+ * Runtime-state durability: **session** — recomputed from members on the
61023
+ * next source event; a restored count would outlive the readings it named.
61024
+ *
61025
+ * See `RuntimeStateDurability`. Enforced by
61026
+ * `scripts/check-runtime-state-durability.ts`.
61027
+ */
61028
+ durability: "session",
61029
+ history: "none"
61030
+ };
60534
61031
  var HeatingValveStatusSchema = object({
60535
61032
  /** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
60536
61033
  position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
@@ -62300,12 +62797,18 @@ var motionCapability = {
62300
62797
  methods: {
62301
62798
  /**
62302
62799
  * Pull the current motion state synchronously. Convenience shortcut
62303
- * for consumers that don't need the full status object; equivalent
62304
- * to `getStatus()?.detected ?? false`. Will likely be folded into
62305
- * `getStatus` once the auto-injected status surface lands in every
62306
- * consumer.
62800
+ * for consumers that don't need the full status object. A composed
62801
+ * group answers from its slice (D944): unknown throws, it is not off.
62307
62802
  */
62308
62803
  isDetected: method(object({ deviceId: number() }), boolean()) },
62804
+ /**
62805
+ * A composed motion group serves `isDetected` from `detected` (D944).
62806
+ * Without this the cap stays uncomposable (`has-commands`).
62807
+ */
62808
+ composedMethods: { isDetected: {
62809
+ kind: "slice",
62810
+ field: "detected"
62811
+ } },
62309
62812
  events: {
62310
62813
  /**
62311
62814
  * Fires every time the runner transitions a camera between
@@ -70556,6 +71059,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
70556
71059
  featureProbe: featureProbeCapability,
70557
71060
  flood: floodCapability,
70558
71061
  gas: gasCapability,
71062
+ groupCommands: groupCommandsCapability,
71063
+ groupStatus: groupStatusCapability,
70559
71064
  heatingValve: heatingValveCapability,
70560
71065
  humidifier: humidifierCapability,
70561
71066
  humiditySensor: humiditySensorCapability,
@@ -71932,6 +72437,13 @@ Object.freeze({
71932
72437
  access: "view",
71933
72438
  role: "admin"
71934
72439
  },
72440
+ "addons.getPackageDocs": {
72441
+ capName: "addons",
72442
+ capScope: "system",
72443
+ addonId: null,
72444
+ access: "view",
72445
+ role: "admin"
72446
+ },
71935
72447
  "addons.getVersions": {
71936
72448
  capName: "addons",
71937
72449
  capScope: "system",
@@ -75040,6 +75552,20 @@ Object.freeze({
75040
75552
  access: "view",
75041
75553
  role: "viewer"
75042
75554
  },
75555
+ "groupCommands.getStatus": {
75556
+ capName: "group-commands",
75557
+ capScope: "device",
75558
+ addonId: null,
75559
+ access: "view",
75560
+ role: "viewer"
75561
+ },
75562
+ "groupStatus.getStatus": {
75563
+ capName: "group-status",
75564
+ capScope: "device",
75565
+ addonId: null,
75566
+ access: "view",
75567
+ role: "viewer"
75568
+ },
75043
75569
  "heatingValve.getStatus": {
75044
75570
  capName: "heating-valve",
75045
75571
  capScope: "device",
@@ -84862,6 +85388,37 @@ var SENSOR_CAP_VOCABULARY = {
84862
85388
  icon: "flame"
84863
85389
  }]
84864
85390
  },
85391
+ "group-commands": {
85392
+ scope: "device",
85393
+ noun: t("Group command", "Comando di gruppo")
85394
+ },
85395
+ "group-status": {
85396
+ scope: "device",
85397
+ noun: t("Group", "Gruppo"),
85398
+ state: [
85399
+ {
85400
+ kind: "numeric",
85401
+ field: "included",
85402
+ quantity: t("the members reporting", "i membri che rispondono"),
85403
+ label: t("Reporting", "Rispondono"),
85404
+ icon: "users"
85405
+ },
85406
+ {
85407
+ kind: "numeric",
85408
+ field: "excluded",
85409
+ quantity: t("the members left out", "i membri esclusi"),
85410
+ label: t("Excluded", "Esclusi"),
85411
+ icon: "users"
85412
+ },
85413
+ {
85414
+ kind: "numeric",
85415
+ field: "total",
85416
+ quantity: t("the member count", "il numero di membri"),
85417
+ label: t("Members", "Membri"),
85418
+ icon: "sigma"
85419
+ }
85420
+ ]
85421
+ },
84865
85422
  "humidity-sensor": {
84866
85423
  scope: "device",
84867
85424
  noun: t("Humidity", "Umidità"),
@@ -86327,6 +86884,16 @@ Object.freeze({
86327
86884
  form: "single",
86328
86885
  optional: false
86329
86886
  }],
86887
+ "groupCommands.getStatus": [{
86888
+ name: "deviceId",
86889
+ form: "single",
86890
+ optional: false
86891
+ }],
86892
+ "groupStatus.getStatus": [{
86893
+ name: "deviceId",
86894
+ form: "single",
86895
+ optional: false
86896
+ }],
86330
86897
  "heatingValve.getStatus": [{
86331
86898
  name: "deviceId",
86332
86899
  form: "single",
@@ -88518,6 +89085,8 @@ new Map(Object.entries({
88518
89085
  "detection-blind": "device-events",
88519
89086
  "motion-noisy": "device-events",
88520
89087
  "motion-calm": "device-events",
89088
+ "package-llm-silent": "device-events",
89089
+ "package-llm-answered": "device-events",
88521
89090
  "recording-stalled": "device-events",
88522
89091
  "recording-healthy": "device-events",
88523
89092
  "recording-degraded": "device-events",
@@ -88601,6 +89170,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
88601
89170
  label: "Motion without a subject",
88602
89171
  kinds: ["motion-noisy", "motion-calm"]
88603
89172
  },
89173
+ {
89174
+ id: "package-llm",
89175
+ family: "device-events",
89176
+ label: "Package confirm",
89177
+ kinds: ["package-llm-silent", "package-llm-answered"]
89178
+ },
88604
89179
  {
88605
89180
  id: "recording",
88606
89181
  family: "device-events",
@@ -88782,6 +89357,8 @@ var DEVICE_EVENTS = [
88782
89357
  "detection-blind",
88783
89358
  "motion-noisy",
88784
89359
  "motion-calm",
89360
+ "package-llm-silent",
89361
+ "package-llm-answered",
88785
89362
  "recording-stalled",
88786
89363
  "recording-healthy",
88787
89364
  "recording-degraded",
@@ -89050,6 +89627,15 @@ new Map([
89050
89627
  snapshotLabel: "Cameras with constant motion now",
89051
89628
  snapshotSection: null
89052
89629
  },
89630
+ {
89631
+ id: "package-llm-confirm",
89632
+ family: "device-events",
89633
+ label: "Package confirm (not answering / answering again)",
89634
+ bad: ["package-llm-silent"],
89635
+ recovery: ["package-llm-answered"],
89636
+ snapshotLabel: "Cameras whose package confirm is not answering",
89637
+ snapshotSection: null
89638
+ },
89053
89639
  {
89054
89640
  id: "recording-health",
89055
89641
  family: "device-events",