@camstack/addon-provider-homeassistant 1.2.634 → 1.2.636

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.
@@ -5579,7 +5579,7 @@ var ZodIssueCode = {
5579
5579
  var ZodFirstPartyTypeKind;
5580
5580
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5581
5581
  //#endregion
5582
- //#region ../types/dist/sleep-Crlmu_tO.mjs
5582
+ //#region ../types/dist/sleep-DJws6ho7.mjs
5583
5583
  /**
5584
5584
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5585
5585
  * window to float samples (D455).
@@ -9034,6 +9034,7 @@ var CAP_NAMES = Object.freeze([
9034
9034
  "image-settings",
9035
9035
  "integrations",
9036
9036
  "intercom",
9037
+ "ir-transmitter",
9037
9038
  "keychain",
9038
9039
  "keychain-admin",
9039
9040
  "lawn-mower-control",
@@ -9092,6 +9093,7 @@ var CAP_NAMES = Object.freeze([
9092
9093
  "recording-onboard",
9093
9094
  "recording-signal",
9094
9095
  "records",
9096
+ "remote",
9095
9097
  "running-state",
9096
9098
  "scene-monitor",
9097
9099
  "script-runner",
@@ -9115,6 +9117,7 @@ var CAP_NAMES = Object.freeze([
9115
9117
  "system",
9116
9118
  "tamper",
9117
9119
  "temperature-sensor",
9120
+ "template",
9118
9121
  "terminal-session",
9119
9122
  "toast",
9120
9123
  "training",
@@ -10055,6 +10058,11 @@ Object.freeze({
10055
10058
  "standby"
10056
10059
  ]
10057
10060
  },
10061
+ {
10062
+ "path": "stateSource",
10063
+ "valueType": "enum",
10064
+ "enumValues": ["reported", "assumed"]
10065
+ },
10058
10066
  {
10059
10067
  "path": "volumeLevel",
10060
10068
  "valueType": "number"
@@ -10281,6 +10289,11 @@ Object.freeze({
10281
10289
  "path": "batteryPower",
10282
10290
  "valueType": "number"
10283
10291
  },
10292
+ {
10293
+ "path": "powerSource",
10294
+ "valueType": "enum",
10295
+ "enumValues": ["mains", "battery"]
10296
+ },
10284
10297
  {
10285
10298
  "path": "desiccantLeftDays",
10286
10299
  "valueType": "number"
@@ -10325,6 +10338,18 @@ Object.freeze({
10325
10338
  {
10326
10339
  "path": "volume",
10327
10340
  "valueType": "number"
10341
+ },
10342
+ {
10343
+ "path": "lastFeedGrams",
10344
+ "valueType": "number"
10345
+ },
10346
+ {
10347
+ "path": "lastFeedHopper1",
10348
+ "valueType": "number"
10349
+ },
10350
+ {
10351
+ "path": "lastFeedHopper2",
10352
+ "valueType": "number"
10328
10353
  }
10329
10354
  ],
10330
10355
  "power-meter": [
@@ -10864,7 +10889,7 @@ object({
10864
10889
  params: record(string(), union([string(), number()])).optional()
10865
10890
  });
10866
10891
  //#endregion
10867
- //#region ../types/dist/err-msg-DIorGYeC.mjs
10892
+ //#region ../types/dist/err-msg-BCdlR2Li.mjs
10868
10893
  var DeviceType = /* @__PURE__ */ function(DeviceType) {
10869
10894
  DeviceType["Camera"] = "camera";
10870
10895
  DeviceType["Hub"] = "hub";
@@ -11210,6 +11235,9 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
11210
11235
  /** Fallback when the notifier service name doesn't match a known
11211
11236
  * pattern. */
11212
11237
  DeviceRole["GenericNotifier"] = "generic-notifier";
11238
+ /** Emits a pulse train (infrared or RF) on request — the `ir-transmitter`
11239
+ * cap. A `DeviceType.Generic` device. */
11240
+ DeviceRole["IrTransmitter"] = "ir-transmitter";
11213
11241
  return DeviceRole;
11214
11242
  }({});
11215
11243
  /**
@@ -11223,7 +11251,7 @@ function errMsg(err) {
11223
11251
  return String(err);
11224
11252
  }
11225
11253
  //#endregion
11226
- //#region ../types/dist/composition-CZImLpOI.mjs
11254
+ //#region ../types/dist/composition-DpFv_J6D.mjs
11227
11255
  /**
11228
11256
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11229
11257
  *
@@ -16796,9 +16824,21 @@ var AlertSeveritySchema = _enum([
16796
16824
  "error",
16797
16825
  "critical"
16798
16826
  ]);
16827
+ /**
16828
+ * An action that RUNS something instead of going somewhere: the admin UI calls
16829
+ * the addon's custom action (`addons.custom`) with exactly these fields. The
16830
+ * producer owns the meaning; the UI knows nothing about the addon or the kind.
16831
+ */
16832
+ var AlertActionInvokeSchema = object({
16833
+ addonId: string().min(1),
16834
+ action: string().min(1),
16835
+ input: record(string(), unknown()).optional()
16836
+ });
16837
+ /** An action has `href` (a link) OR `invoke` (a button that runs a custom action). */
16799
16838
  var AlertActionSchema = object({
16800
16839
  label: string(),
16801
16840
  href: string().optional(),
16841
+ invoke: AlertActionInvokeSchema.optional(),
16802
16842
  /**
16803
16843
  * How `href` is followed. Absent / `app`: an admin-ui route (client-side).
16804
16844
  * `server`: a route the HUB serves (an addon HTTP route such as an OAuth
@@ -19453,12 +19493,13 @@ var CHANGED = {
19453
19493
  expr: "now"
19454
19494
  };
19455
19495
  function numeric(input) {
19496
+ const { alsoFrom, ...base } = input;
19456
19497
  return {
19457
- ...input,
19498
+ ...base,
19458
19499
  family: "numeric",
19459
19500
  deviceType: DeviceType.Sensor,
19460
19501
  memberDeviceType: DeviceType.Sensor,
19461
- memberDeviceTypes: [DeviceType.Sensor],
19502
+ memberDeviceTypes: [DeviceType.Sensor, ...alsoFrom?.deviceTypes ?? []],
19462
19503
  activeWhen: void 0,
19463
19504
  commandCaps: [],
19464
19505
  baseUnit: baseUnitOf(input.quantity),
@@ -19466,9 +19507,10 @@ function numeric(input) {
19466
19507
  accept: [{
19467
19508
  cap: input.outputCap,
19468
19509
  fieldPath: input.outputField
19469
- }]
19510
+ }, ...alsoFrom === void 0 ? [] : [alsoFrom.accept]]
19470
19511
  };
19471
19512
  }
19513
+ var CLIMATE_DEVICES = [DeviceType.Thermostat, DeviceType.Climate];
19472
19514
  function binary(input) {
19473
19515
  return {
19474
19516
  ...input,
@@ -19494,7 +19536,14 @@ var GROUP_TEMPLATES = [
19494
19536
  quantity: "temperature",
19495
19537
  defaultAggregate: "mean",
19496
19538
  empty: "null",
19497
- companions: [NOW$2]
19539
+ companions: [NOW$2],
19540
+ alsoFrom: {
19541
+ deviceTypes: CLIMATE_DEVICES,
19542
+ accept: {
19543
+ cap: "climate-control",
19544
+ fieldPath: "currentTemp"
19545
+ }
19546
+ }
19498
19547
  }),
19499
19548
  numeric({
19500
19549
  id: "humidity",
@@ -19505,7 +19554,14 @@ var GROUP_TEMPLATES = [
19505
19554
  quantity: "humidity",
19506
19555
  defaultAggregate: "mean",
19507
19556
  empty: "null",
19508
- companions: [NOW$2]
19557
+ companions: [NOW$2],
19558
+ alsoFrom: {
19559
+ deviceTypes: CLIMATE_DEVICES,
19560
+ accept: {
19561
+ cap: "climate-control",
19562
+ fieldPath: "currentHumidity"
19563
+ }
19564
+ }
19509
19565
  }),
19510
19566
  numeric({
19511
19567
  id: "pressure",
@@ -44178,6 +44234,17 @@ var LlmProfileSchema = object({
44178
44234
  * field in its editor only when its descriptor lists it in `profileFields`. */
44179
44235
  topK: number().int().positive().optional(),
44180
44236
  maxTokens: number().int().positive().optional(),
44237
+ /** How hard the model "thinks" before it answers. Omitted = the model's own
44238
+ * default. `off` matters for structured output: a thinking model can spend
44239
+ * the whole completion on reasoning and return an empty `content`. Carried
44240
+ * only by the wires that have it — a kind offers the field in its editor
44241
+ * only when its descriptor lists it in `profileFields`. */
44242
+ reasoningEffort: _enum([
44243
+ "off",
44244
+ "low",
44245
+ "medium",
44246
+ "high"
44247
+ ]).optional(),
44181
44248
  /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
44182
44249
  contextLength: number().int().positive().optional(),
44183
44250
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
@@ -44216,6 +44283,7 @@ var LlmProfileFieldSchema = _enum([
44216
44283
  "topP",
44217
44284
  "topK",
44218
44285
  "maxTokens",
44286
+ "reasoningEffort",
44219
44287
  "contextLength",
44220
44288
  "systemPrompt",
44221
44289
  "timeoutMs",
@@ -45466,6 +45534,43 @@ var NotificationActionSchema = object({
45466
45534
  */
45467
45535
  mode: _enum(["navigate", "background"]).optional()
45468
45536
  });
45537
+ /** A delivery parameter value: what a notifier declared it takes. */
45538
+ var DeliveryParamValueSchema = union([
45539
+ string(),
45540
+ number(),
45541
+ boolean()
45542
+ ]);
45543
+ /**
45544
+ * One extra delivery parameter a notifier KIND declares (D938). A rule that
45545
+ * addresses a target of that kind may set it; a kind that declares nothing is
45546
+ * never handed one. The admin UI derives its control from this descriptor —
45547
+ * no editor knows a service by name.
45548
+ *
45549
+ * Optional fields are `.optional()`, never `.default()` (a Zod default does not
45550
+ * run on the addon cap path).
45551
+ */
45552
+ var DeliveryParamSchema = object({
45553
+ key: string().min(1),
45554
+ label: string(),
45555
+ /** i18n key of the label, resolved by the declaring addon's namespace. */
45556
+ labelKey: string().optional(),
45557
+ type: _enum([
45558
+ "enum",
45559
+ "number",
45560
+ "boolean",
45561
+ "string"
45562
+ ]),
45563
+ /** `enum` only: the closed set of accepted values. */
45564
+ options: array(object({
45565
+ value: string(),
45566
+ label: string()
45567
+ })).optional(),
45568
+ /** `number` only. */
45569
+ min: number().optional(),
45570
+ max: number().optional(),
45571
+ /** What the notifier does when the rule sets nothing; shown as the placeholder. */
45572
+ default: DeliveryParamValueSchema.optional()
45573
+ });
45469
45574
  /**
45470
45575
  * The canonical notification. `body` is the only hard field (Apprise model).
45471
45576
  * `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
@@ -45488,7 +45593,13 @@ var NotificationSchema = object({
45488
45593
  tag: string().optional(),
45489
45594
  deviceId: number().optional(),
45490
45595
  eventId: string().optional(),
45491
- metadata: record(string(), unknown()).optional()
45596
+ metadata: record(string(), unknown()).optional(),
45597
+ /**
45598
+ * Values for the parameters the target's kind DECLARES in
45599
+ * {@link TargetKindSchema} `deliveryParams`. Already validated against the
45600
+ * declaration by the sender; a notifier reads only the keys it declared.
45601
+ */
45602
+ delivery: record(string(), DeliveryParamValueSchema).optional()
45492
45603
  });
45493
45604
  /** One declared native severity/priority level for a kind. */
45494
45605
  var TargetKindLevelSchema = object({
@@ -45594,6 +45705,11 @@ var TargetKindSchema = object({
45594
45705
  */
45595
45706
  destinationKeys: array(string()).optional(),
45596
45707
  supportsDiscovery: boolean(),
45708
+ /**
45709
+ * Extra delivery parameters a rule may set for a target of this kind (D938).
45710
+ * Absent = none; the rule editor then offers nothing.
45711
+ */
45712
+ deliveryParams: array(DeliveryParamSchema).optional(),
45597
45713
  caps: TargetKindCapsSchema
45598
45714
  });
45599
45715
  /**
@@ -57995,7 +58111,9 @@ var ManifestShapeSchema = object({
57995
58111
  icon: string().optional()
57996
58112
  }).optional(),
57997
58113
  protected: boolean().optional(),
57998
- removable: boolean().optional()
58114
+ removable: boolean().optional(),
58115
+ /** Declared Integrations-page block (mirror of `AddonDeclaration.integrationSection`). */
58116
+ integrationSection: _enum(["system", "providers"]).optional()
57999
58117
  });
58000
58118
  var AddonProcessSchema = object({
58001
58119
  pid: number().optional(),
@@ -59125,6 +59243,318 @@ onBrightnessChanged: { data: object({
59125
59243
  } } }
59126
59244
  };
59127
59245
  /**
59246
+ * The role vocabulary of a remote (D963): what a button MEANS, independent of
59247
+ * how it is wired. A layout template places buttons by role; a device binds a
59248
+ * role to an action; an exporter asks for a role by name. Roles are shared so
59249
+ * one layout fits every appliance and one voice command fits every binding.
59250
+ *
59251
+ * A role outside this list is `custom:<key>` — the operator's own button (a
59252
+ * SmartIR source, a channel preset). The key is a lowercase slug.
59253
+ */
59254
+ var REMOTE_KNOWN_ROLES = [
59255
+ "power",
59256
+ "power_on",
59257
+ "power_off",
59258
+ "volume_up",
59259
+ "volume_down",
59260
+ "mute",
59261
+ "channel_up",
59262
+ "channel_down",
59263
+ "up",
59264
+ "down",
59265
+ "left",
59266
+ "right",
59267
+ "ok",
59268
+ "back",
59269
+ "home",
59270
+ "menu",
59271
+ "info",
59272
+ "guide",
59273
+ "exit",
59274
+ "input",
59275
+ "play",
59276
+ "pause",
59277
+ "play_pause",
59278
+ "stop",
59279
+ "next",
59280
+ "previous",
59281
+ "fast_forward",
59282
+ "rewind",
59283
+ "digit_0",
59284
+ "digit_1",
59285
+ "digit_2",
59286
+ "digit_3",
59287
+ "digit_4",
59288
+ "digit_5",
59289
+ "digit_6",
59290
+ "digit_7",
59291
+ "digit_8",
59292
+ "digit_9"
59293
+ ];
59294
+ var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
59295
+ var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
59296
+ function isRemoteKnownRole(value) {
59297
+ return KNOWN_ROLES.has(value);
59298
+ }
59299
+ function isRemoteCustomKey(key) {
59300
+ return CUSTOM_KEY_RE.test(key);
59301
+ }
59302
+ /** The key of a `custom:<key>` role, or null for any other string. */
59303
+ function customKeyOfRole(role) {
59304
+ if (!role.startsWith("custom:")) return null;
59305
+ const key = role.slice(7);
59306
+ return isRemoteCustomKey(key) ? key : null;
59307
+ }
59308
+ function isRemoteRole(value) {
59309
+ return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
59310
+ }
59311
+ var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
59312
+ var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
59313
+ var RemoteCustomButtonSchema = object({
59314
+ /** The slug after `custom:` in the role. */
59315
+ key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
59316
+ /** What the operator calls it, and what a voice command may name. */
59317
+ name: string().min(1).max(60)
59318
+ });
59319
+ var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
59320
+ var RemoteConfigSchema = object({
59321
+ layoutTemplateId: string().min(1).nullable(),
59322
+ /**
59323
+ * The transmitter device new bindings and an import send through. A binding
59324
+ * names its own device, so one command may override it.
59325
+ */
59326
+ defaultTransmitterId: number().int().nonnegative().nullable().default(null),
59327
+ /** Keyed by role. A role with no entry falls back to the native cap. */
59328
+ bindings: record(string(), RemoteBindingSchema),
59329
+ customButtons: array(RemoteCustomButtonSchema).max(100),
59330
+ power: object({ mode: RemotePowerModeSchema })
59331
+ }).superRefine((config, ctx) => {
59332
+ const roles = Object.keys(config.bindings);
59333
+ if (roles.length > 200) ctx.addIssue({
59334
+ code: "custom",
59335
+ message: "too many bindings",
59336
+ path: ["bindings"]
59337
+ });
59338
+ for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
59339
+ code: "custom",
59340
+ message: `"${role}" is not a role`,
59341
+ path: ["bindings", role]
59342
+ });
59343
+ const keys = /* @__PURE__ */ new Set();
59344
+ config.customButtons.forEach((button, index) => {
59345
+ if (keys.has(button.key)) ctx.addIssue({
59346
+ code: "custom",
59347
+ message: `custom button "${button.key}" is listed twice`,
59348
+ path: [
59349
+ "customButtons",
59350
+ index,
59351
+ "key"
59352
+ ]
59353
+ });
59354
+ keys.add(button.key);
59355
+ });
59356
+ for (const role of roles) {
59357
+ const key = customKeyOfRole(role);
59358
+ if (key !== null && !keys.has(key)) ctx.addIssue({
59359
+ code: "custom",
59360
+ message: `${role} is bound but has no entry in customButtons`,
59361
+ path: ["bindings", role]
59362
+ });
59363
+ }
59364
+ });
59365
+ object({
59366
+ power: object({
59367
+ state: _enum(["on", "off"]),
59368
+ at: number()
59369
+ }).nullable(),
59370
+ muted: object({
59371
+ value: boolean(),
59372
+ at: number()
59373
+ }).nullable()
59374
+ });
59375
+ var RemoteLayoutButtonSchema = object({
59376
+ id: string().min(1).max(40),
59377
+ /** 0-based grid position. */
59378
+ row: number().int().min(0).max(24),
59379
+ col: number().int().min(0).max(24),
59380
+ rowSpan: number().int().min(1).max(24),
59381
+ colSpan: number().int().min(1).max(24),
59382
+ icon: string().min(1).max(60).optional(),
59383
+ label: string().min(1).max(40).optional(),
59384
+ role: RemoteRoleSchema
59385
+ });
59386
+ object({
59387
+ columns: number().int().min(1).max(24),
59388
+ rows: number().int().min(1).max(24),
59389
+ buttons: array(RemoteLayoutButtonSchema).max(200)
59390
+ }).superRefine((grid, ctx) => {
59391
+ const ids = /* @__PURE__ */ new Set();
59392
+ const taken = /* @__PURE__ */ new Map();
59393
+ grid.buttons.forEach((button, index) => {
59394
+ if (ids.has(button.id)) ctx.addIssue({
59395
+ code: "custom",
59396
+ message: `button id "${button.id}" is used twice`,
59397
+ path: [
59398
+ "buttons",
59399
+ index,
59400
+ "id"
59401
+ ]
59402
+ });
59403
+ ids.add(button.id);
59404
+ if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
59405
+ ctx.addIssue({
59406
+ code: "custom",
59407
+ message: `button "${button.id}" leaves the grid`,
59408
+ path: ["buttons", index]
59409
+ });
59410
+ return;
59411
+ }
59412
+ for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
59413
+ const cell = `${r}:${c}`;
59414
+ const other = taken.get(cell);
59415
+ if (other !== void 0) {
59416
+ ctx.addIssue({
59417
+ code: "custom",
59418
+ message: `buttons "${other}" and "${button.id}" overlap`,
59419
+ path: ["buttons", index]
59420
+ });
59421
+ return;
59422
+ }
59423
+ taken.set(cell, button.id);
59424
+ }
59425
+ });
59426
+ });
59427
+ var RemoteBoundCommandSchema = object({
59428
+ role: RemoteRoleSchema,
59429
+ /** The operator's name for a custom button; absent for a known role. */
59430
+ label: string().optional(),
59431
+ custom: boolean()
59432
+ });
59433
+ var RemoteCommandListSchema = object({
59434
+ layoutTemplateId: string().nullable(),
59435
+ power: object({ mode: RemotePowerModeSchema }),
59436
+ /** Only the roles that are BOUND — the ones a press can reach. */
59437
+ commands: array(RemoteBoundCommandSchema)
59438
+ });
59439
+ var RemoteRefusalReasonSchema = _enum([
59440
+ "no-remote",
59441
+ "unbound-role",
59442
+ "action-failed"
59443
+ ]);
59444
+ var RemoteSendResultSchema = discriminatedUnion("status", [
59445
+ object({
59446
+ status: literal("sent"),
59447
+ /** How many times the action ran. */
59448
+ sends: number().int().min(1)
59449
+ }),
59450
+ object({
59451
+ status: literal("skipped"),
59452
+ reason: literal("already-in-state")
59453
+ }),
59454
+ object({
59455
+ status: literal("refused"),
59456
+ reason: RemoteRefusalReasonSchema,
59457
+ detail: string().optional()
59458
+ })
59459
+ ]);
59460
+ var RemoteMediaCommandSchema = _enum([
59461
+ "play",
59462
+ "pause",
59463
+ "stop",
59464
+ "next",
59465
+ "previous",
59466
+ "setMute",
59467
+ "selectSource"
59468
+ ]);
59469
+ /** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
59470
+ var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
59471
+ var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
59472
+ status: literal("refused"),
59473
+ reason: _enum(["unknown-template", "not-a-media-player"]),
59474
+ detail: string()
59475
+ })]);
59476
+ var deviceInput = object({ deviceId: number().int().nonnegative() });
59477
+ DeviceType.MediaPlayer;
59478
+ method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
59479
+ kind: "mutation",
59480
+ auth: "admin"
59481
+ }), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
59482
+ role: RemoteRoleSchema,
59483
+ /** Sends in a row (volume steps). */
59484
+ repeat: number().int().min(1).max(50).default(1)
59485
+ }), RemoteSendResultSchema, {
59486
+ kind: "mutation",
59487
+ auth: "protected"
59488
+ }), method(deviceInput.extend({
59489
+ command: RemoteMediaCommandSchema,
59490
+ muted: boolean().optional(),
59491
+ source: string().optional(),
59492
+ repeat: number().int().min(1).max(50).default(1)
59493
+ }), RemoteMediaCommandResultSchema, {
59494
+ kind: "mutation",
59495
+ auth: "protected"
59496
+ });
59497
+ var TemplateKindSchema = _enum(["remote"]);
59498
+ /**
59499
+ * template — the generic store of reusable, named operator data (D963). A
59500
+ * record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
59501
+ * button grid of a remote) and the schema each payload must satisfy are
59502
+ * declared by the system in `template-kinds.ts`. Nothing here is specific to a
59503
+ * kind: the engine validates a payload against its kind's schema and, on a
59504
+ * delete, asks the kind's owner whether anything still points at the record.
59505
+ *
59506
+ * Every refusal is a typed result — a UI says "unknown kind" or names the
59507
+ * devices that still use a template, without parsing text.
59508
+ */
59509
+ var TemplateRecordSchema = object({
59510
+ id: string().min(1),
59511
+ kind: TemplateKindSchema,
59512
+ name: string().min(1).max(120),
59513
+ /** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
59514
+ payload: unknown(),
59515
+ createdAt: number(),
59516
+ updatedAt: number()
59517
+ });
59518
+ var TemplateWriteResultSchema = discriminatedUnion("status", [object({
59519
+ status: literal("saved"),
59520
+ template: TemplateRecordSchema
59521
+ }), object({
59522
+ status: literal("refused"),
59523
+ reason: _enum(["invalid-payload", "not-found"]),
59524
+ detail: string()
59525
+ })]);
59526
+ /** A device still pointing at a template. */
59527
+ var TemplateUserSchema = object({
59528
+ deviceId: number().int().nonnegative(),
59529
+ name: string()
59530
+ });
59531
+ var TemplateDeleteResultSchema = discriminatedUnion("status", [
59532
+ object({ status: literal("deleted") }),
59533
+ object({ status: literal("not-found") }),
59534
+ object({
59535
+ status: literal("in-use"),
59536
+ devices: array(TemplateUserSchema).min(1)
59537
+ })
59538
+ ]);
59539
+ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
59540
+ kind: TemplateKindSchema,
59541
+ name: string().min(1).max(120),
59542
+ payload: unknown()
59543
+ }), TemplateWriteResultSchema, {
59544
+ kind: "mutation",
59545
+ auth: "admin"
59546
+ }), method(object({
59547
+ id: string().min(1),
59548
+ name: string().min(1).max(120).optional(),
59549
+ payload: unknown().optional()
59550
+ }), TemplateWriteResultSchema, {
59551
+ kind: "mutation",
59552
+ auth: "admin"
59553
+ }), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
59554
+ kind: "mutation",
59555
+ auth: "admin"
59556
+ });
59557
+ /**
59128
59558
  * button — device-scoped capability for HA `button.*` / `input_button.*`
59129
59559
  * fire-only actuators. A button entity has no readable state — pressing it
59130
59560
  * triggers an action on the HA side. There is no `status` / `runtimeState`:
@@ -59146,6 +59576,56 @@ var buttonCapability = {
59146
59576
  }) }
59147
59577
  };
59148
59578
  /**
59579
+ * A pulse train in signed microseconds: mark (+) first, then space (-), strictly
59580
+ * alternating, no zeros, 2..1024 entries.
59581
+ */
59582
+ var IrTimingsSchema = array(number().int()).min(2).max(1024).superRefine((timings, ctx) => {
59583
+ timings.forEach((value, index) => {
59584
+ const expectMark = index % 2 === 0;
59585
+ if (value === 0 || value > 0 !== expectMark) ctx.addIssue({
59586
+ code: "custom",
59587
+ message: `timing ${index} must be a non-zero ${expectMark ? "mark (positive)" : "space (negative)"}`,
59588
+ path: [index]
59589
+ });
59590
+ });
59591
+ });
59592
+ /** Per-command transmit options. Every key is optional; a transmitter applies what it can. */
59593
+ var TransmitSettingsSchema = object({
59594
+ carrierHz: number().int().positive().optional(),
59595
+ dutyCyclePercent: number().int().min(1).max(100).optional(),
59596
+ repeat: number().int().min(0).max(20).optional(),
59597
+ repeatDelayMs: number().int().min(0).optional()
59598
+ });
59599
+ /** The setting keys a transmitter may declare as settable (`getInfo.settable`). */
59600
+ var TransmitSettingKeySchema = _enum([
59601
+ "carrierHz",
59602
+ "dutyCyclePercent",
59603
+ "repeat",
59604
+ "repeatDelayMs"
59605
+ ]);
59606
+ var IrMediumSchema = _enum(["ir", "rf"]);
59607
+ var IrSendResultSchema = object({
59608
+ ok: literal(true),
59609
+ /** Settings the transmitter could not apply; the train was still sent. */
59610
+ ignoredSettings: array(string())
59611
+ });
59612
+ var IrTransmitterInfoSchema = object({
59613
+ media: array(IrMediumSchema),
59614
+ settable: array(TransmitSettingKeySchema),
59615
+ maxTimings: number().int().positive()
59616
+ });
59617
+ DeviceType.Generic, method(object({
59618
+ deviceId: number().int().nonnegative(),
59619
+ timings: IrTimingsSchema,
59620
+ settings: TransmitSettingsSchema.optional()
59621
+ }), IrSendResultSchema, {
59622
+ kind: "mutation",
59623
+ auth: "protected"
59624
+ }), method(object({ deviceId: number().int().nonnegative() }), IrTransmitterInfoSchema, {
59625
+ kind: "query",
59626
+ auth: "protected"
59627
+ });
59628
+ /**
59149
59629
  * `calendar-source` — collection cap exposing per-provider calendars and
59150
59630
  * their events. Every addon that contributes calendars (Home Assistant,
59151
59631
  * a future Google Calendar addon, …) registers a provider here. The hub
@@ -63276,9 +63756,35 @@ var MediaInfoSchema = object({
63276
63756
  /** Optional cover-art / thumbnail URL. */
