@camstack/addon-provider-homeassistant 1.2.627 → 1.2.629

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,5 +1,5 @@
1
1
  require("node:crypto");
2
- //#region ../types/dist/event-category-DHXxB8t9.mjs
2
+ //#region ../types/dist/event-category-CT-hz5Rb.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -325,6 +325,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
325
325
  /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
326
326
  EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
327
327
  /**
328
+ * A camera's package LLM confirm has failed closed three times in a row
329
+ * (D931, 2026-10-26). One edge per camera until
330
+ * {@link PipelinePackageLlmAnswered}.
331
+ */
332
+ EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
333
+ /** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
334
+ EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
335
+ /**
328
336
  * Per-camera pipeline config was mutated by the orchestrator
329
337
  * (a settings change via `setAgentInferenceDevices` /
330
338
  * `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
@@ -5567,7 +5575,7 @@ var ZodIssueCode = {
5567
5575
  var ZodFirstPartyTypeKind;
5568
5576
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5569
5577
  //#endregion
5570
- //#region ../types/dist/sleep-B81gwQuR.mjs
5578
+ //#region ../types/dist/sleep-bykKrTgu.mjs
5571
5579
  /**
5572
5580
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5573
5581
  * window to float samples (D455).
@@ -9010,6 +9018,7 @@ var CAP_NAMES = Object.freeze([
9010
9018
  "filesystem-browse",
9011
9019
  "flood",
9012
9020
  "gas",
9021
+ "group-commands",
9013
9022
  "group-status",
9014
9023
  "heating-valve",
9015
9024
  "humidifier",
@@ -10831,7 +10840,7 @@ object({
10831
10840
  params: record(string(), union([string(), number()])).optional()
10832
10841
  });
10833
10842
  //#endregion
10834
- //#region ../types/dist/err-msg-BXKzRBwg.mjs
10843
+ //#region ../types/dist/err-msg-DIorGYeC.mjs
10835
10844
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
10836
10845
  DeviceType["Camera"] = "camera";
10837
10846
  DeviceType["Hub"] = "hub";
@@ -10925,8 +10934,14 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
10925
10934
  DeviceType["PetFeeder"] = "pet-feeder";
10926
10935
  /** Built-in dishwasher — program lifecycle, door / remote-start gates,
10927
10936
  * salt and rinse-aid levels. Installed with the `dishwasher` cap.
10928
- * Sources: native Bosch Home Connect, reusable by similar integrations. */
10937
+ * Sources: native Bosch Home Connect, reusable by similar integrations.
10938
+ * A plug-built dishwasher carries running-state and power instead. */
10929
10939
  DeviceType["Dishwasher"] = "dishwasher";
10940
+ /** Washing machine. A plug-built one is running while its power stays
10941
+ * above a threshold. No program cap — that surface is the dishwasher's. */
10942
+ DeviceType["Washer"] = "washer";
10943
+ /** Tumble dryer. Same plug-built running surface as {@link Washer}. */
10944
+ DeviceType["Dryer"] = "dryer";
10930
10945
  return DeviceType;
10931
10946
  }({});
10932
10947
  var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
@@ -11184,7 +11199,7 @@ function errMsg(err) {
11184
11199
  return String(err);
11185
11200
  }
11186
11201
  //#endregion
