@camstack/addon-provider-homeassistant 1.2.647 → 1.2.649

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.
@@ -5971,7 +5971,7 @@ var ZodIssueCode = {
5971
5971
  var ZodFirstPartyTypeKind;
5972
5972
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5973
5973
  //#endregion
5974
- //#region ../types/dist/sleep-B-vp7x15.mjs
5974
+ //#region ../types/dist/sleep-CdJHPm-k.mjs
5975
5975
  /**
5976
5976
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5977
5977
  * window to float samples (D455).
@@ -6088,7 +6088,7 @@ function isKeychainStoredField(field) {
6088
6088
  var SECRET_CLEAR = { $secretClear: true };
6089
6089
  /** The `'***'` token D634 redaction writes for non-admins. */
6090
6090
  var LEGACY_DEVICE_REDACTION = "***";
6091
- function isRecord$6(value) {
6091
+ function isRecord$7(value) {
6092
6092
  return typeof value === "object" && value !== null && !Array.isArray(value);
6093
6093
  }
6094
6094
  function makeSecretMarker(ref) {
@@ -6099,12 +6099,12 @@ function makeSecretMarker(ref) {
6099
6099
  }
6100
6100
  /** A stored marker: an object whose `$secret` is a non-empty string. */
6101
6101
  function isSecretMarker(value) {
6102
- if (!isRecord$6(value)) return false;
6102
+ if (!isRecord$7(value)) return false;
6103
6103
  const ref = value["$secret"];
6104
6104
  return typeof ref === "string" && ref.length > 0;
6105
6105
  }
6106
6106
  function isSecretClear(value) {
6107
- return isRecord$6(value) && value["$secretClear"] === true;
6107
+ return isRecord$7(value) && value["$secretClear"] === true;
6108
6108
  }
6109
6109
  /**
6110
6110
  * The UI view of a stored secret field value: a marker becomes "set", inline
@@ -6487,6 +6487,53 @@ function emitReadiness(bus, params) {
6487
6487
  ts
6488
6488
  }));
6489
6489
  }
6490
+ /** Why a catalogue entry is not a runnable body of its declared kind. */
6491
+ var AddonMigrationDefinitionError = class extends Error {
6492
+ id;
6493
+ constructor(id, message) {
6494
+ super(`${id}: ${message}`);
6495
+ this.id = id;
6496
+ this.name = "AddonMigrationDefinitionError";
6497
+ }
6498
+ };
6499
+ /**
6500
+ * Bind a catalogue to the addon's ports. Throws {@link AddonMigrationDefinitionError} when
6501
+ * an entry's `bodyKind` does not match the body it carries, or is `sql` (a hub-only
6502
+ * body). A throwing body never escapes `execute`: it is reported as a failed result.
6503
+ */
6504
+ function defineAddonMigrations(catalogue, ports) {
6505
+ return catalogue.map((entry) => {
6506
+ const { meta } = entry;
6507
+ if ("plan" in entry) {
6508
+ if (meta.bodyKind !== "plan") throw new AddonMigrationDefinitionError(meta.id, `carries a plan body but declares "${meta.bodyKind}"`);
6509
+ return {
6510
+ meta,
6511
+ execute: () => guarded(async () => ({
6512
+ kind: "plan",
6513
+ plan: await entry.plan(ports)
6514
+ }))
6515
+ };
6516
+ }
6517
+ if (meta.bodyKind !== "procedure") throw new AddonMigrationDefinitionError(meta.id, `carries a procedure body but declares "${meta.bodyKind}"`);
6518
+ return {
6519
+ meta,
6520
+ execute: () => guarded(async () => ({
6521
+ kind: "procedure",
6522
+ result: await entry.procedure(ports)
6523
+ }))
6524
+ };
6525
+ });
6526
+ }
6527
+ async function guarded(work) {
6528
+ try {
6529
+ return await work();
6530
+ } catch (err) {
6531
+ return {
6532
+ kind: "failed",
6533
+ error: errMsg(err)
6534
+ };
6535
+ }
6536
+ }
6490
6537
  var NOT_RUN = {
6491
6538
  declared: false,
6492
6539
  snapshot: null,
@@ -6810,7 +6857,7 @@ var KeychainWriteRefusedError = class extends Error {
6810
6857
  }
6811
6858
  };
6812
6859
  var KEEP = { kind: "keep" };
6813
- function isRecord$5(value) {
6860
+ function isRecord$6(value) {
6814
6861
  return typeof value === "object" && value !== null && !Array.isArray(value);
6815
6862
  }
6816
6863
  function defaultMintId() {
@@ -6823,7 +6870,7 @@ function collectSecretMarkerRefs(value, out = []) {
6823
6870
  return out;
6824
6871
  }
6825
6872
  if (Array.isArray(value)) for (const item of value) collectSecretMarkerRefs(item, out);
6826
- else if (isRecord$5(value)) for (const child of Object.values(value)) collectSecretMarkerRefs(child, out);
6873
+ else if (isRecord$6(value)) for (const child of Object.values(value)) collectSecretMarkerRefs(child, out);
6827
6874
  return out;
6828
6875
  }
6829
6876
  async function storedValueEquals(secrets, marker, candidate) {
@@ -6878,7 +6925,7 @@ function rowId(row, idKey) {
6878
6925
  return null;
6879
6926
  }
6880
6927
  async function writeArray(ctx, node, incoming, stored, fieldPath) {
6881
- const storedRows = Array.isArray(stored) ? stored.filter(isRecord$5) : [];
6928
+ const storedRows = Array.isArray(stored) ? stored.filter(isRecord$6) : [];
6882
6929
  if (!Array.isArray(incoming)) {
6883
6930
  ctx.deletes.push(...collectSecretMarkerRefs(storedRows));
6884
6931
  return {
@@ -6894,7 +6941,7 @@ async function writeArray(ctx, node, incoming, stored, fieldPath) {
6894
6941
  const kept = /* @__PURE__ */ new Set();
6895
6942
  const rows = [];
6896
6943
  for (const row of incoming) {
6897
- if (!isRecord$5(row)) {
6944
+ if (!isRecord$6(row)) {
6898
6945
  rows.push(row);
6899
6946
  continue;
6900
6947
  }
@@ -6919,7 +6966,7 @@ async function writeNode(ctx, node, incoming, stored, fieldPath) {
6919
6966
  case "leaf": return writeLeaf(ctx, incoming, stored, fieldPath);
6920
6967
  case "array": return writeArray(ctx, node, incoming, stored, fieldPath);
6921
6968
  case "object": {
6922
- if (!isRecord$5(incoming)) {
6969
+ if (!isRecord$6(incoming)) {
6923
6970
  if (incoming === void 0) return KEEP;
6924
6971
  ctx.deletes.push(...collectSecretMarkerRefs(stored));
6925
6972
  return {
@@ -6927,7 +6974,7 @@ async function writeNode(ctx, node, incoming, stored, fieldPath) {
6927
6974
  value: incoming
6928
6975
  };
6929
6976
  }
6930
- const storedObj = isRecord$5(stored) ? stored : {};
6977
+ const storedObj = isRecord$6(stored) ? stored : {};
6931
6978
  return {
6932
6979
  kind: "value",
6933
6980
  value: await writeMembers(ctx, node.children, incoming, storedObj, (m) => `${fieldPath}.${m}`)
@@ -7050,7 +7097,7 @@ async function resolveSecretMarkers(value, secrets, options = {}) {
7050
7097
  value: items
7051
7098
  };
7052
7099
  }
7053
- if (isRecord$5(v)) {
7100
+ if (isRecord$6(v)) {
7054
7101
  const out = {};
7055
7102
  for (const [k, child] of Object.entries(v)) {
7056
7103
  const s = substitute(child);
@@ -7082,7 +7129,7 @@ var SecretOverwriteRefusedError = class extends Error {
7082
7129
  this.name = "SecretOverwriteRefusedError";
7083
7130
  }
7084
7131
  };
7085
- function isRecord$4(value) {
7132
+ function isRecord$5(value) {
7086
7133
  return typeof value === "object" && value !== null && !Array.isArray(value);
7087
7134
  }
7088
7135
  function resolvedValue(pass, marker) {
@@ -7111,7 +7158,7 @@ function inArray(pass, incoming, stored) {
7111
7158
  return incoming.map((item, index) => {
7112
7159
  const twin = stored[index];
7113
7160
  if (isSecretMarker(twin)) return typeof item === "string" && item === resolvedValue(pass, twin) ? twin : item;
7114
- if (isRecord$4(item) && isRecord$4(twin)) return inArrayRow(pass, item, twin);
7161
+ if (isRecord$5(item) && isRecord$5(twin)) return inArrayRow(pass, item, twin);
7115
7162
  if (Array.isArray(item) && Array.isArray(twin)) return inArray(pass, item, twin);
7116
7163
  return item;
7117
7164
  });
@@ -7122,7 +7169,7 @@ function inArrayRow(pass, incoming, stored) {
7122
7169
  const twin = stored[key];
7123
7170
  if (isSecretMarker(twin)) {
7124
7171
  if (typeof value === "string" && value === resolvedValue(pass, twin)) out[key] = twin;
7125
- } else if (isRecord$4(value) && isRecord$4(twin)) out[key] = inArrayRow(pass, value, twin);
7172
+ } else if (isRecord$5(value) && isRecord$5(twin)) out[key] = inArrayRow(pass, value, twin);
7126
7173
  else if (Array.isArray(value) && Array.isArray(twin)) out[key] = inArray(pass, value, twin);
7127
7174
  }
7128
7175
  return out;
@@ -7130,7 +7177,7 @@ function inArrayRow(pass, incoming, stored) {
7130
7177
  async function walk(pass, incoming, stored) {
7131
7178
  if (isSecretMarker(stored)) return atMarker(pass, incoming, stored);
7132
7179
  if (Array.isArray(incoming) && Array.isArray(stored)) return inArray(pass, incoming, stored);
7133
- if (!isRecord$4(incoming) || !isRecord$4(stored)) return incoming;
7180
+ if (!isRecord$5(incoming) || !isRecord$5(stored)) return incoming;
7134
7181
  const out = { ...incoming };
7135
7182
  for (const [key, value] of Object.entries(incoming)) out[key] = await walk(pass, value, stored[key]);
7136
7183
  return out;
@@ -7161,7 +7208,7 @@ async function restoreUnchangedSecrets(input) {
7161
7208
  function isJsonEqual(a, b) {
7162
7209
  if (Object.is(a, b)) return true;
7163
7210
  if (Array.isArray(a)) return Array.isArray(b) && a.length === b.length && a.every((v, i) => isJsonEqual(v, b[i]));
7164
- if (isRecord$4(a) && isRecord$4(b)) {
7211
+ if (isRecord$5(a) && isRecord$5(b)) {
7165
7212
  const keys = Object.keys(a);
7166
7213
  if (keys.length !== Object.keys(b).length) return false;
7167
7214
  return keys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && isJsonEqual(a[k], b[k]));
@@ -7185,7 +7232,7 @@ function markerKeysOf(blob, owner) {
7185
7232
  }
7186
7233
  function nodeFromStored(value, owner) {
7187
7234
  if (isSecretMarker(value)) return isSecretRefOwnedBy(value.$secret, owner) ? { kind: "leaf" } : null;
7188
- if (!isRecord$4(value)) return null;
7235
+ if (!isRecord$5(value)) return null;
7189
7236
  const children = /* @__PURE__ */ new Map();
7190
7237
  for (const [key, child] of Object.entries(value)) {
7191
7238
  const node = nodeFromStored(child, owner);
@@ -7804,6 +7851,44 @@ var BaseAddon = class {
7804
7851
  return null;
7805
7852
  }
7806
7853
  /**
7854
+ * D986 scoped settings: the form shape of the CLUSTER-wide settings one capability this addon
7855
+ * provides owns, or `null` when it has none. `cap` is a capability name the addon's manifest
7856
+ * declares. Stored as `addon-settings` rows `<addonId>.<field>`. The keys of this schema, of
7857
+ * {@link nodeSettingsSchema} and of {@link deviceDefaultsSchema} are disjoint, and a key never
7858
+ * contains `@` (guard `check-scoped-settings-declared`). SHAPE only: values are read by scope.
7859
+ */
7860
+ async clusterSettingsSchema(_cap) {
7861
+ return null;
7862
+ }
7863
+ /**
7864
+ * D986: the form shape of the settings one capability owns PER NODE, or `null`. Stored as
7865
+ * `addon-settings` rows `<addonId>.<field>@<nodeId>` carrying `nodeId` in the row data, so a
7866
+ * forgotten node's rows go in one central delete.
7867
+ */
7868
+ async nodeSettingsSchema(_cap) {
7869
+ return null;
7870
+ }
7871
+ /**
7872
+ * D986: the form shape of the FLEET DEFAULTS of the per-device settings one capability owns,
7873
+ * or `null`. Stored as `addon-settings` rows `<addonId>.<field>`; a device resolves its value
7874
+ * as device row, then this default, then the schema default (`resolveDeviceSettings`).
7875
+ */
7876
+ async deviceDefaultsSchema(_cap) {
7877
+ return null;
7878
+ }
7879
+ /**
7880
+ * The host's read of the scoped declarations: the schema one capability declares for `scope`,
7881
+ * or `null`. Beside {@link getIntegrationFormSchema}, the same shape: the hook is protected, the
7882
+ * host asks this method.
7883
+ */
7884
+ async getScopedSettingsSchema(scope, cap) {
7885
+ switch (scope) {
7886
+ case "cluster": return this.clusterSettingsSchema(cap);
7887
+ case "node": return this.nodeSettingsSchema(cap);
7888
+ case "device-defaults": return this.deviceDefaultsSchema(cap);
7889
+ }
7890
+ }
7891
+ /**
7807
7892
  * What the create wizard and the integration edit page render for one instance: the addon's
7808
7893
  * per-instance schema when it declares one, else its global schema (what they always showed).
7809
7894
  */
@@ -8597,47 +8682,6 @@ function normalizeAddonInitResult(result) {
8597
8682
  if (Array.isArray(result)) return { providers: result };
8598
8683
  return result;
8599
8684
  }
8600
- /**
8601
- * The share-view scope kinds a share-link token can carry. The hub mints
8602
- * and validates them (`ShareViewGrantSchema` builds its
8603
- * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
8604
- */
8605
- var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
8606
- /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
8607
- var PeerBytesTicketSchema = object({
8608
- /** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
8609
- url: string().min(1),
8610
- /**
8611
- * The HOST node this URL means something on — the hub or a named agent,
8612
- * never a runner. {@link AddonPeerBytes.open} compares it to its own and
8613
- * refuses `cross-node` by name when they differ, without dialling.
8614
- */
8615
- hostNodeId: string().min(1),
8616
- expiresAtMs: number().int().nonnegative(),
8617
- /**
8618
- * What the producer DECLARED the body to be, when it knows — `null` when it
8619
- * does not. Never `0` for unknown (D393): a consumer sizing a bound off this
8620
- * must be able to tell "the producer did not say" from "the body is empty".
8621
- */
8622
- declaredBytes: number().int().nonnegative().nullable()
8623
- });
8624
- /** Limits and names of `ctx.records` (D881). One authority; the engine and the facade read it. */
8625
- /** The files a kind may live in. `history` is device-history's (D850), never records. */
8626
- var RECORD_DATABASES = ["settings", "events"];
8627
- /** The classes of a kind: the `@durable` vocabulary, one authority (replaces the annotation). */
8628
- var RECORD_CLASSES = [
8629
- "config",
8630
- "ledger",
8631
- "audit",
8632
- "mirror",
8633
- "ephemeral"
8634
- ];
8635
- var RECORD_DEFAULT_MAX_DATA_BYTES = 64 * 1024;
8636
- var RECORD_MAX_DATA_BYTES = 1024 * 1024;
8637
- var RECORD_BATCH_MAX = 1e3;
8638
- var RECORD_QUERY_MAX = 1e3;
8639
- /** A kind in the `settings` file may not bound itself above this (D447: high volume is `events`). */
8640
- var RECORD_SETTINGS_MAX_ROWS = 5e4;
8641
8685
  var PREFIX = "records/";
8642
8686
  /** The base of every records failure. `detail` is the human part of the message. */
8643
8687
  var RecordsError = class extends Error {
@@ -8670,6 +8714,83 @@ var DeclarationRefusedError = class extends RecordsError {
8670
8714
  this.name = "DeclarationRefusedError";
8671
8715
  }
8672
8716
  };
8717
+ /** Limits and names of `ctx.records` (D881). One authority; the engine and the facade read it. */
8718
+ /** The files a kind may live in. `history` is device-history's (D850), never records. */
8719
+ var RECORD_DATABASES = ["settings", "events"];
8720
+ /** The classes of a kind: the `@durable` vocabulary, one authority (replaces the annotation). */
8721
+ var RECORD_CLASSES = [
8722
+ "config",
8723
+ "ledger",
8724
+ "audit",
8725
+ "mirror",
8726
+ "ephemeral"
8727
+ ];
8728
+ var RECORD_DEFAULT_MAX_DATA_BYTES = 64 * 1024;
8729
+ var RECORD_MAX_DATA_BYTES = 1024 * 1024;
8730
+ var RECORD_BATCH_MAX = 1e3;
8731
+ var RECORD_QUERY_MAX = 1e3;
8732
+ /** A kind in the `settings` file may not bound itself above this (D447: high volume is `events`). */
8733
+ var RECORD_SETTINGS_MAX_ROWS = 5e4;
8734
+ /**
8735
+ * Secret fields of a record, addressed the way a Zod schema declares them
8736
+ * (`collectZodSecretPaths`): dotted keys, `[]` for "each element of this array"
8737
+ * (`auth.accessToken`, `headers[].value`).
8738
+ *
8739
+ * Array elements are matched by a DECLARED id key (`secretArrayKeys`:
8740
+ * `{ headers: 'name' }`), never by index, so reordering a list keeps every
8741
+ * keychain ref (the same rule as `arrayItemFieldPath`). The concrete path of a
8742
+ * leaf names its element: `headers[X-Api].value`.
8743
+ *
8744
+ * Pure and browser-safe. Nothing here mutates: every transform returns a new value.
8745
+ */
8746
+ /** The array prefixes (declared form, e.g. `headers` or `a.headers`) of a path. */
8747
+ function parseSecretPath(path) {
8748
+ if (path.length === 0) throw new InvalidRecordError("an empty secret path");
8749
+ return path.split(".").map((raw) => {
8750
+ const each = raw.endsWith("[]");
8751
+ const key = each ? raw.slice(0, -2) : raw;
8752
+ if (key.length === 0) throw new InvalidRecordError(`secret path "${path}" has an empty segment`);
8753
+ return {
8754
+ key,
8755
+ each
8756
+ };
8757
+ });
8758
+ }
8759
+ /** The declared array prefixes of `path` that need an id key (`headers`, `a.rows`). */
8760
+ function secretArrayPrefixes(path) {
8761
+ const segments = parseSecretPath(path);
8762
+ const prefixes = [];
8763
+ const walked = [];
8764
+ for (const segment of segments) {
8765
+ walked.push(segment.key);
8766
+ if (segment.each) prefixes.push(walked.join("."));
8767
+ }
8768
+ return prefixes;
8769
+ }
8770
+ /**
8771
+ * The share-view scope kinds a share-link token can carry. The hub mints
8772
+ * and validates them (`ShareViewGrantSchema` builds its
8773
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
8774
+ */
8775
+ var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
8776
+ /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
8777
+ var PeerBytesTicketSchema = object({
8778
+ /** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
8779
+ url: string().min(1),
8780
+ /**
8781
+ * The HOST node this URL means something on — the hub or a named agent,
8782
+ * never a runner. {@link AddonPeerBytes.open} compares it to its own and
8783
+ * refuses `cross-node` by name when they differ, without dialling.
8784
+ */
8785
+ hostNodeId: string().min(1),
8786
+ expiresAtMs: number().int().nonnegative(),
8787
+ /**
8788
+ * What the producer DECLARED the body to be, when it knows — `null` when it
8789
+ * does not. Never `0` for unknown (D393): a consumer sizing a bound off this
8790
+ * must be able to tell "the producer did not say" from "the body is empty".
8791
+ */
8792
+ declaredBytes: number().int().nonnegative().nullable()
8793
+ });
8673
8794
  function defOf(schema) {
8674
8795
  const zodBag = Reflect.get(schema, "_zod");
8675
8796
  if (typeof zodBag !== "object" || zodBag === null) return {};
@@ -8738,42 +8859,6 @@ function collectZodSecretPaths(schema, prefix = "") {
8738
8859
  return [...new Set(paths)];
8739
8860
  }
8740
8861
  /**
8741
- * Secret fields of a record, addressed the way a Zod schema declares them
8742
- * (`collectZodSecretPaths`): dotted keys, `[]` for "each element of this array"
8743
- * (`auth.accessToken`, `headers[].value`).
8744
- *
8745
- * Array elements are matched by a DECLARED id key (`secretArrayKeys`:
8746
- * `{ headers: 'name' }`), never by index, so reordering a list keeps every
8747
- * keychain ref (the same rule as `arrayItemFieldPath`). The concrete path of a
8748
- * leaf names its element: `headers[X-Api].value`.
8749
- *
8750
- * Pure and browser-safe. Nothing here mutates: every transform returns a new value.
8751
- */
8752
- /** The array prefixes (declared form, e.g. `headers` or `a.headers`) of a path. */
8753
- function parseSecretPath(path) {
8754
- if (path.length === 0) throw new InvalidRecordError("an empty secret path");
8755
- return path.split(".").map((raw) => {
8756
- const each = raw.endsWith("[]");
8757
- const key = each ? raw.slice(0, -2) : raw;
8758
- if (key.length === 0) throw new InvalidRecordError(`secret path "${path}" has an empty segment`);
8759
- return {
8760
- key,
8761
- each
8762
- };
8763
- });
8764
- }
8765
- /** The declared array prefixes of `path` that need an id key (`headers`, `a.rows`). */
8766
- function secretArrayPrefixes(path) {
8767
- const segments = parseSecretPath(path);
8768
- const prefixes = [];
8769
- const walked = [];
8770
- for (const segment of segments) {
8771
- walked.push(segment.key);
8772
- if (segment.each) prefixes.push(walked.join("."));
8773
- }
8774
- return prefixes;
8775
- }
8776
- /**
8777
8862
  * Record kinds (D881): the declaration an addon makes of one kind of fact, the
8778
8863
  * Zod row schema that describes it, and the helper that turns the two into the
8779
8864
  * JSON the engine stores.
@@ -9738,6 +9823,7 @@ var CAP_NAMES = Object.freeze([
9738
9823
  "humidity-sensor",
9739
9824
  "image",
9740
9825
  "image-settings",
9826
+ "integration-instances",
9741
9827
  "integrations",
9742
9828
  "intercom",
9743
9829
  "ir-transmitter",
@@ -11671,7 +11757,7 @@ object({
11671
11757
  params: record(string(), union([string(), number()])).optional()
11672
11758
  });
11673
11759
  //#endregion
11674
- //#region ../types/dist/composition-kKKOdFIG.mjs
11760
+ //#region ../types/dist/composition-BDUoQsw9.mjs
11675
11761
  /**
11676
11762
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11677
11763
  *
@@ -14123,6 +14209,16 @@ var MigrationPlanSchema = object({ edits: array(discriminatedUnion("op", [
14123
14209
  precondition: PreconditionSchema
14124
14210
  })
14125
14211
  ])) });
14212
+ /** `JSON.stringify` with object keys sorted, so equal values spell the same. */
14213
+ function canonicalJson(value) {
14214
+ if (Array.isArray(value)) return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
14215
+ if (typeof value === "object" && value !== null) return `{${Object.entries(value).filter(([, item]) => item !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => `${JSON.stringify(key)}:${canonicalJson(item)}`).join(",")}}`;
14216
+ return JSON.stringify(value) ?? "null";
14217
+ }
14218
+ /** The precondition string for a value a plan read (`null` when it read nothing). */
14219
+ function preconditionOf(value) {
14220
+ return canonicalJson(value ?? null);
14221
+ }
14126
14222
  /**
14127
14223
  * What a `procedure` body reports. `already-done` means the rerun observed the
14128
14224
  * work finished (a crash between the work and the ledger row, or a manual fix)
@@ -16071,8 +16167,18 @@ var LogChannelDescriptorSchema = object({
16071
16167
  * the operator narrows to one camera, sees nothing, and concludes the code
16072
16168
  * path was never taken.
16073
16169
  */
16074
- perDevice: boolean()
16075
- });
16170
+ perDevice: boolean(),
16171
+ /**
16172
+ * What the channel is FOR, so the UI can list the channels an addon offers.
16173
+ *
16174
+ * - `diagnostic` (the default): a per-component diagnostic armed from the
16175
+ * Levels page, emitted at its declared level.
16176
+ * - `debug`: a `debug.<channel>` dump watched live for a short window
16177
+ * (`ctx.debug`). Always per-device, and its lines are denied by the log
16178
+ * ring unless somebody is watching that device.
16179
+ */
16180
+ kind: _enum(["diagnostic", "debug"]).default("diagnostic")
16181
+ }).refine((d) => d.kind !== "debug" || d.name.startsWith("debug.") && d.perDevice, { message: "a debug channel is named debug.<channel> and is per-device" });
16076
16182
  /**
16077
16183
  * An armed window over one channel, as the document hands it to a mirror.
16078
16184
  *
@@ -21288,6 +21394,7 @@ var SYSTEM_CAP_VOCABULARY = {
21288
21394
  "load-contribution": system(INTERNAL),
21289
21395
  "local-network": system(NETWORK),
21290
21396
  "log-channels": system(INTERNAL),
21397
+ "integration-instances": system(INTERNAL),
21291
21398
  "log-destination": system(INTERNAL),
21292
21399
  "login-method": system(IDENTITY),
21293
21400
  "mesh-network": system(NETWORK),
@@ -43588,7 +43695,7 @@ var TargetKindCapsSchema = object({
43588
43695
  * the union is large and not meant for runtime validation here; the exported
43589
43696
  * `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
43590
43697
  */
43591
- var ConfigSchemaPassthrough$3 = unknown();
43698
+ var ConfigSchemaPassthrough$4 = unknown();
43592
43699
  var TargetKindSchema = object({
43593
43700
  kind: string(),
43594
43701
  label: string(),
@@ -43625,7 +43732,7 @@ var TargetKindSchema = object({
43625
43732
  * its raster path, which is the safe default for an unknown image.
43626
43733
  */
43627
43734
  iconMediaType: string().optional(),
43628
- configSchema: ConfigSchemaPassthrough$3,
43735
+ configSchema: ConfigSchemaPassthrough$4,
43629
43736
  /**
43630
43737
  * The config keys that decide WHERE this kind's secrets are sent (server,
43631
43738
  * base URL, instance, chat, recipient). A save that changes any of them
@@ -51614,6 +51721,45 @@ var deviceProviderCapability = {
51614
51721
  }
51615
51722
  };
51616
51723
  /**
51724
+ * What the passive listener of `local-network` saw on the wire, before any
51725
+ * provider classified it. Device-manager turns an observation into the hits
51726
+ * of the providers whose declared discovery modes it matches.
51727
+ */
51728
+ var DiscoveryObservationSchema = discriminatedUnion("kind", [object({
51729
+ kind: literal("mdns"),
51730
+ /** Normalised DNS-SD service type, e.g. `_esphomelib._tcp`. */
51731
+ serviceType: string(),
51732
+ instance: string(),
51733
+ host: string(),
51734
+ /** The A record address when the announcement carried one. */
51735
+ address: string().nullable(),
51736
+ port: number().int(),
51737
+ txt: record(string(), string())
51738
+ }), object({
51739
+ kind: literal("ssdp"),
51740
+ /** Sender address of the datagram. */
51741
+ host: string(),
51742
+ port: number().int(),
51743
+ /** `NT` of a NOTIFY, `ST` of a search response. */
51744
+ target: string(),
51745
+ headers: record(string(), string())
51746
+ })]);
51747
+ object({
51748
+ addonId: string(),
51749
+ candidate: DiscoveryCandidateSchema,
51750
+ firstSeenAt: number(),
51751
+ lastSeenAt: number(),
51752
+ dismissed: boolean()
51753
+ });
51754
+ var DiscoveryProposalSchema = object({
51755
+ id: string(),
51756
+ addonId: string(),
51757
+ candidate: DiscoveryCandidateSchema,
51758
+ firstSeenAt: number(),
51759
+ lastSeenAt: number(),
51760
+ dismissed: boolean()
51761
+ });
51762
+ /**
51617
51763
  * Device Manager capability — hub-side singleton that unifies device persistence,
51618
51764
  * live registry access, and all management operations into a single tRPC surface.
51619
51765
  *
@@ -52342,6 +52488,19 @@ method(object({
52342
52488
  }), object({ candidates: array(DiscoveryCandidateSchema).readonly() }), {
52343
52489
  kind: "mutation",
52344
52490
  auth: "admin"
52491
+ }), method(object({}), object({ proposals: array(DiscoveryProposalSchema).readonly() }), { auth: "admin" }), method(object({ id: string() }), object({ dismissed: boolean() }), {
52492
+ kind: "mutation",
52493
+ auth: "admin"
52494
+ }), method(object({ observations: array(DiscoveryObservationSchema).max(512) }), object({ proposed: number().int() }), {
52495
+ kind: "mutation",
52496
+ auth: "admin"
52497
+ }), method(object({}), object({
52498
+ providers: number().int(),
52499
+ proposed: number().int()
52500
+ }), {
52501
+ kind: "mutation",
52502
+ auth: "admin",
52503
+ timeoutMs: 12e4
52345
52504
  }), method(object({ addonId: string() }), object({ deviceType: _enum(DeviceType).nullable() }), { auth: "admin" }), method(object({ addonId: string() }), unknown(), { auth: "admin" }), method(object({
52346
52505
  deviceId: number(),
52347
52506
  key: string(),
@@ -55581,9 +55740,15 @@ var AvailableIntegrationTypeSchema = object({
55581
55740
  * branch on CAP — never on addon name. `device-adoption` integrations
55582
55741
  * (Home Assistant, …) route through the broker step (Approach A);
55583
55742
  * `device-provider` integrations (Reolink/ONVIF) keep the
55584
- * legacy config → discovery flow.
55743
+ * legacy config → discovery flow. `connection` is an addon that only holds a
55744
+ * connection as typed records (`integration-instances`, D985): no devices,
55745
+ * no discovery.
55585
55746
  */
55586
- kind: _enum(["device-adoption", "device-provider"]),
55747
+ kind: _enum([
55748
+ "device-adoption",
55749
+ "device-provider",
55750
+ "connection"
55751
+ ]),
55587
55752
  /**
55588
55753
  * For `device-adoption` addons: the broker kind to create/link
55589
55754
  * (e.g. `home-assistant`), declared in the addon manifest. `null` for
@@ -55696,6 +55861,67 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
55696
55861
  auth: "admin"
55697
55862
  });
55698
55863
  /**
55864
+ * `integration-instances` - the connection of an addon that holds ONE or SEVERAL
55865
+ * (an account, a relay, a destination) as typed records, shown on the
55866
+ * Integrations page like every other integration (D985, D986).
55867
+ *
55868
+ * A collection of providers: each addon that holds connections registers one
55869
+ * and the hub aggregator (`integrations.*`) reaches a provider with the pinned
55870
+ * `addonId`. It is internal and has no route: the operator-facing surface is
55871
+ * the `integrations` cap, which keeps ONE list.
55872
+ *
55873
+ * Identity: the instance id IS the `integrations` registry id (`int_NNNN`,
55874
+ * immutable, already in the `/integrations/<id>` URL). A second operator-chosen
55875
+ * slug would be a second authority over one identity (D224). `name` is the
55876
+ * editable label.
55877
+ *
55878
+ * Secrets: every field the instance kind marks `.meta({ secret: true })` reaches
55879
+ * the form as a `SecretFieldView`, never text (D789). A patch value omitted, `''`
55880
+ * or the redaction token KEEPS the stored secret; `{ $secretClear: true }`
55881
+ * clears it.
55882
+ */
55883
+ var ConfigSchemaPassthrough$3 = custom();
55884
+ var IntegrationInstanceIdSchema = string().min(1);
55885
+ var IntegrationInstanceDescriptionSchema = object({
55886
+ /** `single`: at most one instance can exist (Loki). `multiple`: an account each. */
55887
+ instanceMode: _enum(["single", "multiple"]),
55888
+ /** What the instance is, for the UI (`destination`, `relay`, `account`). */
55889
+ kind: string(),
55890
+ /** True when `testInstance` really probes the remote. */
55891
+ canTest: boolean()
55892
+ });
55893
+ var IntegrationInstanceStatusSchema = object({
55894
+ state: _enum([
55895
+ "ok",
55896
+ "off",
55897
+ "error",
55898
+ "unknown"
55899
+ ]),
55900
+ detail: string().optional()
55901
+ });
55902
+ var IntegrationInstanceSchema = object({
55903
+ id: IntegrationInstanceIdSchema,
55904
+ name: string(),
55905
+ /** The addon's own rule (an URL is present, a client id is present...). */
55906
+ configured: boolean(),
55907
+ /** Values for the instance form; a secret is a `SecretFieldView`, never text. */
55908
+ formValues: record(string(), unknown()),
55909
+ status: IntegrationInstanceStatusSchema.optional()
55910
+ });
55911
+ var IntegrationInstancePatchSchema = object({
55912
+ id: IntegrationInstanceIdSchema,
55913
+ name: string().min(1).optional(),
55914
+ /** Omitted / '' / redaction token keeps a secret; `{ $secretClear: true }` clears it. */
55915
+ values: record(string(), unknown())
55916
+ });
55917
+ method(_void(), IntegrationInstanceDescriptionSchema), method(object({ id: IntegrationInstanceIdSchema.nullable() }), ConfigSchemaPassthrough$3), method(_void(), array(IntegrationInstanceSchema).readonly()), method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable()), method(object({
55918
+ id: IntegrationInstanceIdSchema,
55919
+ name: string().min(1)
55920
+ }), object({ id: string() }), { kind: "mutation" }), method(IntegrationInstancePatchSchema, object({ ok: literal(true) }), { kind: "mutation" }), method(object({ id: IntegrationInstanceIdSchema }), object({ ok: literal(true) }), { kind: "mutation" }), optionalMethod(object({
55921
+ id: IntegrationInstanceIdSchema.nullable(),
55922
+ values: record(string(), unknown())
55923
+ }), TestConnectionResultSchema$1, { kind: "mutation" });
55924
+ /**
55699
55925
  * Two-way audio / talk-back cap. Clients open a WebRTC audio-only
55700
55926
  * session (server-initiated offer pattern, identical to the main
55701
55927
  * video WebRTC flow) and the browser captures the mic; the server
@@ -76689,6 +76915,40 @@ var LoggingSettingsStateSchema = object({
76689
76915
  opsLogRetentionDays: number().int().min(0),
76690
76916
  persisted: boolean()
76691
76917
  });
76918
+ /**
76919
+ * Debug WATCH — a short, per-device window over `debug.<channel>` lines.
76920
+ *
76921
+ * `start` opens (or re-arms) a 10 minute window; `rearm` extends a LIVE one
76922
+ * and never revives a lapsed one; `stop` closes it; `list` only reads. No
76923
+ * chain of re-arms outlives 60 minutes from the first start. The hub holds the
76924
+ * watches in memory and pushes the interest to every node, so a watch lapses
76925
+ * by itself and survives nothing — a restart is a stop.
76926
+ */
76927
+ var DebugWatchInputSchema = object({
76928
+ action: _enum([
76929
+ "list",
76930
+ "start",
76931
+ "rearm",
76932
+ "stop"
76933
+ ]),
76934
+ /** Full channel names, `debug.<channel>`, each declared with `kind: 'debug'`. */
76935
+ channels: array(string().min(1)).readonly().default([]),
76936
+ /** Numeric device ids. Required (non-empty) for `start`. */
76937
+ deviceIds: array(number().int()).readonly().default([])
76938
+ });
76939
+ var DebugWatchStateSchema = object({
76940
+ channel: string(),
76941
+ deviceIds: array(number().int()).readonly(),
76942
+ startedAtMs: number(),
76943
+ untilMs: number(),
76944
+ capAtMs: number()
76945
+ });
76946
+ var DebugWatchResultSchema = object({
76947
+ nowMs: number(),
76948
+ watches: array(DebugWatchStateSchema).readonly(),
76949
+ /** Channels a `rearm` found already lapsed: nothing was revived. */
76950
+ lapsed: array(string()).readonly()
76951
+ });
76692
76952
  method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
76693
76953
  kind: "mutation",
76694
76954
  auth: "admin"
@@ -76704,6 +76964,9 @@ method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_
76704
76964
  }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(_void(), array(ReportedFailureContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
76705
76965
  kind: "mutation",
76706
76966
  auth: "admin"
76967
+ }), method(DebugWatchInputSchema, DebugWatchResultSchema, {
76968
+ kind: "mutation",
76969
+ auth: "admin"
76707
76970
  });
76708
76971
  /**
76709
76972
  * Tamper / case-open detection sensor. Drives Home Assistant
@@ -83813,6 +84076,13 @@ Object.freeze({
83813
84076
  access: "view",
83814
84077
  role: "admin"
83815
84078
  },
84079
+ "deviceManager.dismissDiscoveryProposal": {
84080
+ capName: "device-manager",
84081
+ capScope: "system",
84082
+ addonId: null,
84083
+ access: "create",
84084
+ role: "admin"
84085
+ },
83816
84086
  "deviceManager.enable": {
83817
84087
  capName: "device-manager",
83818
84088
  capScope: "system",
@@ -83995,6 +84265,13 @@ Object.freeze({
83995
84265
  access: "view",
83996
84266
  role: "viewer"
83997
84267
  },
84268
+ "deviceManager.listDiscoveryProposals": {
84269
+ capName: "device-manager",
84270
+ capScope: "system",
84271
+ addonId: null,
84272
+ access: "view",
84273
+ role: "admin"
84274
+ },
83998
84275
  "deviceManager.listLocationDescriptions": {
83999
84276
  capName: "device-manager",
84000
84277
  capScope: "system",
@@ -84149,6 +84426,13 @@ Object.freeze({
84149
84426
  access: "create",
84150
84427
  role: "admin"
84151
84428
  },
84429
+ "deviceManager.reportDiscoveryObservations": {
84430
+ capName: "device-manager",
84431
+ capScope: "system",
84432
+ addonId: null,
84433
+ access: "create",
84434
+ role: "admin"
84435
+ },
84152
84436
  "deviceManager.runDeviceAction": {
84153
84437
  capName: "device-manager",
84154
84438
  capScope: "system",
@@ -84156,6 +84440,13 @@ Object.freeze({
84156
84440
  access: "create",
84157
84441
  role: "admin"
84158
84442
  },
84443
+ "deviceManager.runDiscoverySweep": {
84444
+ capName: "device-manager",
84445
+ capScope: "system",
84446
+ addonId: null,
84447
+ access: "create",
84448
+ role: "admin"
84449
+ },
84159
84450
  "deviceManager.setChildLayout": {
84160
84451
  capName: "device-manager",
84161
84452
  capScope: "system",
@@ -85087,6 +85378,62 @@ Object.freeze({
85087
85378
  access: "create",
85088
85379
  role: "admin"
85089
85380
  },
85381
+ "integrationInstances.createInstance": {
85382
+ capName: "integration-instances",
85383
+ capScope: "system",
85384
+ addonId: null,
85385
+ access: "create",
85386
+ role: "admin"
85387
+ },
85388
+ "integrationInstances.deleteInstance": {
85389
+ capName: "integration-instances",
85390
+ capScope: "system",
85391
+ addonId: null,
85392
+ access: "delete",
85393
+ role: "admin"
85394
+ },
85395
+ "integrationInstances.describe": {
85396
+ capName: "integration-instances",
85397
+ capScope: "system",
85398
+ addonId: null,
85399
+ access: "view",
85400
+ role: "admin"
85401
+ },
85402
+ "integrationInstances.getInstance": {
85403
+ capName: "integration-instances",
85404
+ capScope: "system",
85405
+ addonId: null,
85406
+ access: "view",
85407
+ role: "admin"
85408
+ },
85409
+ "integrationInstances.instanceFormSchema": {
85410
+ capName: "integration-instances",
85411
+ capScope: "system",
85412
+ addonId: null,
85413
+ access: "view",
85414
+ role: "admin"
85415
+ },
85416
+ "integrationInstances.listInstances": {
85417
+ capName: "integration-instances",
85418
+ capScope: "system",
85419
+ addonId: null,
85420
+ access: "view",
85421
+ role: "admin"
85422
+ },
85423
+ "integrationInstances.testInstance": {
85424
+ capName: "integration-instances",
85425
+ capScope: "system",
85426
+ addonId: null,
85427
+ access: "create",
85428
+ role: "admin"
85429
+ },
85430
+ "integrationInstances.updateInstance": {
85431
+ capName: "integration-instances",
85432
+ capScope: "system",
85433
+ addonId: null,
85434
+ access: "create",
85435
+ role: "admin"
85436
+ },
85090
85437
  "integrations.create": {
85091
85438
  capName: "integrations",
85092
85439
  capScope: "system",
@@ -90743,6 +91090,13 @@ Object.freeze({
90743
91090
  access: "create",
90744
91091
  role: "viewer"
90745
91092
  },
91093
+ "system.debugWatch": {
91094
+ capName: "system",
91095
+ capScope: "system",
91096
+ addonId: null,
91097
+ access: "create",
91098
+ role: "admin"
91099
+ },
90746
91100
  "system.detectSiteLocation": {
90747
91101
  capName: "system",
90748
91102
  capScope: "system",
@@ -94672,6 +95026,11 @@ Object.freeze({
94672
95026
  form: "single",
94673
95027
  optional: false
94674
95028
  }],
95029
+ "system.debugWatch": [{
95030
+ name: "deviceIds",
95031
+ form: "array",
95032
+ optional: true
95033
+ }],
94675
95034
  "tamper.getStatus": [{
94676
95035
  name: "deviceId",
94677
95036
  form: "single",
@@ -96838,4 +97197,4 @@ async function listHomeAssistantBrokers(query) {
96838
97197
  return (await query({})).filter((broker) => broker.kind === HA_BROKER_KIND);
96839
97198
  }
96840
97199
  //#endregion
96841
- export { humiditySensorCapability as $, number as $t, brokerCapability as A, temperatureSensorCapability as At, consumableKindOf as B, RecordSecretUnavailableError as Bt, alarmPanelCapability as C, runningFromVacuumState as Ct, bestLocationMatch as D, smokeCapability as Dt, batteryCapability as E, sendToExportedTarget as Et, carbonMonoxideCapability as F, valveCapability as Ft, deviceAdoptionCapability as G, entryBody as Gt, controlCapability as H, createEvent as Ht, climateControlCapability as I, vibrationCapability as It, eventEmitterCapability as J, _enum as Jt, deviceExportCapability as K, isReadingQuantity as Kt, colorCapability as L, waterHeaterCapability as Lt, buildDeviceAdminUrl as M, tryConvertUnit as Mt, buttonCapability as N, updateCapability as Nt, binaryCapability as O, switchCapability as Ot, calendarSourceCapability as P, vacuumControlCapability as Pt, humidifierCapability as Q, literal as Qt, connectivityCapability as R, weatherCapability as Rt, airQualitySensorCapability as S, runningFromMediaPlayer as St, automationControlCapability as T, scriptRunnerCapability as Tt, coverCapability as U, defineEntryKind as Ut, contactCapability as V, baseUnitOf as Vt, deviceAdminLinkCapability as W, defineRecordKinds as Wt, floodCapability as X, boolean as Xt, fanControlCapability as Y, array as Yt, gasCapability as Z, discriminatedUnion as Zt, PLUG_APPLIANCE_TYPES as _, publicEndpointReaderFrom as _t, BaseDevice as a, url as an, motionCapability as at, accessoriesCapability as b, runExportedAction as bt, COCO_TO_MACRO as c, DeviceType as cn, notifierCapability as ct, ConsumableItemSchema as d, parseAdminBase as dt, object as en, imageCapability as et, ConsumableStatusSchema as f, powerMeterCapability as ft, MediaPlayerRepeatSchema as g, pruneDeletedEntities as gt, HvacModeSchema as h, pressureSensorCapability as ht, AlarmArmModeSchema as i, unknown as in, mediaPlayerCapability as it, buildAddonRouteProvider as j, tryConvertDelta as jt, brightnessCapability as k, tamperCapability as kt, CameraSwitchIdSchema as l, errMsg as ln, numericSensorCapability as lt, FanDirectionSchema as m, presenceCapability as mt, HA_PROVIDER_ADDON_ID as n, string as nn, lawnMowerControlCapability as nt, BaseDeviceProvider as o, DeviceFeature as on, normalizeUnit as ot, EnumSensorDateTimeFormatSchema as p, prepareNotification as pt, enumSensorCapability as q, nodePin as qt, listHomeAssistantBrokers as r, union as rn, lockControlCapability as rt, CAMERA_SWITCH_ORDER as s, DeviceRole as sn, notificationOutputCapability as st, HA_BROKER_KIND as t, record as tn, ingestReading as tt, ConsumableFormSchema as u, EventCategory as un, oauthIntegrationCapability as ut, RUNNING_STATE_COLD as v, quantityFromUnit as vt, ambientLightSensorCapability as w, runningStateCapability as wt, addonRoutesCapability as x, runningFromLawnMower as xt, TargetSchema as y, resolveAttachmentUrls as yt, consumableFormOf as z, BaseAddon as zt };
97200
+ export { humiditySensorCapability as $, discriminatedUnion as $t, brokerCapability as A, tamperCapability as At, consumableKindOf as B, BaseAddon as Bt, alarmPanelCapability as C, runningFromMediaPlayer as Ct, bestLocationMatch as D, sendToExportedTarget as Dt, batteryCapability as E, scriptRunnerCapability as Et, carbonMonoxideCapability as F, vacuumControlCapability as Ft, deviceAdoptionCapability as G, defineEntryKind as Gt, controlCapability as H, baseUnitOf as Ht, climateControlCapability as I, valveCapability as It, eventEmitterCapability as J, isReadingQuantity as Jt, deviceExportCapability as K, defineRecordKinds as Kt, colorCapability as L, vibrationCapability as Lt, buildDeviceAdminUrl as M, tryConvertDelta as Mt, buttonCapability as N, tryConvertUnit as Nt, binaryCapability as O, smokeCapability as Ot, calendarSourceCapability as P, updateCapability as Pt, humidifierCapability as Q, boolean as Qt, connectivityCapability as R, waterHeaterCapability as Rt, airQualitySensorCapability as S, runningFromLawnMower as St, automationControlCapability as T, runningStateCapability as Tt, coverCapability as U, createEvent as Ut, contactCapability as V, RecordSecretUnavailableError as Vt, deviceAdminLinkCapability as W, defineAddonMigrations as Wt, floodCapability as X, _enum as Xt, fanControlCapability as Y, nodePin as Yt, gasCapability as Z, array as Zt, PLUG_APPLIANCE_TYPES as _, pruneDeletedEntities as _t, BaseDevice as a, union as an, motionCapability as at, accessoriesCapability as b, resolveAttachmentUrls as bt, COCO_TO_MACRO as c, DeviceFeature as cn, notifierCapability as ct, ConsumableItemSchema as d, errMsg as dn, parseAdminBase as dt, literal as en, imageCapability as et, ConsumableStatusSchema as f, EventCategory as fn, powerMeterCapability as ft, MediaPlayerRepeatSchema as g, pressureSensorCapability as gt, HvacModeSchema as h, presenceCapability as ht, AlarmArmModeSchema as i, string as in, mediaPlayerCapability as it, buildAddonRouteProvider as j, temperatureSensorCapability as jt, brightnessCapability as k, switchCapability as kt, CameraSwitchIdSchema as l, DeviceRole as ln, numericSensorCapability as lt, FanDirectionSchema as m, prepareNotification as mt, HA_PROVIDER_ADDON_ID as n, object as nn, lawnMowerControlCapability as nt, BaseDeviceProvider as o, unknown as on, normalizeUnit as ot, EnumSensorDateTimeFormatSchema as p, preconditionOf as pt, enumSensorCapability as q, entryBody as qt, listHomeAssistantBrokers as r, record as rn, lockControlCapability as rt, CAMERA_SWITCH_ORDER as s, url as sn, notificationOutputCapability as st, HA_BROKER_KIND as t, number as tn, ingestReading as tt, ConsumableFormSchema as u, DeviceType as un, oauthIntegrationCapability as ut, RUNNING_STATE_COLD as v, publicEndpointReaderFrom as vt, ambientLightSensorCapability as w, runningFromVacuumState as wt, addonRoutesCapability as x, runExportedAction as xt, TargetSchema as y, quantityFromUnit as yt, consumableFormOf as z, weatherCapability as zt };