63277
63757
  imageUrl: string().optional()
63278
63758
  });
63759
+ /**
63760
+ * Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
63761
+ * the device said so. `assumed`: the driver has no feedback (infrared) and
63762
+ * tracks what it last SENT; it moves only after a send was accepted, and a
63763
+ * human at the real remote makes it wrong. A UI shows an assumed value as a
63764
+ * guess, never as a reading.
63765
+ */
63766
+ var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
63767
+ /** The fields of a media-player status a driver can only guess. */
63768
+ var MediaPlayerAssumedFieldSchema = _enum([
63769
+ "state",
63770
+ "volumeLevel",
63771
+ "isMuted",
63772
+ "source"
63773
+ ]);
63279
63774
  var MediaPlayerStatusSchema = object({
63280
63775
  /** Playback lifecycle state. */
63281
63776
  state: MediaPlayerStateSchema,
63777
+ /**
63778
+ * Whether the state fields are readings or the driver's own bookkeeping.
63779
+ * A slice written before this field existed parses as `reported`.
63780
+ */
63781
+ stateSource: MediaPlayerStateSourceSchema.default("reported"),
63782
+ /**
63783
+ * Which fields are the driver's own guess. `stateSource` is `assumed` when
63784
+ * this is not empty; a field not listed here is a reading even then (power
63785
+ * from a running-state source, mute guessed from the last send).
63786
+ */
63787
+ assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
63282
63788
  /** Volume as 0..100 inclusive. Null when the device has no volume
63283
63789
  * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
63284
63790
  volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
@@ -65206,9 +65712,14 @@ var PetFeederStatusSchema = object({
65206
65712
  * (`device_class: problem`, on = low). True when the tank reports empty,
65207
65713
  * or, on a dual-hopper model, when EITHER hopper is empty. */
65208
65714
  lowFood: boolean(),
65209
- /** Battery charge 0..100 (%). Null on mains-powered models or when the
65210
- * device has no battery reading. */
65715
+ /** Battery charge 0..100 (%). On a feeder running on `mains` this is the
65716
+ * BACKUP battery's charge, not the power source. Null when the device has
65717
+ * no battery reading. */
65211
65718
  batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
65719
+ /** What the feeder is powered from right now: `mains` (plugged in, the
65720
+ * battery is only a backup) or `battery`. Null when the device does not
65721
+ * report it. */
65722
+ powerSource: _enum(["mains", "battery"]).nullable(),
65212
65723
  /**
65213
65724
  * Desiccant life remaining, stored in seconds (duration base, D944).
65214
65725
  * Providers convert from the days the feeder reports. Null when the
@@ -65236,6 +65747,14 @@ var PetFeederStatusSchema = object({
65236
65747
  feedSound: boolean(),
65237
65748
  /** Speaker / prompt volume level (device-scaled integer). */
65238
65749
  volume: number().meta(readingMeta("none")),
65750
+ /** Portion (grams) of the last manual feed sent from a single-hopper
65751
+ * stepper — the default the next manual feed starts from. Persisted per
65752
+ * device by the provider; null until a manual feed has been sent. */
65753
+ lastFeedGrams: gramsPortion.nullable(),
65754
+ /** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
65755
+ lastFeedHopper1: gramsPortion.nullable(),
65756
+ /** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
65757
+ lastFeedHopper2: gramsPortion.nullable(),
65239
65758
  /** Ms epoch when the slice was last refreshed from the cloud. */
65240
65759
  lastFetchedAt: number()
65241
65760
  });