11187
- //#region ../types/dist/composition-B85l9j1M.mjs
11202
+ //#region ../types/dist/composition-B2rw5L29.mjs
11188
11203
  /**
11189
11204
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11190
11205
  *
@@ -11940,6 +11955,26 @@ function validateExpressionSource(src) {
11940
11955
  return null;
11941
11956
  }
11942
11957
  /**
11958
+ * One power reading becomes a washer, dryer or dishwasher (D944 helper).
11959
+ *
11960
+ * Standby of the control board is under 5 W; a motor or a heater is far
11961
+ * above that, so 5 W is the line. A door lock or a short pump spike is not
11962
+ * a cycle, so running starts only after 30 s above the line.
11963
+ *
11964
+ * A wash, dry or dishwasher pause (soak, heat-wait, heater off between
11965
+ * bursts) lasts several minutes. Ending the cycle on the first dip would
11966
+ * report "finished" in the middle of the program, so the stop dwell is
11967
+ * 10 minutes on every type. The number is stored per type so one machine
11968
+ * can move later without moving the others.
11969
+ */
11970
+ var APPLIANCE_TEMPLATE_ID = "appliance";
11971
+ var APPLIANCE_KINDS = [
11972
+ "washer",
11973
+ "dryer",
11974
+ "dishwasher"
11975
+ ];
11976
+ DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
11977
+ /**
11943
11978
  * A composition source identity: `(addonId, stableId)`, never a numeric device
11944
11979
  * id. Split out so helper schemas can name it without a cycle through
11945
11980
  * `composition.ts` (D659).
@@ -11963,7 +11998,9 @@ var GROUP_TEMPLATE_IDS = [
11963
11998
  "leak",
11964
11999
  "smoke",
11965
12000
  "occupancy",
11966
- "binary"
12001
+ "binary",
12002
+ "switch",
12003
+ "light"
11967
12004
  ];
11968
12005
  var NUMERIC_AGGREGATES = [
11969
12006
  "mean",
@@ -11973,6 +12010,8 @@ var NUMERIC_AGGREGATES = [
11973
12010
  "sum"
11974
12011
  ];
11975
12012
  var BINARY_AGGREGATES = ["any", "all"];
12013
+ /** How an actuator group decides it is on. Unknown members never count as off. */
12014
+ var ACTIVE_CRITERIA = ["at-least-one", "all"];
11976
12015
  var AGGREGATE_REDUCERS = [
11977
12016
  "mean",
11978
12017
  "median",
@@ -11984,6 +12023,7 @@ var AGGREGATE_REDUCERS = [
11984
12023
  ];
11985
12024
  var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
11986
12025
  var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
12026
+ var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
11987
12027
  /** One member. The field is stored so occupancy can name motion or binary. */
11988
12028
  var HelperMemberSchema = object({
11989
12029
  source: CompositionSourceRefSchema,
@@ -11994,7 +12034,17 @@ var HelperSpecSchema = discriminatedUnion("kind", [object({
11994
12034
  kind: literal("group"),
11995
12035
  templateId: GroupTemplateIdSchema,
11996
12036
  aggregate: AggregateReducerSchema,
11997
- members: array(HelperMemberSchema).min(1).max(64)
12037
+ members: array(HelperMemberSchema).min(1).max(64),
12038
+ /** Actuator groups only. Readings leave this unset. */
12039
+ active: ActiveCriterionSchema.optional()
12040
+ }), object({
12041
+ kind: literal("appliance"),
12042
+ templateId: literal(APPLIANCE_TEMPLATE_ID),
12043
+ appliance: _enum(APPLIANCE_KINDS),
12044
+ thresholdWatts: number().positive(),
12045
+ startDwellMs: number().int().nonnegative(),
12046
+ stopDwellMs: number().int().nonnegative(),
12047
+ member: HelperMemberSchema
11998
12048
  })]);
11999
12049
  /** A composed device's stableId is this prefix plus the block id. */
12000
12050
  var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
@@ -18799,6 +18849,7 @@ function numeric(input) {
18799
18849
  family: "numeric",
18800
18850
  deviceType: DeviceType.Sensor,
18801
18851
  memberDeviceType: DeviceType.Sensor,
18852
+ commandCaps: [],
18802
18853
  baseUnit: baseUnitOf(input.quantity),
18803
18854
  aggregates: NUMERIC_AGGREGATES,
18804
18855
  accept: [{
@@ -18813,6 +18864,7 @@ function binary(input) {
18813
18864
  family: "binary",
18814
18865
  deviceType: DeviceType.Sensor,
18815
18866
  memberDeviceType: DeviceType.Sensor,
18867
+ commandCaps: [],
18816
18868
  quantity: "none",
18817
18869
  baseUnit: void 0,
18818
18870
  aggregates: BINARY_AGGREGATES,
@@ -19007,9 +19059,47 @@ var GROUP_TEMPLATES = [
19007
19059
  fieldPath: "on"
19008
19060
  }],
19009
19061
  companions: [CHANGED]
19062
+ }),
19063
+ actuator({
19064
+ id: "switch",
19065
+ 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.",
19066
+ deviceType: DeviceType.Switch,
19067
+ outputCap: "switch",
19068
+ commandCaps: ["switch"]
19069
+ }),
19070
+ actuator({
19071
+ id: "light",
19072
+ 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.",
19073
+ deviceType: DeviceType.Light,
19074
+ outputCap: "switch",
19075
+ commandCaps: [
19076
+ "switch",
19077
+ "brightness",
19078
+ "color"
19079
+ ]
19010
19080
  })
19011
19081
  ];
19082
+ function actuator(input) {
19083
+ return {
19084
+ ...input,
19085
+ family: "actuator",
19086
+ role: void 0,
19087
+ memberDeviceType: input.deviceType,
19088
+ outputField: "on",
19089
+ quantity: "none",
19090
+ baseUnit: void 0,
19091
+ aggregates: BINARY_AGGREGATES,
19092
+ defaultAggregate: "any",
19093
+ empty: "offline",
19094
+ accept: [{
19095
+ cap: "switch",
19096
+ fieldPath: "on"
19097
+ }],
19098
+ companions: [CHANGED]
19099
+ };
19100
+ }
19012
19101
  new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
19102
+ DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
19013
19103
  `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
19014
19104
  /**
19015
19105
  * What a composition may BUILD on a device type (G2, D676): the caps a new
@@ -46097,6 +46187,8 @@ var NcSystemEventKindSchema = _enum([
46097
46187
  "detection-blind",
46098
46188
  "motion-noisy",
46099
46189
  "motion-calm",
46190
+ "package-llm-silent",
46191
+ "package-llm-answered",
46100
46192
  "recording-stalled",
46101
46193
  "recording-healthy",
46102
46194
  "recording-degraded",
@@ -57276,6 +57368,28 @@ var PackageVersionInfoSchema = object({
57276
57368
  deprecated: string().optional(),
57277
57369
  distTags: array(string()).readonly()
57278
57370
  });
57371
+ /**
57372
+ * One published document. `ok` is markdown from the registry. `missing` means
57373
+ * the registry answered and the file was not there. `error` is a registry or
57374
+ * tarball failure — never an empty string standing in for either.
57375
+ */
57376
+ var PackageDocBodySchema = discriminatedUnion("status", [
57377
+ object({
57378
+ status: literal("ok"),
57379
+ markdown: string()
57380
+ }),
57381
+ object({ status: literal("missing") }),
57382
+ object({
57383
+ status: literal("error"),
57384
+ message: string()
57385
+ })
57386
+ ]);
57387
+ var PackageDocsSchema = object({
57388
+ name: string(),
57389
+ version: string(),
57390
+ readme: PackageDocBodySchema,
57391
+ changelog: PackageDocBodySchema
57392
+ });
57279
57393
  var SearchResultSchema = object({
57280
57394
  name: string(),
57281
57395
  version: string(),
@@ -57494,7 +57608,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
57494
57608
  }), object({ success: literal(true) }), {
57495
57609
  kind: "mutation",
57496
57610
  auth: "admin"
57497
- }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
57611
+ }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
57612
+ name: string().min(1),
57613
+ version: string().min(1).optional()
57614
+ }), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
57498
57615
  kind: "mutation",
57499
57616
  auth: "admin"
57500
57617
  }), method(object({ packageName: string() }), object({ success: literal(true) }), {
@@ -60864,6 +60981,39 @@ var gasCapability = {
60864
60981
  * whether persisting is worth a SQLite commit. */
60865
60982
  volatileStateFields: ["lastChangedAt"]
60866
60983
  };
60984
+ var GroupCommandsSchema = object({
60985
+ /** One row per member that has been commanded. A later command replaces that member's row. */
60986
+ results: array(object({
60987
+ deviceId: number().int().nonnegative(),
60988
+ cap: string().min(1),
60989
+ method: string().min(1),
60990
+ ok: boolean(),
60991
+ error: string().optional(),
60992
+ /** Ms epoch of the attempt. */
60993
+ at: number()
60994
+ })) });
60995
+ var groupCommandsCapability = {
60996
+ name: "group-commands",
60997
+ scope: "device",
60998
+ deviceNative: true,
60999
+ mode: "singleton",
61000
+ deviceTypes: [DeviceType.Switch, DeviceType.Light],
61001
+ methods: {},
61002
+ status: {
61003
+ schema: GroupCommandsSchema,
61004
+ kind: "push"
61005
+ },
61006
+ runtimeState: GroupCommandsSchema,
61007
+ /**
61008
+ * Runtime-state durability: **session** — the last attempt. A restored
61009
+ * failure would outlive the command that caused it.
61010
+ *
61011
+ * See `RuntimeStateDurability`. Enforced by
61012
+ * `scripts/check-runtime-state-durability.ts`.
61013
+ */
61014
+ durability: "session",
61015
+ history: "none"
61016
+ };
60867
61017
  /**
60868
61018
  * How many members of a helper group answered (D944). Counts are integers,
60869
61019
  * not measurements: zero included is a real count, never a stand-in reading.
@@ -60892,7 +61042,11 @@ var groupStatusCapability = {
60892
61042
  scope: "device",
60893
61043
  deviceNative: true,
60894
61044
  mode: "singleton",
60895
- deviceTypes: [DeviceType.Sensor],
61045
+ deviceTypes: [
61046
+ DeviceType.Sensor,
61047
+ DeviceType.Switch,
61048
+ DeviceType.Light
61049
+ ],
60896
61050
  methods: {},
60897
61051
  status: {
60898
61052
  schema: GroupStatusSchema,
@@ -64727,7 +64881,12 @@ var powerMeterCapability = {
64727
64881
  scope: "device",
64728
64882
  deviceNative: true,
64729
64883
  mode: "singleton",
64730
- deviceTypes: [DeviceType.Sensor],
64884
+ deviceTypes: [
64885
+ DeviceType.Sensor,
64886
+ DeviceType.Washer,
64887
+ DeviceType.Dryer,
64888
+ DeviceType.Dishwasher
64889
+ ],
64731
64890
  methods: {},
64732
64891
  status: {
64733
64892
  schema: PowerMeterStatusSchema,
@@ -65473,6 +65632,8 @@ var runningCustomize = {
65473
65632
  stateField: "running"
65474
65633
  },
65475
65634
  deviceTypes: [
65635
+ DeviceType.Washer,
65636
+ DeviceType.Dryer,
65476
65637
  DeviceType.Dishwasher,
65477
65638
  DeviceType.Vacuum,
65478
65639
  DeviceType.LawnMower,
@@ -70611,7 +70772,7 @@ function tryConvertDelta(value, from, to) {
70611
70772
  return shifted - origin;
70612
70773
  }
70613
70774
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
70614
- 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;
70775
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
70615
70776
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
70616
70777
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
70617
70778
  new Set(CAP_NAMES);
@@ -70940,6 +71101,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
70940
71101
  featureProbe: featureProbeCapability,
70941
71102
  flood: floodCapability,
70942
71103
  gas: gasCapability,
71104
+ groupCommands: groupCommandsCapability,
70943
71105
  groupStatus: groupStatusCapability,
70944
71106
  heatingValve: heatingValveCapability,
70945
71107
  humidifier: humidifierCapability,
@@ -72209,7 +72371,7 @@ var BaseDeviceProvider = class extends BaseAddon {
72209
72371
  return toDeviceSummary(device, this.addonId);
72210
72372
  }
72211
72373
  };
72212
- 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;
72374
+ 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;
72213
72375
  new Set(Object.values(DeviceType));
72214
72376
  Object.freeze({
72215
72377
  "accessories.getStatus": {
@@ -72317,6 +72479,13 @@ Object.freeze({
72317
72479
  access: "view",
72318
72480
  role: "admin"
72319
72481
  },
72482
+ "addons.getPackageDocs": {
72483
+ capName: "addons",
72484
+ capScope: "system",
72485
+ addonId: null,
72486
+ access: "view",
72487
+ role: "admin"
72488
+ },
72320
72489
  "addons.getVersions": {
72321
72490
  capName: "addons",
72322
72491
  capScope: "system",
@@ -75425,6 +75594,13 @@ Object.freeze({
75425
75594
  access: "view",
75426
75595
  role: "viewer"
75427
75596
  },
75597
+ "groupCommands.getStatus": {
75598
+ capName: "group-commands",
75599
+ capScope: "device",
75600
+ addonId: null,
75601
+ access: "view",
75602
+ role: "viewer"
75603
+ },
75428
75604
  "groupStatus.getStatus": {
75429
75605
  capName: "group-status",
75430
75606
  capScope: "device",
@@ -84482,7 +84658,39 @@ var APPLIANCE_CAP_VOCABULARY = {
84482
84658
  phrase: t("When {device} finishes", "Quando {device} finisce"),
84483
84659
  icon: "square"
84484
84660
  }
84485
- }
84661
+ },
84662
+ overrides: { byType: {
84663
+ [DeviceType.Washer]: {
84664
+ state: { running: {
84665
+ whenTrue: t("When the washing machine starts", "Quando la lavatrice inizia"),
84666
+ whenFalse: t("When the washing machine has finished", "Quando la lavatrice ha finito")
84667
+ } },
84668
+ events: {
84669
+ onStarted: { phrase: t("When the washing machine starts", "Quando la lavatrice inizia") },
84670
+ onFinished: { phrase: t("When the washing machine has finished", "Quando la lavatrice ha finito") }
84671
+ }
84672
+ },
84673
+ [DeviceType.Dryer]: {
84674
+ state: { running: {
84675
+ whenTrue: t("When the dryer starts", "Quando l'asciugatrice inizia"),
84676
+ whenFalse: t("When the dryer has finished", "Quando l'asciugatrice ha finito")
84677
+ } },
84678
+ events: {
84679
+ onStarted: { phrase: t("When the dryer starts", "Quando l'asciugatrice inizia") },
84680
+ onFinished: { phrase: t("When the dryer has finished", "Quando l'asciugatrice ha finito") }
84681
+ }
84682
+ },
84683
+ [DeviceType.Dishwasher]: {
84684
+ state: { running: {
84685
+ whenTrue: t("When the dishwasher starts", "Quando la lavastoviglie inizia"),
84686
+ whenFalse: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito")
84687
+ } },
84688
+ events: {
84689
+ onStarted: { phrase: t("When the dishwasher starts", "Quando la lavastoviglie inizia") },
84690
+ onFinished: { phrase: t("When the dishwasher has finished", "Quando la lavastoviglie ha finito") }
84691
+ }
84692
+ }
84693
+ } }
84486
84694
  },
84487
84695
  update: {
84488
84696
  scope: "device",
@@ -85254,6 +85462,10 @@ var SENSOR_CAP_VOCABULARY = {
85254
85462
  icon: "flame"
85255
85463
  }]
85256
85464
  },
85465
+ "group-commands": {
85466
+ scope: "device",
85467
+ noun: t("Group command", "Comando di gruppo")
85468
+ },
85257
85469
  "group-status": {
85258
85470
  scope: "device",
85259
85471
  noun: t("Group", "Gruppo"),
@@ -85778,8 +85990,58 @@ function projectAction(cap, action) {
85778
85990
  };
85779
85991
  }
85780
85992
  Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
85781
- 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;
85993
+ 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;
85782
85994
  DeviceFeature.BatteryOperated;
85995
+ /**
85996
+ * How a washer, dryer or dishwasher leaves CamStack.
85997
+ *
85998
+ * Home Assistant has no laundry domain: the device is offered, and what
85999
+ * travels is its power reading. The others have a laundry type that this
86000
+ * export cannot honour yet, so they are named and withheld.
86001
+ */
86002
+ var PLUG_APPLIANCE_TYPES = [
86003
+ DeviceType.Washer,
86004
+ DeviceType.Dryer,
86005
+ DeviceType.Dishwasher
86006
+ ];
86007
+ 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.";
86008
+ 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.";
86009
+ var ALEXA_REASON = "Alexa has no laundry category in this export, and neither power nor running has an Alexa interface.";
86010
+ var GOOGLE_REASON = "Google WASHER, DRYER and DISHWASHER require RunCycle. A power threshold is not that trait, and this export does not publish RunCycle.";
86011
+ 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.";
86012
+ function withheld(reason) {
86013
+ return {
86014
+ [DeviceType.Washer]: {
86015
+ exported: false,
86016
+ reason
86017
+ },
86018
+ [DeviceType.Dryer]: {
86019
+ exported: false,
86020
+ reason
86021
+ },
86022
+ [DeviceType.Dishwasher]: {
86023
+ exported: false,
86024
+ reason
86025
+ }
86026
+ };
86027
+ }
86028
+ function offered(received) {
86029
+ return {
86030
+ [DeviceType.Washer]: {
86031
+ exported: true,
86032
+ as: received
86033
+ },
86034
+ [DeviceType.Dryer]: {
86035
+ exported: true,
86036
+ as: received
86037
+ },
86038
+ [DeviceType.Dishwasher]: {
86039
+ exported: true,
86040
+ as: received
86041
+ }
86042
+ };
86043
+ }
86044
+ offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
85783
86045
  Object.freeze({
85784
86046
  "accessories.getStatus": [{
85785
86047
  name: "deviceId",
@@ -86746,6 +87008,11 @@ Object.freeze({
86746
87008
  form: "single",
86747
87009
  optional: false
86748
87010
  }],
87011
+ "groupCommands.getStatus": [{
87012
+ name: "deviceId",
87013
+ form: "single",
87014
+ optional: false
87015
+ }],
86749
87016
  "groupStatus.getStatus": [{
86750
87017
  name: "deviceId",
86751
87018
  form: "single",
@@ -88942,6 +89209,8 @@ new Map(Object.entries({
88942
89209
  "detection-blind": "device-events",
88943
89210
  "motion-noisy": "device-events",
88944
89211
  "motion-calm": "device-events",
89212
+ "package-llm-silent": "device-events",
89213
+ "package-llm-answered": "device-events",
88945
89214
  "recording-stalled": "device-events",
88946
89215
  "recording-healthy": "device-events",
88947
89216
  "recording-degraded": "device-events",
@@ -89025,6 +89294,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
89025
89294
  label: "Motion without a subject",
89026
89295
  kinds: ["motion-noisy", "motion-calm"]
89027
89296
  },
89297
+ {
89298
+ id: "package-llm",
89299
+ family: "device-events",
89300
+ label: "Package confirm",
89301
+ kinds: ["package-llm-silent", "package-llm-answered"]
89302
+ },
89028
89303
  {
89029
89304
  id: "recording",
89030
89305
  family: "device-events",
@@ -89206,6 +89481,8 @@ var DEVICE_EVENTS = [
89206
89481
  "detection-blind",
89207
89482
  "motion-noisy",
89208
89483
  "motion-calm",
89484
+ "package-llm-silent",
89485
+ "package-llm-answered",
89209
89486
  "recording-stalled",
89210
89487
  "recording-healthy",
89211
89488
  "recording-degraded",
@@ -89474,6 +89751,15 @@ new Map([
89474
89751
  snapshotLabel: "Cameras with constant motion now",
89475
89752
  snapshotSection: null
89476
89753
  },
89754
+ {
89755
+ id: "package-llm-confirm",
89756
+ family: "device-events",
89757
+ label: "Package confirm (not answering / answering again)",
89758
+ bad: ["package-llm-silent"],
89759
+ recovery: ["package-llm-answered"],
89760
+ snapshotLabel: "Cameras whose package confirm is not answering",
89761
+ snapshotSection: null
89762
+ },
89477
89763
  {
89478
89764
  id: "recording-health",
89479
89765
  family: "device-events",
@@ -90303,6 +90589,12 @@ Object.defineProperty(exports, "MediaPlayerRepeatSchema", {
90303
90589
  return MediaPlayerRepeatSchema;
90304
90590
  }
90305
90591
  });
90592
+ Object.defineProperty(exports, "PLUG_APPLIANCE_TYPES", {
90593
+ enumerable: true,
90594
+ get: function() {
90595
+ return PLUG_APPLIANCE_TYPES;
90596
+ }
90597
+ });
90306
90598
  Object.defineProperty(exports, "RUNNING_STATE_COLD", {
90307
90599
  enumerable: true,
90308
90600
  get: function() {
@@ -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-CRwUHjY7.js");
27
+ const require_dist = require("../dist-sQp4D2Eo.js");
28
28
  let node_crypto = require("node:crypto");
29
29
  require("node:zlib");
30
30
  let node_fs = require("node:fs");
@@ -3492,6 +3492,10 @@ var CAPS_NOT_EXPORTED = [
3492
3492
  cap: "group-status",
3493
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
3494
  },
3495
+ {
3496
+ cap: "group-commands",
3497
+ reason: "The last fan-out a helper group attempted (D944), one row per member. It is session-only and has no history. The command an automation sends is the member capability (switch, brightness, colour), not this record."
3498
+ },
3495
3499
  {
3496
3500
  cap: "recording-onboard",
3497
3501
  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."
@@ -6654,6 +6658,46 @@ function projectSynthetic(input, nowMs) {
6654
6658
  return values;
6655
6659
  }
6656
6660
  //#endregion
6661
+ //#region src/ha-export/supported-device-kinds.ts
6662
+ /**
6663
+ * Device types the Home Assistant export picker offers.
6664
+ *
6665
+ * A UI filter. What actually travels is still the entity catalog: a washer,
6666
+ * dryer or dishwasher is offered because its power reading exports as a
6667
+ * sensor. running-state stays unmapped.
6668
+ */
6669
+ var SUPPORTED_DEVICE_KINDS = [
6670
+ "camera",
6671
+ "light",
6672
+ "siren",
6673
+ "switch",
6674
+ "sensor",
6675
+ "thermostat",
6676
+ "climate",
6677
+ "button",
6678
+ "event-emitter",
6679
+ "update",
6680
+ "generic",
6681
+ "lock",
6682
+ "cover",
6683
+ "valve",
6684
+ "humidifier",
6685
+ "water-heater",
6686
+ "fan",
6687
+ "media-player",
6688
+ "alarm-panel",
6689
+ "control",
6690
+ "presence",
6691
+ "weather",
6692
+ "vacuum",
6693
+ "lawn-mower",
6694
+ "container",
6695
+ "image",
6696
+ "pet-feeder",
6697
+ "hub",
6698
+ ...require_dist.PLUG_APPLIANCE_TYPES
6699
+ ];
6700
+ //#endregion
6657
6701
  //#region src/ha-export/ha-export.addon.ts
6658
6702
  /**
6659
6703
  * Native Home Assistant export — a custom component fed by HTTP push.
@@ -9046,36 +9090,6 @@ var HaExportAddon = class extends require_dist.BaseAddon {
9046
9090
  * CAPABILITIES, not its type, and restricting the picker by type is what
9047
9091
  * confined the previous exporter to cameras.
9048
9092
  */
9049
- var SUPPORTED_DEVICE_KINDS = [
9050
- "camera",
9051
- "light",
9052
- "siren",
9053
- "switch",
9054
- "sensor",
9055
- "thermostat",
9056
- "climate",
9057
- "button",
9058
- "event-emitter",
9059
- "update",
9060
- "generic",
9061
- "lock",
9062
- "cover",
9063
- "valve",
9064
- "humidifier",
9065
- "water-heater",
9066
- "fan",
9067
- "media-player",
9068
- "alarm-panel",
9069
- "control",
9070
- "presence",
9071
- "weather",
9072
- "vacuum",
9073
- "lawn-mower",
9074
- "container",
9075
- "image",
9076
- "pet-feeder",
9077
- "hub"
9078
- ];
9079
9093
  /**
9080
9094
  * POST one message to Home Assistant's push view.
9081
9095
  *