@camstack/addon-provider-homeassistant 1.2.659 → 1.2.660

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.
@@ -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_ha_instance_settings = require("../ha-instance-settings-CRvQ5rH6.js");
27
+ const require_legacy_integration_rows = require("../legacy-integration-rows-BWVmjfDO.js");
28
28
  let node_crypto = require("node:crypto");
29
29
  require("node:zlib");
30
30
  let node_fs = require("node:fs");
@@ -91,7 +91,7 @@ async function applyCameraFunctionWrite(api, deviceId, write, sourceNodeId) {
91
91
  await api.streamBroker.setDeviceAudioMute.mutate({
92
92
  deviceId,
93
93
  muted: write.muted
94
- }, require_ha_instance_settings.nodePin(sourceNodeId));
94
+ }, require_legacy_integration_rows.nodePin(sourceNodeId));
95
95
  return;
96
96
  }
97
97
  }
@@ -725,8 +725,8 @@ function consumableEntity(key, facet) {
725
725
  * rather than to an icon for nothing.
726
726
  */
727
727
  function consumableForm(item) {
728
- const declared = require_ha_instance_settings.ConsumableFormSchema.safeParse(item.form);
729
- return require_ha_instance_settings.consumableFormOf({
728
+ const declared = require_legacy_integration_rows.ConsumableFormSchema.safeParse(item.form);
729
+ return require_legacy_integration_rows.consumableFormOf({
730
730
  ...item.kind !== void 0 ? { kind: item.kind } : {},
731
731
  ...declared.success ? { form: declared.data } : {}
732
732
  });
@@ -739,7 +739,7 @@ function partIcon(key, label) {
739
739
  function formIcon(item, form) {
740
740
  switch (form) {
741
741
  case "part": return partIcon(item.key, item.label);
742
- case "tank": return require_ha_instance_settings.consumableKindOf(item) === "waste" ? "mdi:water-off" : "mdi:water";
742
+ case "tank": return require_legacy_integration_rows.consumableKindOf(item) === "waste" ? "mdi:water-off" : "mdi:water";
743
743
  case "product": return "mdi:shaker-outline";
744
744
  case "bin": return "mdi:delete";
745
745
  }
@@ -750,8 +750,8 @@ function formIcon(item, form) {
750
750
  * form this export does not know degrades one icon instead of refusing the
751
751
  * whole slice.
752
752
  */
753
- var ExportConsumableItemSchema = require_ha_instance_settings.ConsumableItemSchema.extend({ form: require_ha_instance_settings.unknown().optional() });
754
- var ExportConsumablesSchema = require_ha_instance_settings.object({ items: require_ha_instance_settings.array(ExportConsumableItemSchema) });
753
+ var ExportConsumableItemSchema = require_legacy_integration_rows.ConsumableItemSchema.extend({ form: require_legacy_integration_rows.unknown().optional() });
754
+ var ExportConsumablesSchema = require_legacy_integration_rows.object({ items: require_legacy_integration_rows.array(ExportConsumableItemSchema) });
755
755
  /**
756
756
  * A worn part's life is a diagnostic; a tank's fill is what the device page
757
757
  * is for (a vacuum's clean water, a dishwasher's salt), so it is not hidden.
@@ -764,7 +764,7 @@ function consumableEntities(item) {
764
764
  capName: "consumables",
765
765
  itemKey: item.key
766
766
  };
767
- const kind = require_ha_instance_settings.consumableKindOf(item);
767
+ const kind = require_legacy_integration_rows.consumableKindOf(item);
768
768
  const form = consumableForm(item);
769
769
  const icon = formIcon(item, form);
770
770
  /** What the item IS, on the sensors that describe it (not on a counter or a button). */
@@ -804,7 +804,7 @@ function consumableEntities(item) {
804
804
  platform: "sensor",
805
805
  label: `${item.label} status`,
806
806
  deviceClass: "enum",
807
- options: require_ha_instance_settings.ConsumableStatusSchema.options,
807
+ options: require_legacy_integration_rows.ConsumableStatusSchema.options,
808
808
  icon,
809
809
  attributes,
810
810
  entityCategory: "diagnostic"
@@ -2405,7 +2405,7 @@ var CAP_ENTITY_MAP = {
2405
2405
  * failure. `fanMode` and `preset` get no such list at all: they are
2406
2406
  * free-form strings, so they stay sensors.
2407
2407
  */
2408
- options: require_ha_instance_settings.HvacModeSchema.options,
2408
+ options: require_legacy_integration_rows.HvacModeSchema.options,
2409
2409
  extras: {
2410
2410
  "current-temp": {
2411
2411
  platform: "sensor",
@@ -2555,7 +2555,7 @@ var CAP_ENTITY_MAP = {
2555
2555
  field: "direction",
2556
2556
  label: "Direction",
2557
2557
  writable: true,
2558
- options: require_ha_instance_settings.FanDirectionSchema.options,
2558
+ options: require_legacy_integration_rows.FanDirectionSchema.options,
2559
2559
  enabledByDefault: false
2560
2560
  }
2561
2561
  }
@@ -2985,7 +2985,7 @@ var CAP_ENTITY_MAP = {
2985
2985
  field: "repeat",
2986
2986
  label: "Repeat",
2987
2987
  writable: true,
2988
- options: require_ha_instance_settings.MediaPlayerRepeatSchema.options,
2988
+ options: require_legacy_integration_rows.MediaPlayerRepeatSchema.options,
2989
2989
  enabledByDefault: false
2990
2990
  },
2991
2991
  shuffle: {
@@ -3481,7 +3481,7 @@ function controlEntitySpecs(slice, quantity) {
3481
3481
  const min = readFiniteNumber(slice, "min") ?? PERCENT_RANGE.min;
3482
3482
  const max = readFiniteNumber(slice, "max") ?? PERCENT_RANGE.max;
3483
3483
  const step = readFiniteNumber(slice, "step") ?? PERCENT_RANGE.step;
3484
- const unit = quantity === void 0 ? void 0 : require_ha_instance_settings.baseUnitOf(quantity);
3484
+ const unit = quantity === void 0 ? void 0 : require_legacy_integration_rows.baseUnitOf(quantity);
3485
3485
  if (min < max && step > 0) return [{
3486
3486
  entity: primary,
3487
3487
  platform: "number",
@@ -3803,7 +3803,7 @@ function buildDerivedPlan(device, options = UNNEGOTIATED_PLAN_OPTIONS) {
3803
3803
  continue;
3804
3804
  }
3805
3805
  if (cap === "numeric-sensor") {
3806
- const unit = device.readingQuantity === void 0 ? void 0 : require_ha_instance_settings.baseUnitOf(device.readingQuantity);
3806
+ const unit = device.readingQuantity === void 0 ? void 0 : require_legacy_integration_rows.baseUnitOf(device.readingQuantity);
3807
3807
  specs.push(...capEntitySpecs(cap).map((spec) => degradeUnsupported(unit === void 0 ? spec : {
3808
3808
  ...spec,
3809
3809
  unit
@@ -3878,7 +3878,7 @@ function buildDevicePlan(device, options = UNNEGOTIATED_PLAN_OPTIONS) {
3878
3878
  * was.
3879
3879
  */
3880
3880
  /** The camera function ids, keyed by the entity slug the catalog emits. */
3881
- var CAMERA_SWITCH_BY_SLUG = Object.fromEntries(require_ha_instance_settings.CAMERA_SWITCH_ORDER.map((id) => [toSlug(id), id]));
3881
+ var CAMERA_SWITCH_BY_SLUG = Object.fromEntries(require_legacy_integration_rows.CAMERA_SWITCH_ORDER.map((id) => [toSlug(id), id]));
3882
3882
  var PTZ_DIRECTION_BY_ENTITY = Object.fromEntries(PTZ_BUTTONS.map((entity) => [entity, entity.slice(4)]));
3883
3883
  function parseBool(value) {
3884
3884
  const lower = value.trim().toLowerCase();
@@ -3941,7 +3941,7 @@ function parseAlarmAction(value) {
3941
3941
  if (lower === "disarm" || lower === "disarmed") return { kind: "disarm" };
3942
3942
  if (lower === "trigger" || lower === "triggered") return { kind: "trigger" };
3943
3943
  const withoutPrefix = lower.startsWith("armed_") ? lower.slice(6) : lower.startsWith("arm_") ? lower.slice(4) : lower;
3944
- const mode = require_ha_instance_settings.AlarmArmModeSchema.safeParse(withoutPrefix);
3944
+ const mode = require_legacy_integration_rows.AlarmArmModeSchema.safeParse(withoutPrefix);
3945
3945
  return mode.success ? {
3946
3946
  kind: "arm",
3947
3947
  mode: mode.data
@@ -4090,7 +4090,7 @@ var CAP_COMMAND_ROUTES = {
4090
4090
  },
4091
4091
  "climate-control": {
4092
4092
  primary: (deviceId, value) => {
4093
- const mode = parseEnum(require_ha_instance_settings.HvacModeSchema, value);
4093
+ const mode = parseEnum(require_legacy_integration_rows.HvacModeSchema, value);
4094
4094
  return mode === null ? null : {
4095
4095
  kind: "climate-mode",
4096
4096
  deviceId,
@@ -4205,7 +4205,7 @@ var CAP_COMMAND_ROUTES = {
4205
4205
  };
4206
4206
  },
4207
4207
  direction: (deviceId, value) => {
4208
- const direction = parseEnum(require_ha_instance_settings.FanDirectionSchema, value);
4208
+ const direction = parseEnum(require_legacy_integration_rows.FanDirectionSchema, value);
4209
4209
  return direction === null ? null : {
4210
4210
  kind: "fan-direction",
4211
4211
  deviceId,
@@ -4409,7 +4409,7 @@ var CAP_COMMAND_ROUTES = {
4409
4409
  };
4410
4410
  },
4411
4411
  repeat: (deviceId, value) => {
4412
- const repeat = parseEnum(require_ha_instance_settings.MediaPlayerRepeatSchema, value);
4412
+ const repeat = parseEnum(require_legacy_integration_rows.MediaPlayerRepeatSchema, value);
4413
4413
  return repeat === null ? null : {
4414
4414
  kind: "media-repeat",
4415
4415
  deviceId,
@@ -5001,7 +5001,7 @@ async function planDropPublicBaseUrl(ports) {
5001
5001
  op: "deleteKeys",
5002
5002
  scope: ADDON_SETTINGS_TABLE,
5003
5003
  keys: present.map(rowId),
5004
- precondition: require_ha_instance_settings.preconditionOf(Object.fromEntries(present.map((key) => [rowId(key), {
5004
+ precondition: require_legacy_integration_rows.preconditionOf(Object.fromEntries(present.map((key) => [rowId(key), {
5005
5005
  addonId: HA_EXPORT_ADDON_ID,
5006
5006
  key,
5007
5007
  value: stored[key]
@@ -5231,7 +5231,7 @@ async function planDropPerBrokerFlags(ports) {
5231
5231
  op: "deleteKeys",
5232
5232
  scope: ADDON_SETTINGS_TABLE,
5233
5233
  keys: drop.map((entry) => rowId(entry.storeKey)),
5234
- precondition: require_ha_instance_settings.preconditionOf(Object.fromEntries(drop.map((entry) => [rowId(entry.storeKey), {
5234
+ precondition: require_legacy_integration_rows.preconditionOf(Object.fromEntries(drop.map((entry) => [rowId(entry.storeKey), {
5235
5235
  addonId: HA_EXPORT_ADDON_ID,
5236
5236
  key: entry.storeKey,
5237
5237
  value: entry.value
@@ -5257,15 +5257,15 @@ var HA_EXPORT_TARGETS_KIND_NAME = "ha-export-targets";
5257
5257
  var HA_TARGET_KIND = "ha-target";
5258
5258
  var TARGET_ID_PREFIX = "hae_";
5259
5259
  /** The schema is checked against the interface by its annotation: a drifted field fails the typecheck. */
5260
- var HaExportTargetBodySchema = require_ha_instance_settings.object({
5261
- name: require_ha_instance_settings.string().min(1),
5262
- connectionId: require_ha_instance_settings.string(),
5263
- mediaRole: require_ha_instance_settings._enum(HA_MEDIA_ROLES),
5264
- reconcileIntervalSec: require_ha_instance_settings.number(),
5265
- devices: require_ha_instance_settings.array(require_ha_instance_settings.string()),
5266
- enabled: require_ha_instance_settings.boolean().optional()
5260
+ var HaExportTargetBodySchema = require_legacy_integration_rows.object({
5261
+ name: require_legacy_integration_rows.string().min(1),
5262
+ connectionId: require_legacy_integration_rows.string(),
5263
+ mediaRole: require_legacy_integration_rows._enum(HA_MEDIA_ROLES),
5264
+ reconcileIntervalSec: require_legacy_integration_rows.number(),
5265
+ devices: require_legacy_integration_rows.array(require_legacy_integration_rows.string()),
5266
+ enabled: require_legacy_integration_rows.boolean().optional()
5267
5267
  });
5268
- var haExportTargetsKind = require_ha_instance_settings.defineEntryKind(HA_EXPORT_TARGETS_KIND_NAME, {
5268
+ var haExportTargetsKind = require_legacy_integration_rows.defineEntryKind(HA_EXPORT_TARGETS_KIND_NAME, {
5269
5269
  title: "Home Assistant export targets",
5270
5270
  nameField: "name",
5271
5271
  schema: HaExportTargetBodySchema,
@@ -5604,7 +5604,7 @@ async function planDropMovedLinks(ports) {
5604
5604
  op: "deleteKeys",
5605
5605
  scope: ADDON_SETTINGS_TABLE,
5606
5606
  keys: present.map(rowId),
5607
- precondition: require_ha_instance_settings.preconditionOf(Object.fromEntries(present.map((key) => [rowId(key), {
5607
+ precondition: require_legacy_integration_rows.preconditionOf(Object.fromEntries(present.map((key) => [rowId(key), {
5608
5608
  addonId: HA_EXPORT_ADDON_ID,
5609
5609
  key,
5610
5610
  value: stored[key]
@@ -5740,13 +5740,13 @@ var ADDON_MIGRATIONS = [
5740
5740
  * outside `migrations/` names it (`no-legacy-links-reader.spec.ts`).
5741
5741
  */
5742
5742
  var HA_EXPORT_LINKS_KIND_NAME = "ha-export-links";
5743
- var HaExportLinksBodySchema = require_ha_instance_settings.object({
5744
- name: require_ha_instance_settings.string().min(1),
5745
- exportTo: require_ha_instance_settings.boolean(),
5746
- mediaRole: require_ha_instance_settings._enum(HA_MEDIA_ROLES),
5747
- devices: require_ha_instance_settings.array(require_ha_instance_settings.string())
5743
+ var HaExportLinksBodySchema = require_legacy_integration_rows.object({
5744
+ name: require_legacy_integration_rows.string().min(1),
5745
+ exportTo: require_legacy_integration_rows.boolean(),
5746
+ mediaRole: require_legacy_integration_rows._enum(HA_MEDIA_ROLES),
5747
+ devices: require_legacy_integration_rows.array(require_legacy_integration_rows.string())
5748
5748
  });
5749
- var haExportLinksKind = require_ha_instance_settings.defineEntryKind(HA_EXPORT_LINKS_KIND_NAME, {
5749
+ var haExportLinksKind = require_legacy_integration_rows.defineEntryKind(HA_EXPORT_LINKS_KIND_NAME, {
5750
5750
  title: "Home Assistant export links (retired)",
5751
5751
  nameField: "name",
5752
5752
  schema: HaExportLinksBodySchema,
@@ -5781,7 +5781,7 @@ async function readAllLinks(handle) {
5781
5781
  function haExportMigrationPorts(deps) {
5782
5782
  return {
5783
5783
  readStored: deps.readStored,
5784
- ...require_ha_instance_settings.haInstanceSettingsPortsOver(deps.api.integrations),
5784
+ ...require_legacy_integration_rows.haInstanceSettingsPortsOver(deps.api.integrations),
5785
5785
  warn: deps.warn,
5786
5786
  putLinks: async (brokerId, body) => {
5787
5787
  if (await deps.links.get(brokerId) !== null) return "exists";
@@ -5791,7 +5791,7 @@ function haExportMigrationPorts(deps) {
5791
5791
  data: body
5792
5792
  }, { ifRev: 0 });
5793
5793
  } catch (err) {
5794
- if (err instanceof require_ha_instance_settings.RevConflictError) return "exists";
5794
+ if (err instanceof require_legacy_integration_rows.RevConflictError) return "exists";
5795
5795
  throw err;
5796
5796
  }
5797
5797
  return "created";
@@ -5805,7 +5805,7 @@ function haExportMigrationPorts(deps) {
5805
5805
  data: body
5806
5806
  }, { ifRev: 0 });
5807
5807
  } catch (err) {
5808
- if (err instanceof require_ha_instance_settings.RevConflictError) return "exists";
5808
+ if (err instanceof require_legacy_integration_rows.RevConflictError) return "exists";
5809
5809
  throw err;
5810
5810
  }
5811
5811
  return "created";
@@ -5887,7 +5887,7 @@ function buildTargetForm() {
5887
5887
  * may push to one Home Assistant.
5888
5888
  */
5889
5889
  function openTargetInstances(records, deps) {
5890
- return new require_ha_instance_settings.RecordIntegrationInstances(records, haExportTargetsKind, {
5890
+ return new require_legacy_integration_rows.RecordIntegrationInstances(records, haExportTargetsKind, {
5891
5891
  description: {
5892
5892
  role: "services",
5893
5893
  instanceMode: "multiple",
@@ -6646,7 +6646,7 @@ function reduceLastTriggers(rows) {
6646
6646
  function macroOf(className) {
6647
6647
  const lower = className.toLowerCase();
6648
6648
  if (EXPORTED_MACROS.includes(lower)) return lower;
6649
- const mapped = require_ha_instance_settings.COCO_TO_MACRO.mapping[lower];
6649
+ const mapped = require_legacy_integration_rows.COCO_TO_MACRO.mapping[lower];
6650
6650
  return typeof mapped === "string" ? mapped : null;
6651
6651
  }
6652
6652
  function iso(timestamp) {
@@ -7795,7 +7795,7 @@ var ExportedEntities = class {
7795
7795
  this.ports.logger.warn("homeassistant-export: exported entities not reconciled — a list was unanswered", { meta: { error: errMsg$1(err) } });
7796
7796
  return;
7797
7797
  }
7798
- const { dropped } = require_ha_instance_settings.pruneDeletedEntities([...this.state.actions.map((e) => ({
7798
+ const { dropped } = require_legacy_integration_rows.pruneDeletedEntities([...this.state.actions.map((e) => ({
7799
7799
  kind: "action",
7800
7800
  actionId: e.actionId
7801
7801
  })), ...this.state.targets.map((e) => ({
@@ -7867,7 +7867,7 @@ var ExportedEntities = class {
7867
7867
  const action = this.state.actions.find((e) => actionEntity(e.actionId) === entity);
7868
7868
  if (action !== void 0) return {
7869
7869
  handled: true,
7870
- applied: (await require_ha_instance_settings.runExportedAction(this.ports.api, this.ports.logger, {
7870
+ applied: (await require_legacy_integration_rows.runExportedAction(this.ports.api, this.ports.logger, {
7871
7871
  exporter: EXPORTER,
7872
7872
  actionId: action.actionId
7873
7873
  })).status === "started"
@@ -7875,7 +7875,7 @@ var ExportedEntities = class {
7875
7875
  const target = this.state.targets.find((e) => targetEntity(e.targetId) === entity);
7876
7876
  if (target !== void 0) return {
7877
7877
  handled: true,
7878
- applied: (await require_ha_instance_settings.sendToExportedTarget(this.ports.api, this.ports.logger, {
7878
+ applied: (await require_legacy_integration_rows.sendToExportedTarget(this.ports.api, this.ports.logger, {
7879
7879
  exporter: EXPORTER,
7880
7880
  targetId: target.targetId,
7881
7881
  notification: { body: value }
@@ -7926,7 +7926,7 @@ var SUPPORTED_DEVICE_KINDS = [
7926
7926
  "image",
7927
7927
  "pet-feeder",
7928
7928
  "hub",
7929
- ...require_ha_instance_settings.PLUG_APPLIANCE_TYPES
7929
+ ...require_legacy_integration_rows.PLUG_APPLIANCE_TYPES
7930
7930
  ];
7931
7931
  //#endregion
7932
7932
  //#region src/ha-export/ha-export.addon.ts
@@ -7991,7 +7991,7 @@ var DEFAULT_CONFIG = { exportedEntities: {
7991
7991
  actions: [],
7992
7992
  targets: []
7993
7993
  } };
7994
- var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
7994
+ var HaExportAddon = class extends require_legacy_integration_rows.BaseAddon {
7995
7995
  links = /* @__PURE__ */ new Map();
7996
7996
  instances = null;
7997
7997
  /** The Home Assistant connections (broker ids) the last `broker.list` answered. */
@@ -8105,7 +8105,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
8105
8105
  await records.declare({ "ha-export-targets": haExportTargetsKind });
8106
8106
  const targetsHandle = records.kind(haExportTargetsKind);
8107
8107
  const legacyLinks = await declareLegacyLinks(records);
8108
- await this.runMigrations(require_ha_instance_settings.defineAddonMigrations(ADDON_MIGRATIONS, haExportMigrationPorts({
8108
+ await this.runMigrations(require_legacy_integration_rows.defineAddonMigrations(ADDON_MIGRATIONS, haExportMigrationPorts({
8109
8109
  readStored: async () => this.resolveGlobalStore(),
8110
8110
  api: this.ctx.api,
8111
8111
  links: legacyLinks,
@@ -8122,7 +8122,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
8122
8122
  health: (id, body) => this.targetHealth(id, body),
8123
8123
  onChanged: (id, change) => this.onTargetChanged(id, change)
8124
8124
  });
8125
- const secret = this.state("haExportMediaSecret", require_ha_instance_settings.string(), "");
8125
+ const secret = this.state("haExportMediaSecret", require_legacy_integration_rows.string(), "");
8126
8126
  const existing = await secret.get();
8127
8127
  if (existing.length === 0) {
8128
8128
  const minted = randomSecret();
@@ -8155,9 +8155,9 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
8155
8155
  this.exportedEntities = exportedEntities;
8156
8156
  return [
8157
8157
  {
8158
- capability: require_ha_instance_settings.deviceExportCapability,
8158
+ capability: require_legacy_integration_rows.deviceExportCapability,
8159
8159
  provider: {
8160
- getStatus: async (input) => this.buildStatus(this.targetScope(require_ha_instance_settings.statusInstanceOf(input))),
8160
+ getStatus: async (input) => this.buildStatus(this.targetScope(require_legacy_integration_rows.statusInstanceOf(input))),
8161
8161
  listInstances: async () => this.book().ids().map((id) => ({
8162
8162
  instanceId: id,
8163
8163
  name: this.book().name(id),
@@ -8203,12 +8203,12 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
8203
8203
  }
8204
8204
  },
8205
8205
  {
8206
- capability: require_ha_instance_settings.integrationInstancesCapability,
8206
+ capability: require_legacy_integration_rows.integrationInstancesCapability,
8207
8207
  provider: this.requireInstances().toProvider()
8208
8208
  },
8209
8209
  {
8210
- capability: require_ha_instance_settings.addonRoutesCapability,
8211
- provider: require_ha_instance_settings.buildAddonRouteProvider(ADDON_ID, [{
8210
+ capability: require_legacy_integration_rows.addonRoutesCapability,
8211
+ provider: require_legacy_integration_rows.buildAddonRouteProvider(ADDON_ID, [{
8212
8212
  method: "POST",
8213
8213
  path: "/command",
8214
8214
  access: "authenticated",
@@ -8219,7 +8219,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
8219
8219
  }])
8220
8220
  },
8221
8221
  {
8222
- capability: require_ha_instance_settings.oauthIntegrationCapability,
8222
+ capability: require_legacy_integration_rows.oauthIntegrationCapability,
8223
8223
  provider: { getDescriptor: async () => HOME_ASSISTANT_OAUTH_INTEGRATION }
8224
8224
  }
8225
8225
  ];
@@ -8248,16 +8248,16 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
8248
8248
  return this.instances;
8249
8249
  }
8250
8250
  wireListeners() {
8251
- this.subscribe({ category: require_ha_instance_settings.EventCategory.DeviceStateChanged }, (event) => {
8251
+ this.subscribe({ category: require_legacy_integration_rows.EventCategory.DeviceStateChanged }, (event) => {
8252
8252
  this.onSliceChanged(event.data);
8253
8253
  });
8254
- this.subscribe({ category: require_ha_instance_settings.EventCategory.DeviceOnline }, (event) => {
8254
+ this.subscribe({ category: require_legacy_integration_rows.EventCategory.DeviceOnline }, (event) => {
8255
8255
  this.onOnlineChanged(event.data, true);
8256
8256
  });
8257
- this.subscribe({ category: require_ha_instance_settings.EventCategory.DeviceOffline }, (event) => {
8257
+ this.subscribe({ category: require_legacy_integration_rows.EventCategory.DeviceOffline }, (event) => {
8258
8258
  this.onOnlineChanged(event.data, false);
8259
8259
  });
8260
- this.subscribe({ category: require_ha_instance_settings.EventCategory.MotionOnMotionChanged }, (event) => {
8260
+ this.subscribe({ category: require_legacy_integration_rows.EventCategory.MotionOnMotionChanged }, (event) => {
8261
8261
  this.onMotion(event.data);
8262
8262
  });
8263
8263
  /**
@@ -8266,13 +8266,13 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
8266
8266
  * the entity existed and effectively never moved. It also carries the
8267
8267
  * window LEVEL, which nothing else on the export path does.
8268
8268
  */
8269
- this.subscribe({ category: require_ha_instance_settings.EventCategory.PipelineAudioInferenceResult }, (event) => {
8269
+ this.subscribe({ category: require_legacy_integration_rows.EventCategory.PipelineAudioInferenceResult }, (event) => {
8270
8270
  this.onAudioWindow(event.data);
8271
8271
  });
8272
- this.subscribe({ category: require_ha_instance_settings.EventCategory.PipelineAnalyticsTrackLifecycle }, (event) => {
8272
+ this.subscribe({ category: require_legacy_integration_rows.EventCategory.PipelineAnalyticsTrackLifecycle }, (event) => {
8273
8273
  this.onTrackLifecycle(event.data);
8274
8274
  });
8275
- this.subscribe({ category: require_ha_instance_settings.EventCategory.ZoneAnalyticsOccupancyChanged }, (event) => {
8275
+ this.subscribe({ category: require_legacy_integration_rows.EventCategory.ZoneAnalyticsOccupancyChanged }, (event) => {
8276
8276
  this.onZoneOccupancy(event.data);
8277
8277
  });
8278
8278
  /**
@@ -8281,11 +8281,11 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
8281
8281
  * rather than a state push.
8282
8282
  */
8283
8283
  for (const category of [
8284
- require_ha_instance_settings.EventCategory.DeviceRegistered,
8285
- require_ha_instance_settings.EventCategory.DeviceUnregistered,
8286
- require_ha_instance_settings.EventCategory.DeviceBindingsChanged,
8287
- require_ha_instance_settings.EventCategory.DeviceMetaChanged,
8288
- require_ha_instance_settings.EventCategory.BrokerStatusChanged
8284
+ require_legacy_integration_rows.EventCategory.DeviceRegistered,
8285
+ require_legacy_integration_rows.EventCategory.DeviceUnregistered,
8286
+ require_legacy_integration_rows.EventCategory.DeviceBindingsChanged,
8287
+ require_legacy_integration_rows.EventCategory.DeviceMetaChanged,
8288
+ require_legacy_integration_rows.EventCategory.BrokerStatusChanged
8289
8289
  ]) this.subscribe({ category }, () => {
8290
8290
  this.reconcileSoon();
8291
8291
  });
@@ -9398,7 +9398,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
9398
9398
  */
9399
9399
  capSlices: snapshot,
9400
9400
  itemEntities: items.entities,
9401
- ...require_ha_instance_settings.isReadingQuantity(readingQuantity) ? { readingQuantity } : {}
9401
+ ...require_legacy_integration_rows.isReadingQuantity(readingQuantity) ? { readingQuantity } : {}
9402
9402
  },
9403
9403
  heldBack
9404
9404
  };
@@ -9632,7 +9632,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
9632
9632
  maskEnabled: privacySlice["enabled"] === true,
9633
9633
  audioEnabled: typeof privacySlice["audioEnabled"] === "boolean" ? privacySlice["audioEnabled"] : null
9634
9634
  };
9635
- const brokerAudioMuted = sourceNodeId === null ? null : await this.ctx.api.streamBroker.getDeviceAudioMute.query({ deviceId }, require_ha_instance_settings.nodePin(sourceNodeId)).then((r) => r.muted).catch((err) => {
9635
+ const brokerAudioMuted = sourceNodeId === null ? null : await this.ctx.api.streamBroker.getDeviceAudioMute.query({ deviceId }, require_legacy_integration_rows.nodePin(sourceNodeId)).then((r) => r.muted).catch((err) => {
9636
9636
  this.ctx.logger.warn("ha-export: could not read broker audio mute, the broker-audio function degrades", {
9637
9637
  tags: { deviceId },
9638
9638
  meta: {
@@ -9683,7 +9683,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
9683
9683
  * reasoning.
9684
9684
  */
9685
9685
  async refreshBrokers() {
9686
- const haBrokers = await require_ha_instance_settings.listHomeAssistantBrokers((input) => this.ctx.api.broker.list.query(input));
9686
+ const haBrokers = await require_legacy_integration_rows.listHomeAssistantBrokers((input) => this.ctx.api.broker.list.query(input));
9687
9687
  /**
9688
9688
  * NEVER treat an empty enumeration as "the connections are gone".
9689
9689
  *
@@ -10064,7 +10064,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
10064
10064
  }
10065
10065
  switch (command.kind) {
10066
10066
  case "camera-function": {
10067
- const parsed = require_ha_instance_settings.CameraSwitchIdSchema.safeParse(command.switchId);
10067
+ const parsed = require_legacy_integration_rows.CameraSwitchIdSchema.safeParse(command.switchId);
10068
10068
  if (!parsed.success) {
10069
10069
  this.ctx.logger.warn("ha-export: dropping a command for an unknown camera function", {
10070
10070
  tags: { deviceId: command.deviceId },
@@ -10345,7 +10345,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
10345
10345
  */
10346
10346
  targetScope(instanceId) {
10347
10347
  if (instanceId === void 0) return this.enabledTargetIds();
10348
- if (!this.knownTargetIds().has(instanceId)) throw new require_ha_instance_settings.ExportInstanceUnknownError("provider-homeassistant", instanceId);
10348
+ if (!this.knownTargetIds().has(instanceId)) throw new require_legacy_integration_rows.ExportInstanceUnknownError("provider-homeassistant", instanceId);
10349
10349
  return [instanceId];
10350
10350
  }
10351
10351
  exposedDeviceRows(scope) {
@@ -1,4 +1,4 @@
1
- import { F as buildAddonRouteProvider, It as statusInstanceOf, Jt as BaseAddon, Ot as runExportedAction, Pt as sendToExportedTarget, Qt as baseUnitOf, Sn as EventCategory, U as consumableFormOf, W as consumableKindOf, X as deviceExportCapability, Zt as RevConflictError, _ as HvacModeSchema, _t as oauthIntegrationCapability, a as AlarmArmModeSchema, an as nodePin, bt as preconditionOf, c as CAMERA_SWITCH_ORDER, cn as boolean, ct as integrationInstancesCapability, d as ConsumableFormSchema, dn as number, en as defineAddonMigrations, f as ConsumableItemSchema, fn as object, g as FanDirectionSchema, gn as unknown, h as ExportInstanceUnknownError, i as listHomeAssistantBrokers, in as isReadingQuantity, l as COCO_TO_MACRO, mn as string, on as _enum, p as ConsumableStatusSchema, sn as array, t as haInstanceSettingsPortsOver, tn as defineEntryKind, u as CameraSwitchIdSchema, v as MediaPlayerRepeatSchema, w as addonRoutesCapability, wt as pruneDeletedEntities, x as RecordIntegrationInstances, y as PLUG_APPLIANCE_TYPES } from "../ha-instance-settings-qhCNJbbn.mjs";
1
+ import { F as buildAddonRouteProvider, It as statusInstanceOf, Jt as BaseAddon, Ot as runExportedAction, Pt as sendToExportedTarget, Qt as baseUnitOf, Sn as EventCategory, U as consumableFormOf, W as consumableKindOf, X as deviceExportCapability, Zt as RevConflictError, _ as HvacModeSchema, _t as oauthIntegrationCapability, a as AlarmArmModeSchema, an as nodePin, bt as preconditionOf, c as CAMERA_SWITCH_ORDER, cn as boolean, ct as integrationInstancesCapability, d as ConsumableFormSchema, dn as number, en as defineAddonMigrations, f as ConsumableItemSchema, fn as object, g as FanDirectionSchema, gn as unknown, h as ExportInstanceUnknownError, i as listHomeAssistantBrokers, in as isReadingQuantity, l as COCO_TO_MACRO, mn as string, on as _enum, p as ConsumableStatusSchema, sn as array, t as haInstanceSettingsPortsOver, tn as defineEntryKind, u as CameraSwitchIdSchema, v as MediaPlayerRepeatSchema, w as addonRoutesCapability, wt as pruneDeletedEntities, x as RecordIntegrationInstances, y as PLUG_APPLIANCE_TYPES } from "../legacy-integration-rows-BIbFoT26.mjs";
2
2
  import { createHmac, timingSafeEqual } from "node:crypto";
3
3
  import "node:zlib";
4
4
  import "node:fs";
@@ -11996,7 +11996,7 @@ object({
11996
11996
  params: record(string(), union([string(), number()])).optional()
11997
11997
  });
11998
11998
  //#endregion
11999
- //#region ../types/dist/composition-CRNwcFYY.mjs
11999
+ //#region ../types/dist/composition-pOHbTzRB.mjs
12000
12000
  /**
12001
12001
  * The ffmpeg build every CamStack node downloads, per platform and arch.
12002
12002
  *
@@ -50855,6 +50855,9 @@ var RunningProposalEvidenceSchema = object({
50855
50855
  runsFound: number().int().nonnegative(),
50856
50856
  pausesFound: number().int().nonnegative(),
50857
50857
  longestPauseMs: number().nonnegative(),
50858
+ /** Episodes shorter than ~90 s (an anti-crease pulse, a display waking): never a run, never a pause. */
50859
+ pulsesFound: number().int().nonnegative(),
50860
+ longestPulseMs: number().nonnegative(),
50858
50861
  idleFloorW: number(),
50859
50862
  noiseCeilingW: number(),
50860
50863
  plateauW: number(),
@@ -81310,11 +81313,15 @@ function runningFromMediaPlayer(state, previous, fetchedAt, transitionAt) {
81310
81313
  * 1. idle floor F = time-weighted median; noise ceiling N = highest value seen
81311
81314
  * near F. A device that is not near one level most of the time has no floor.
81312
81315
  * 2. coarse activity = above max(2N, N + 5 W); consecutive stretches are episodes.
81313
- * 3. gaps between episodes split in two by the largest log-scale jump (>= 3x):
81314
- * the short ones are pauses INSIDE a run (a soak), the long ones separate runs.
81316
+ * 3. an episode shorter than `PULSE_MAX_MS` is a PULSE (an anti-crease tumble, a
81317
+ * display waking): it is neither a run nor a pause. Among the remaining
81318
+ * episodes, gaps over `PAUSE_MAX_MS` always separate runs; the rest split in
81319
+ * two by the largest log-scale jump (>= 3x): the short ones are pauses INSIDE
81320
+ * a run (a soak), the long ones separate runs. A stretch under `MIN_RUN_MS`
81321
+ * is no run.
81315
81322
  * 4. T = geometric mean of N and the plateau's 10th percentile, snapped to a
81316
- * grid a person would type; stop dwell covers the longest pause; start dwell
81317
- * covers the longest standby blip above T.
81323
+ * grid a person would type; stop dwell covers the longest pause and the
81324
+ * kind's floor; start dwell covers the longest pulse and standby blip above T.
81318
81325
  * 5. the numbers are proved by REPLAY through the real `dwell` evaluation: each
81319
81326
  * run must hold exactly one true interval and nothing may flap outside.
81320
81327
  */
@@ -81325,6 +81332,10 @@ var MINUTE_MS$1 = 60 * SECOND_MS;
81325
81332
  30 * SECOND_MS;
81326
81333
  60 * SECOND_MS;
81327
81334
  20 * MINUTE_MS$1;
81335
+ 90 * SECOND_MS;
81336
+ 30 * MINUTE_MS$1;
81337
+ 10 * MINUTE_MS$1;
81338
+ DeviceType.Dryer, 3 * MINUTE_MS$1, DeviceType.Dishwasher, 3 * MINUTE_MS$1, DeviceType.Washer, 10 * MINUTE_MS$1;
81328
81339
  10 * SECOND_MS;
81329
81340
  10 * SECOND_MS;
81330
81341
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverStoppable, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
@@ -98417,6 +98428,17 @@ function haInstanceSettingsPortsOver(api) {
98417
98428
  skipRestart: true
98418
98429
  });
98419
98430
  return true;
98431
+ },
98432
+ clearInstanceSettingsKeys: async (integrationId, keys) => {
98433
+ if (!(await api.list.query()).some((i) => i.id === integrationId && i.addonId === "provider-homeassistant")) return false;
98434
+ const stored = await api.getSettings.query({ id: integrationId });
98435
+ const drop = new Set(keys);
98436
+ await api.setSettings.mutate({
98437
+ id: integrationId,
98438
+ settings: Object.fromEntries(Object.entries(stored).filter(([key]) => !drop.has(key))),
98439
+ skipRestart: true
98440
+ });
98441
+ return true;
98420
98442
  }
98421
98443
  };
98422
98444
  }
@@ -11997,7 +11997,7 @@ object({
11997
11997
  params: record(string(), union([string(), number()])).optional()
11998
11998
  });
11999
11999
  //#endregion
12000
- //#region ../types/dist/composition-CRNwcFYY.mjs
12000
+ //#region ../types/dist/composition-pOHbTzRB.mjs
12001
12001
  /**
12002
12002
  * The ffmpeg build every CamStack node downloads, per platform and arch.
12003
12003
  *
@@ -50856,6 +50856,9 @@ var RunningProposalEvidenceSchema = object({
50856
50856
  runsFound: number().int().nonnegative(),
50857
50857
  pausesFound: number().int().nonnegative(),
50858
50858
  longestPauseMs: number().nonnegative(),
50859
+ /** Episodes shorter than ~90 s (an anti-crease pulse, a display waking): never a run, never a pause. */
50860
+ pulsesFound: number().int().nonnegative(),
50861
+ longestPulseMs: number().nonnegative(),
50859
50862
  idleFloorW: number(),
50860
50863
  noiseCeilingW: number(),
50861
50864
  plateauW: number(),
@@ -81311,11 +81314,15 @@ function runningFromMediaPlayer(state, previous, fetchedAt, transitionAt) {
81311
81314
  * 1. idle floor F = time-weighted median; noise ceiling N = highest value seen
81312
81315
  * near F. A device that is not near one level most of the time has no floor.
81313
81316
  * 2. coarse activity = above max(2N, N + 5 W); consecutive stretches are episodes.
81314
- * 3. gaps between episodes split in two by the largest log-scale jump (>= 3x):
81315
- * the short ones are pauses INSIDE a run (a soak), the long ones separate runs.
81317
+ * 3. an episode shorter than `PULSE_MAX_MS` is a PULSE (an anti-crease tumble, a
81318
+ * display waking): it is neither a run nor a pause. Among the remaining
81319
+ * episodes, gaps over `PAUSE_MAX_MS` always separate runs; the rest split in
81320
+ * two by the largest log-scale jump (>= 3x): the short ones are pauses INSIDE
81321
+ * a run (a soak), the long ones separate runs. A stretch under `MIN_RUN_MS`
81322
+ * is no run.
81316
81323
  * 4. T = geometric mean of N and the plateau's 10th percentile, snapped to a
81317
- * grid a person would type; stop dwell covers the longest pause; start dwell
81318
- * covers the longest standby blip above T.
81324
+ * grid a person would type; stop dwell covers the longest pause and the
81325
+ * kind's floor; start dwell covers the longest pulse and standby blip above T.
81319
81326
  * 5. the numbers are proved by REPLAY through the real `dwell` evaluation: each
81320
81327
  * run must hold exactly one true interval and nothing may flap outside.
81321
81328
  */
@@ -81326,6 +81333,10 @@ var MINUTE_MS$1 = 60 * SECOND_MS;
81326
81333
  30 * SECOND_MS;
81327
81334
  60 * SECOND_MS;
81328
81335
  20 * MINUTE_MS$1;
81336
+ 90 * SECOND_MS;
81337
+ 30 * MINUTE_MS$1;
81338
+ 10 * MINUTE_MS$1;
81339
+ DeviceType.Dryer, 3 * MINUTE_MS$1, DeviceType.Dishwasher, 3 * MINUTE_MS$1, DeviceType.Washer, 10 * MINUTE_MS$1;
81329
81340
  10 * SECOND_MS;
81330
81341
  10 * SECOND_MS;
81331
81342
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverStoppable, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
@@ -98418,6 +98429,17 @@ function haInstanceSettingsPortsOver(api) {
98418
98429
  skipRestart: true
98419
98430
  });
98420
98431
  return true;
98432
+ },
98433
+ clearInstanceSettingsKeys: async (integrationId, keys) => {
98434
+ if (!(await api.list.query()).some((i) => i.id === integrationId && i.addonId === "provider-homeassistant")) return false;
98435
+ const stored = await api.getSettings.query({ id: integrationId });
98436
+ const drop = new Set(keys);
98437
+ await api.setSettings.mutate({
98438
+ id: integrationId,
98439
+ settings: Object.fromEntries(Object.entries(stored).filter(([key]) => !drop.has(key))),
98440
+ skipRestart: true
98441
+ });
98442
+ return true;
98421
98443
  }
98422
98444
  };
98423
98445
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.2.659",
3
+ "version": "1.2.660",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",
@@ -137,7 +137,7 @@
137
137
  "description": "Device provider (import) + native entity export (push). Two addons, one bundle, separate processes."
138
138
  },
139
139
  "requires": {
140
- "server": ">=1.2.768"
140
+ "server": ">=1.2.769"
141
141
  }
142
142
  },
143
143
  "files": [