@@ -71281,6 +71800,14 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
71281
71800
  kind: "mutation",
71282
71801
  auth: "admin"
71283
71802
  });
71803
+ discriminatedUnion("kind", [object({
71804
+ kind: literal("raw"),
71805
+ timings: array(number().int()),
71806
+ settings: TransmitSettingsSchema.optional()
71807
+ }), object({
71808
+ kind: literal("pronto"),
71809
+ code: string()
71810
+ })]);
71284
71811
  function resolveSince(running, previous, transitionAtMs, bootstrapSinceMs) {
71285
71812
  if (running === null) return null;
71286
71813
  const prevRunning = previous?.running ?? null;
@@ -71718,7 +72245,7 @@ function tryConvertDelta(value, from, to) {
71718
72245
  return shifted - origin;
71719
72246
  }
71720
72247
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
71721
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, 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.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
72248
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, 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.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
71722
72249
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
71723
72250
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
71724
72251
  new Set(CAP_NAMES);
@@ -76871,6 +77398,20 @@ Object.freeze({
76871
77398
  access: "create",
76872
77399
  role: "viewer"
76873
77400
  },
77401
+ "irTransmitter.getInfo": {
77402
+ capName: "ir-transmitter",
77403
+ capScope: "device",
77404
+ addonId: null,
77405
+ access: "view",
77406
+ role: "viewer"
77407
+ },
77408
+ "irTransmitter.send": {
77409
+ capName: "ir-transmitter",
77410
+ capScope: "device",
77411
+ addonId: null,
77412
+ access: "create",
77413
+ role: "viewer"
77414
+ },
76874
77415
  "keychain.delete": {
76875
77416
  capName: "keychain",
76876
77417
  capScope: "system",
@@ -80994,6 +81535,41 @@ Object.freeze({
80994
81535
  access: "create",
80995
81536
  role: "admin"
80996
81537
  },
81538
+ "remote.getConfig": {
81539
+ capName: "remote",
81540
+ capScope: "system",
81541
+ addonId: null,
81542
+ access: "view",
81543
+ role: "admin"
81544
+ },
81545
+ "remote.listCommands": {
81546
+ capName: "remote",
81547
+ capScope: "system",
81548
+ addonId: null,
81549
+ access: "view",
81550
+ role: "admin"
81551
+ },
81552
+ "remote.sendCommand": {
81553
+ capName: "remote",
81554
+ capScope: "system",
81555
+ addonId: null,
81556
+ access: "create",
81557
+ role: "admin"
81558
+ },
81559
+ "remote.sendMediaCommand": {
81560
+ capName: "remote",
81561
+ capScope: "system",
81562
+ addonId: null,
81563
+ access: "create",
81564
+ role: "admin"
81565
+ },
81566
+ "remote.setConfig": {
81567
+ capName: "remote",
81568
+ capScope: "system",
81569
+ addonId: null,
81570
+ access: "create",
81571
+ role: "admin"
81572
+ },
80997
81573
  "runningState.getStatus": {
80998
81574
  capName: "running-state",
80999
81575
  capScope: "device",
@@ -82184,6 +82760,41 @@ Object.freeze({
82184
82760
  access: "view",
82185
82761
  role: "viewer"
82186
82762
  },
82763
+ "template.create": {
82764
+ capName: "template",
82765
+ capScope: "system",
82766
+ addonId: null,
82767
+ access: "create",
82768
+ role: "admin"
82769
+ },
82770
+ "template.delete": {
82771
+ capName: "template",
82772
+ capScope: "system",
82773
+ addonId: null,
82774
+ access: "delete",
82775
+ role: "admin"
82776
+ },
82777
+ "template.get": {
82778
+ capName: "template",
82779
+ capScope: "system",
82780
+ addonId: null,
82781
+ access: "view",
82782
+ role: "admin"
82783
+ },
82784
+ "template.list": {
82785
+ capName: "template",
82786
+ capScope: "system",
82787
+ addonId: null,
82788
+ access: "view",
82789
+ role: "admin"
82790
+ },
82791
+ "template.update": {
82792
+ capName: "template",
82793
+ capScope: "system",
82794
+ addonId: null,
82795
+ access: "create",
82796
+ role: "admin"
82797
+ },
82187
82798
  "terminalSession.adoptLegacyMonitor": {
82188
82799
  capName: "terminal-session",
82189
82800
  capScope: "system",
@@ -84494,6 +85105,11 @@ var ACTUATOR_CAP_VOCABULARY = {
84494
85105
  icon: "circle-dot"
84495
85106
  }]
84496
85107
  },
85108
+ "ir-transmitter": {
85109
+ scope: "device",
85110
+ noun: t("IR / RF transmitter", "Trasmettitore IR / RF"),
85111
+ notOperatorFacing: { send: "a raw pulse train is not something an operator composes in an automation; the remote that owns the command table sends it" }
85112
+ },
84497
85113
  control: {
84498
85114
  scope: "device",
84499
85115
  noun: t("Control", "Controllo"),
@@ -87010,6 +87626,7 @@ var SYSTEM_CAP_VOCABULARY = {
87010
87626
  "recording-archive": system(STORAGE),
87011
87627
  "recording-export": system("recording exports — requested from the timeline, not an automation step"),
87012
87628
  records: system(INTERNAL),
87629
+ remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
87013
87630
  "server-management": system(CLUSTER),
87014
87631
  "settings-store": system(INTERNAL),
87015
87632
  "smtp-provider": system(INTERNAL),
@@ -87022,6 +87639,7 @@ var SYSTEM_CAP_VOCABULARY = {
87022
87639
  "storage-provider": system(STORAGE),
87023
87640
  "stream-broker": system(PIPELINE),
87024
87641
  system: system(CLUSTER),
87642
+ template: system("operator-authored templates — edited in their own editor, never actuated"),
87025
87643
  "terminal-session": system(CLUSTER),
87026
87644
  toast: system(UI_PLUMBING),
87027
87645
  training: system(ML),
@@ -88224,6 +88842,16 @@ Object.freeze({
88224
88842
  form: "single",
88225
88843
  optional: false
88226
88844
  }],
88845
+ "irTransmitter.getInfo": [{
88846
+ name: "deviceId",
88847
+ form: "single",
88848
+ optional: false
88849
+ }],
88850
+ "irTransmitter.send": [{
88851
+ name: "deviceId",
88852
+ form: "single",
88853
+ optional: false
88854
+ }],
88227
88855
  "keychain.deleteDeviceScope": [{
88228
88856
  name: "deviceId",
88229
88857
  form: "single",
@@ -89449,6 +90077,31 @@ Object.freeze({
89449
90077
  form: "single",
89450
90078
  optional: true
89451
90079
  }],
90080
+ "remote.getConfig": [{
90081
+ name: "deviceId",
90082
+ form: "single",
90083
+ optional: false
90084
+ }],
90085
+ "remote.listCommands": [{
90086
+ name: "deviceId",
90087
+ form: "single",
90088
+ optional: false
90089
+ }],
90090
+ "remote.sendCommand": [{
90091
+ name: "deviceId",
90092
+ form: "single",
90093
+ optional: false
90094
+ }],
90095
+ "remote.sendMediaCommand": [{
90096
+ name: "deviceId",
90097
+ form: "single",
90098
+ optional: false
90099
+ }],
90100
+ "remote.setConfig": [{
90101
+ name: "deviceId",
90102
+ form: "single",
90103
+ optional: false
90104
+ }],
89452
90105
  "runningState.getStatus": [{
89453
90106
  name: "deviceId",
89454
90107
  form: "single",
@@ -91606,5 +92259,13 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
91606
92259
  String.raw`(?<=^|["'(\s>,\[{])`;
91607
92260
  var MB = 1024 * 1024;
91608
92261
  1024 * MB, 3072 * MB;
92262
+ object({
92263
+ manufacturer: string().optional(),
92264
+ supportedModels: array(string()).optional(),
92265
+ supportedController: string().optional(),
92266
+ commandsEncoding: string(),
92267
+ delay: number().nonnegative().optional(),
92268
+ commands: record(string(), unknown())
92269
+ });
91609
92270
  //#endregion
91610
92271
  export { lawnMowerControlCapability as $, union as $t, buttonCapability as A, weatherCapability as At, coverCapability as B, defineRecordKinds as Bt, batteryCapability as C, tryConvertDelta as Ct, brokerCapability as D, valveCapability as Dt, brightnessCapability as E, vacuumControlCapability as Et, connectivityCapability as F, BaseAddon as Ft, eventEmitterCapability as G, array as Gt, deviceAdoptionCapability as H, isReadingQuantity as Ht, consumableFormOf as I, RecordSecretUnavailableError as It, gasCapability as J, literal as Jt, fanControlCapability as K, boolean as Kt, consumableKindOf as L, baseUnitOf as Lt, carbonMonoxideCapability as M, DeviceRole as Mt, climateControlCapability as N, DeviceType as Nt, buildAddonRouteProvider as O, vibrationCapability as Ot, colorCapability as P, errMsg as Pt, ingestReading as Q, string as Qt, contactCapability as R, createEvent as Rt, automationControlCapability as S, temperatureSensorCapability as St, binaryCapability as T, updateCapability as Tt, deviceExportCapability as U, nodePin as Ut, deviceAdminLinkCapability as V, entryBody as Vt, enumSensorCapability as W, _enum as Wt, humiditySensorCapability as X, object as Xt, humidifierCapability as Y, number as Yt, imageCapability as Z, record as Zt, accessoriesCapability as _, runningStateCapability as _t, COCO_TO_MACRO as a, notifierCapability as at, alarmPanelCapability as b, switchCapability as bt, ConsumableItemSchema as c, parseAdminBase as ct, FanDirectionSchema as d, presenceCapability as dt, unknown as en, lockControlCapability as et, HvacModeSchema as f, pressureSensorCapability as ft, TargetSchema as g, runningFromVacuumState as gt, RUNNING_STATE_COLD as h, runningFromMediaPlayer as ht, CAMERA_SWITCH_ORDER as i, notificationOutputCapability as it, calendarSourceCapability as j, DeviceFeature as jt, buildDeviceAdminUrl as k, waterHeaterCapability as kt, ConsumableStatusSchema as l, powerMeterCapability as lt, PLUG_APPLIANCE_TYPES as m, runningFromLawnMower as mt, BaseDevice as n, EventCategory as nn, motionCapability as nt, CameraSwitchIdSchema as o, numericSensorCapability as ot, MediaPlayerRepeatSchema as p, quantityFromUnit as pt, floodCapability as q, discriminatedUnion as qt, BaseDeviceProvider as r, normalizeUnit as rt, ConsumableFormSchema as s, oauthIntegrationCapability as st, AlarmArmModeSchema as t, url as tn, mediaPlayerCapability as tt, EnumSensorDateTimeFormatSchema as u, prepareNotification as ut, addonRoutesCapability as v, scriptRunnerCapability as vt, bestLocationMatch as w, tryConvertUnit as wt, ambientLightSensorCapability as x, tamperCapability as xt, airQualitySensorCapability as y, smokeCapability as yt, controlCapability as z, defineEntryKind as zt };