@camstack/addon-agent-ui 1.2.316 → 1.2.318

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.
package/dist/addon.js CHANGED
@@ -786,7 +786,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
786
786
  return EventCategory;
787
787
  }({});
788
788
  //#endregion
789
- //#region ../types/dist/device-type-CfHw_quR.mjs
789
+ //#region ../types/dist/device-type-D1fH5kaC.mjs
790
790
  /**
791
791
  import { errMsg } from '@camstack/types'
792
792
  * Extract a human-readable message from an unknown error value.
@@ -1017,6 +1017,12 @@ var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
1017
1017
  DeviceFeature["MediaPlayerPrevious"] = "media-player-previous";
1018
1018
  /** Media player exposes stop distinct from pause. */
1019
1019
  DeviceFeature["MediaPlayerStop"] = "media-player-stop";
1020
+ /** Media player exposes volume up / down in steps (an infrared TV has no level). */
1021
+ DeviceFeature["MediaPlayerVolumeStep"] = "media-player-volume-step";
1022
+ /** Media player exposes channel up / down in steps. */
1023
+ DeviceFeature["MediaPlayerChannelStep"] = "media-player-channel-step";
1024
+ /** Media player exposes power on / off. */
1025
+ DeviceFeature["MediaPlayerPower"] = "media-player-power";
1020
1026
  /** Alarm panel requires a PIN code on arm/disarm. */
1021
1027
  DeviceFeature["AlarmPinRequired"] = "alarm-pin-required";
1022
1028
  /** Presence device carries GPS coordinates (lat/lng/accuracy) in
@@ -5843,7 +5849,7 @@ var ZodIssueCode = {
5843
5849
  var ZodFirstPartyTypeKind;
5844
5850
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5845
5851
  //#endregion
5846
- //#region ../types/dist/sleep-QsoHs66J.mjs
5852
+ //#region ../types/dist/sleep-BKClVk0K.mjs
5847
5853
  /**
5848
5854
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5849
5855
  * window to float samples (D455).
@@ -5922,6 +5928,22 @@ function buildAlawTable() {
5922
5928
  }
5923
5929
  buildUlawTable();
5924
5930
  buildAlawTable();
5931
+ /**
5932
+ * An addon whose own migrations did not apply refuses to initialise (D987). The error is typed
5933
+ * so a runner hosting several addons can tell "this addon is blocked" from a crash and keep its
5934
+ * co-located siblings running. Recognised by NAME and shape, never `instanceof`: a forked addon
5935
+ * bundles its own copy of this module, so the class the runner sees is not the one that threw.
5936
+ */
5937
+ var MIGRATIONS_BLOCKED_ERROR_NAME = "AddonMigrationsBlockedError";
5938
+ var AddonMigrationsBlockedError = class extends Error {
5939
+ /** The ledger ids that did not apply and block the owner. */
5940
+ migrationIds;
5941
+ constructor(migrationIds) {
5942
+ super(`migration(s) ${migrationIds.join(", ")} did not apply and block this addon — fix or retry them (migrations.retry), then restart it`);
5943
+ this.name = MIGRATIONS_BLOCKED_ERROR_NAME;
5944
+ this.migrationIds = migrationIds;
5945
+ }
5946
+ };
5925
5947
  /** Is this field's stored value a credential? */
5926
5948
  function isSecretConfigField(field) {
5927
5949
  if (field.type === "password") return true;
@@ -7528,7 +7550,7 @@ var BaseAddon = class {
7528
7550
  startMigration: (input) => api.startMigration.mutate(input),
7529
7551
  finishMigration: (input) => api.finishMigration.mutate(input)
7530
7552
  }, migrations, this.ctx.logger);
7531
- if (report.blockOwner.length > 0) throw new Error(`migration(s) ${report.blockOwner.join(", ")} did not apply and block this addon — fix or retry them (migrations.retry), then restart it`);
7553
+ if (report.blockOwner.length > 0) throw new AddonMigrationsBlockedError(report.blockOwner);
7532
7554
  return report;
7533
7555
  }
7534
7556
  /**
@@ -9282,6 +9304,7 @@ var CAP_NAMES = Object.freeze([
9282
9304
  "backup",
9283
9305
  "battery",
9284
9306
  "binary",
9307
+ "board-key-source",
9285
9308
  "brightness",
9286
9309
  "broker",
9287
9310
  "button",
@@ -9403,6 +9426,7 @@ var CAP_NAMES = Object.freeze([
9403
9426
  "privacy-mask",
9404
9427
  "ptz",
9405
9428
  "ptz-autotrack",
9429
+ "pump-cycle",
9406
9430
  "reboot",
9407
9431
  "record-entries",
9408
9432
  "recording",
@@ -10695,18 +10719,6 @@ Object.freeze({
10695
10719
  "path": "pumpRunning",
10696
10720
  "valueType": "boolean"
10697
10721
  },
10698
- {
10699
- "path": "pumpIntervalEnabled",
10700
- "valueType": "boolean"
10701
- },
10702
- {
10703
- "path": "pumpOnTime",
10704
- "valueType": "number"
10705
- },
10706
- {
10707
- "path": "pumpOffTime",
10708
- "valueType": "number"
10709
- },
10710
10722
  {
10711
10723
  "path": "lastDrink",
10712
10724
  "valueType": "number"
@@ -10830,6 +10842,20 @@ Object.freeze({
10830
10842
  "valueType": "number"
10831
10843
  }
10832
10844
  ],
10845
+ "pump-cycle": [
10846
+ {
10847
+ "path": "enabled",
10848
+ "valueType": "boolean"
10849
+ },
10850
+ {
10851
+ "path": "onTime",
10852
+ "valueType": "number"
10853
+ },
10854
+ {
10855
+ "path": "offTime",
10856
+ "valueType": "number"
10857
+ }
10858
+ ],
10833
10859
  "recording-archive": [
10834
10860
  {
10835
10861
  "path": "deviceId",
@@ -11279,7 +11305,7 @@ object({
11279
11305
  params: record(string(), union([string(), number()])).optional()
11280
11306
  });
11281
11307
  //#endregion
11282
- //#region ../types/dist/composition-Dh3RfMx5.mjs
11308
+ //#region ../types/dist/composition-BodkvOV0.mjs
11283
11309
  /**
11284
11310
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11285
11311
  *
@@ -12416,7 +12442,14 @@ var CompositionForwardCommandSchema = object({
12416
12442
  method: string().min(1),
12417
12443
  args: record(string().min(1), CompositionForwardArgSchema).optional()
12418
12444
  });
12419
- var CompositionCommandTargetSchema = discriminatedUnion("kind", [CompositionForwardCommandSchema, CompositionCodeSourceSchema]);
12445
+ var CompositionCommandTargetSchema = discriminatedUnion("kind", [
12446
+ CompositionForwardCommandSchema,
12447
+ CompositionCodeSourceSchema,
12448
+ object({
12449
+ kind: literal("extension"),
12450
+ target: literal("remote")
12451
+ })
12452
+ ]);
12420
12453
  /** An item key inside an item-array cap (`consumables.items[<key>]`). */
12421
12454
  var COMPOSITION_ITEM_KEY_RE = /^[a-z0-9][a-z0-9-]{0,47}$/;
12422
12455
  /**
@@ -18832,24 +18865,52 @@ var APPLIANCE_CAP_VOCABULARY = {
18832
18865
  args: { on: false }
18833
18866
  },
18834
18867
  {
18835
- id: "petFountain.intervalOn",
18836
- method: "setPumpInterval",
18868
+ id: "petFountain.resetDailyConsumption",
18869
+ method: "resetDailyConsumption",
18870
+ label: t("Clear daily consumption", "Azzera il consumo giornaliero"),
18871
+ phrase: t("Clear the daily water consumption of {device}", "Azzera il consumo giornaliero di acqua di {device}"),
18872
+ icon: "rotate-ccw"
18873
+ }
18874
+ ],
18875
+ state: [{
18876
+ kind: "boolean",
18877
+ field: "empty",
18878
+ label: t("Tank empty", "Serbatoio vuoto"),
18879
+ whenTrue: t("When the tank of {device} is empty", "Quando il serbatoio di {device} è vuoto"),
18880
+ whenFalse: t("When the tank of {device} is refilled", "Quando il serbatoio di {device} viene riempito"),
18881
+ icon: "droplet"
18882
+ }, {
18883
+ kind: "numeric",
18884
+ field: "waterLevel",
18885
+ quantity: t("the water level", "il livello dell’acqua"),
18886
+ label: t("Water level", "Livello dell’acqua"),
18887
+ unit: "%",
18888
+ icon: "droplets"
18889
+ }]
18890
+ },
18891
+ "pump-cycle": {
18892
+ scope: "device",
18893
+ noun: t("Pump cycle", "Ciclo della pompa"),
18894
+ actions: [
18895
+ {
18896
+ id: "pumpCycle.on",
18897
+ method: "setEnabled",
18837
18898
  label: t("Pump cycle on", "Ciclo pompa attivo"),
18838
18899
  phrase: t("Run the pump of {device} on its on/off cycle", "Fai lavorare la pompa di {device} a ciclo acceso/spento"),
18839
18900
  icon: "timer",
18840
18901
  args: { on: true }
18841
18902
  },
18842
18903
  {
18843
- id: "petFountain.intervalOff",
18844
- method: "setPumpInterval",
18904
+ id: "pumpCycle.off",
18905
+ method: "setEnabled",
18845
18906
  label: t("Pump cycle off", "Ciclo pompa spento"),
18846
18907
  phrase: t("Run the pump of {device} continuously", "Fai lavorare la pompa di {device} in continuo"),
18847
18908
  icon: "timer-off",
18848
18909
  args: { on: false }
18849
18910
  },
18850
18911
  {
18851
- id: "petFountain.pumpOnMinutes",
18852
- method: "setPumpOnMinutes",
18912
+ id: "pumpCycle.onMinutes",
18913
+ method: "setOnMinutes",
18853
18914
  label: t("Set pump run time", "Imposta il tempo di lavoro della pompa"),
18854
18915
  phrase: t("Set the pump of {device} to run {minutes} minutes per cycle", "Imposta la pompa di {device} a lavorare {minutes} minuti per ciclo"),
18855
18916
  icon: "timer",
@@ -18865,8 +18926,8 @@ var APPLIANCE_CAP_VOCABULARY = {
18865
18926
  }]
18866
18927
  },
18867
18928
  {
18868
- id: "petFountain.pumpOffMinutes",
18869
- method: "setPumpOffMinutes",
18929
+ id: "pumpCycle.offMinutes",
18930
+ method: "setOffMinutes",
18870
18931
  label: t("Set pump rest time", "Imposta il tempo di riposo della pompa"),
18871
18932
  phrase: t("Set the pump of {device} to rest {minutes} minutes per cycle", "Imposta la pompa di {device} a riposare {minutes} minuti per ciclo"),
18872
18933
  icon: "timer-off",
@@ -18880,35 +18941,63 @@ var APPLIANCE_CAP_VOCABULARY = {
18880
18941
  unit: "min"
18881
18942
  }
18882
18943
  }]
18883
- },
18884
- {
18885
- id: "petFountain.resetDailyConsumption",
18886
- method: "resetDailyConsumption",
18887
- label: t("Clear daily consumption", "Azzera il consumo giornaliero"),
18888
- phrase: t("Clear the daily water consumption of {device}", "Azzera il consumo giornaliero di acqua di {device}"),
18889
- icon: "rotate-ccw"
18890
18944
  }
18891
18945
  ],
18892
18946
  state: [{
18893
18947
  kind: "boolean",
18894
- field: "empty",
18895
- label: t("Tank empty", "Serbatoio vuoto"),
18896
- whenTrue: t("When the tank of {device} is empty", "Quando il serbatoio di {device} è vuoto"),
18897
- whenFalse: t("When the tank of {device} is refilled", "Quando il serbatoio di {device} viene riempito"),
18898
- icon: "droplet"
18899
- }, {
18900
- kind: "numeric",
18901
- field: "waterLevel",
18902
- quantity: t("the water level", "il livello dell’acqua"),
18903
- label: t("Water level", "Livello dell’acqua"),
18904
- unit: "%",
18905
- icon: "droplets"
18948
+ field: "enabled",
18949
+ label: t("Pump cycle", "Ciclo pompa"),
18950
+ whenTrue: t("When {device} starts running its pump on a cycle", "Quando {device} inizia a far lavorare la pompa a ciclo"),
18951
+ whenFalse: t("When {device} runs its pump continuously", "Quando {device} fa lavorare la pompa in continuo"),
18952
+ icon: "timer"
18906
18953
  }]
18907
18954
  },
18908
18955
  "media-player": {
18909
18956
  scope: "device",
18910
18957
  noun: t("Media player", "Lettore multimediale"),
18911
18958
  actions: [
18959
+ {
18960
+ id: "media.turnOn",
18961
+ method: "turnOn",
18962
+ label: t("Turn on", "Accendi"),
18963
+ phrase: t("Turn on {device}", "Accendi {device}"),
18964
+ icon: "power"
18965
+ },
18966
+ {
18967
+ id: "media.turnOff",
18968
+ method: "turnOff",
18969
+ label: t("Turn off", "Spegni"),
18970
+ phrase: t("Turn off {device}", "Spegni {device}"),
18971
+ icon: "power"
18972
+ },
18973
+ {
18974
+ id: "media.volumeUp",
18975
+ method: "volumeUp",
18976
+ label: t("Volume up", "Alza il volume"),
18977
+ phrase: t("Raise the volume of {device}", "Alza il volume di {device}"),
18978
+ icon: "volume-2"
18979
+ },
18980
+ {
18981
+ id: "media.volumeDown",
18982
+ method: "volumeDown",
18983
+ label: t("Volume down", "Abbassa il volume"),
18984
+ phrase: t("Lower the volume of {device}", "Abbassa il volume di {device}"),
18985
+ icon: "volume-2"
18986
+ },
18987
+ {
18988
+ id: "media.channelUp",
18989
+ method: "channelUp",
18990
+ label: t("Channel up", "Canale successivo"),
18991
+ phrase: t("Go to the next channel on {device}", "Passa al canale successivo su {device}"),
18992
+ icon: "skip-forward"
18993
+ },
18994
+ {
18995
+ id: "media.channelDown",
18996
+ method: "channelDown",
18997
+ label: t("Channel down", "Canale precedente"),
18998
+ phrase: t("Go to the previous channel on {device}", "Torna al canale precedente su {device}"),
18999
+ icon: "skip-back"
19000
+ },
18912
19001
  {
18913
19002
  id: "media.play",
18914
19003
  method: "play",
@@ -20795,6 +20884,7 @@ var SYSTEM_CAP_VOCABULARY = {
20795
20884
  "audio-analyzer": system(PIPELINE),
20796
20885
  "audio-codec": system(INTERNAL),
20797
20886
  "auth-provider": system(IDENTITY),
20887
+ "board-key-source": system(INTERNAL),
20798
20888
  backup: system("system backups — run and restored from the Backups page"),
20799
20889
  broker: system("message-broker connections — configured, not actuated"),
20800
20890
  "calendar-source": system(INTERNAL),
@@ -45238,6 +45328,49 @@ object({
45238
45328
  lastChangedAt: number()
45239
45329
  });
45240
45330
  DeviceType.Sensor;
45331
+ /**
45332
+ * Why a board key could not be read. Typed so a caller reports the cause and
45333
+ * never treats "could not read" as "has no key" (D49).
45334
+ */
45335
+ var BoardKeyFailureReasonSchema = _enum([
45336
+ "unknown-source",
45337
+ "not-admin",
45338
+ "no-builder",
45339
+ "no-ingress-url",
45340
+ "unreachable",
45341
+ "unknown-board",
45342
+ "no-encryption-key",
45343
+ "unreadable-config"
45344
+ ]);
45345
+ var BoardKeySourceSchema = object({
45346
+ sourceId: string(),
45347
+ name: string()
45348
+ });
45349
+ var BoardKeyBoardSchema = object({
45350
+ /** The builder's file name, e.g. `kitchen.yaml`: the handle `getBoardKey` takes. */
45351
+ configuration: string(),
45352
+ /** The node name the builder gives the board. */
45353
+ name: string(),
45354
+ /** The address the builder knows the board by, when it has one. */
45355
+ address: string().nullable()
45356
+ });
45357
+ var BoardKeyFailureSchema = object({
45358
+ ok: literal(false),
45359
+ reason: BoardKeyFailureReasonSchema,
45360
+ detail: string().optional()
45361
+ });
45362
+ var ListBoardsResultSchema = discriminatedUnion("ok", [object({
45363
+ ok: literal(true),
45364
+ boards: array(BoardKeyBoardSchema).readonly()
45365
+ }), BoardKeyFailureSchema]);
45366
+ var GetBoardKeyResultSchema = discriminatedUnion("ok", [object({
45367
+ ok: literal(true),
45368
+ key: string()
45369
+ }), BoardKeyFailureSchema]);
45370
+ method(_void(), array(BoardKeySourceSchema).readonly(), { auth: "admin" }), method(object({ sourceId: string().min(1) }), ListBoardsResultSchema, { auth: "admin" }), method(object({
45371
+ sourceId: string().min(1),
45372
+ configuration: string().min(1)
45373
+ }), GetBoardKeyResultSchema, { auth: "admin" });
45241
45374
  object({
45242
45375
  /** Current level as 0..100 inclusive. Firmware-reported. */
45243
45376
  level: number().min(0).max(100).meta(readingMeta("percentage")),
@@ -47315,6 +47448,188 @@ DeviceType.Control, method(object({
47315
47448
  kind: "mutation",
47316
47449
  auth: "protected"
47317
47450
  });
47451
+ /**
47452
+ * Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
47453
+ * Apple TV, Spotify, Roku, generic OTT receivers, …) on
47454
+ * `DeviceType.MediaPlayer`. Disjoint from the camera streaming
47455
+ * surface — those use `DeviceType.Camera` + the broker pipeline.
47456
+ *
47457
+ * The cap declares a wide method surface; not every backend supports
47458
+ * every method. Drivers signal sub-capability via the
47459
+ * `DeviceFeature.MediaPlayerXxx` flags (paired one-to-one with the
47460
+ * corresponding method) so the UI gates buttons without a slice
47461
+ * fetch — same pattern as `PanTiltZoom` for cameras.
47462
+ */
47463
+ var MediaPlayerStateSchema = _enum([
47464
+ "off",
47465
+ "on",
47466
+ "idle",
47467
+ "playing",
47468
+ "paused",
47469
+ "buffering",
47470
+ "standby"
47471
+ ]);
47472
+ var MediaPlayerRepeatSchema = _enum([
47473
+ "off",
47474
+ "all",
47475
+ "one"
47476
+ ]);
47477
+ var MediaInfoSchema = object({
47478
+ /** Free-form media kind (`music`, `tvshow`, `movie`, `app`, `channel`,
47479
+ * `podcast`, …). */
47480
+ type: string(),
47481
+ /** Human-readable title. */
47482
+ title: string(),
47483
+ /** Optional artist / channel / station label. */
47484
+ artist: string().optional(),
47485
+ /** Optional album / season / show name. */
47486
+ album: string().optional(),
47487
+ /** Optional cover-art / thumbnail URL. */
47488
+ imageUrl: string().optional()
47489
+ });
47490
+ /**
47491
+ * Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
47492
+ * the device said so. `assumed`: the driver has no feedback (infrared) and
47493
+ * tracks what it last SENT; it moves only after a send was accepted, and a
47494
+ * human at the real remote makes it wrong. A UI shows an assumed value as a
47495
+ * guess, never as a reading.
47496
+ */
47497
+ var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
47498
+ /** The fields of a media-player status a driver can only guess. */
47499
+ var MediaPlayerAssumedFieldSchema = _enum([
47500
+ "state",
47501
+ "volumeLevel",
47502
+ "isMuted",
47503
+ "source"
47504
+ ]);
47505
+ var MediaPlayerStatusSchema = object({
47506
+ /** Playback lifecycle state. */
47507
+ state: MediaPlayerStateSchema,
47508
+ /**
47509
+ * Whether the state fields are readings or the driver's own bookkeeping.
47510
+ * A slice written before this field existed parses as `reported`.
47511
+ */
47512
+ stateSource: MediaPlayerStateSourceSchema.default("reported"),
47513
+ /**
47514
+ * Which fields are the driver's own guess. `stateSource` is `assumed` when
47515
+ * this is not empty; a field not listed here is a reading even then (power
47516
+ * from a running-state source, mute guessed from the last send).
47517
+ */
47518
+ assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
47519
+ /** Volume as 0..100 inclusive. Null when the device has no volume
47520
+ * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
47521
+ volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
47522
+ /** Mute toggle distinct from volume=0. Null when no mute surface.
47523
+ * Pair with `DeviceFeature.MediaPlayerMute`. */
47524
+ isMuted: boolean().nullable(),
47525
+ /** Active source / input. Empty when no source surface. */
47526
+ source: string(),
47527
+ /** Selectable sources. Empty when no source surface.
47528
+ * Pair with `DeviceFeature.MediaPlayerSelectSource`. */
47529
+ availableSources: array(string()),
47530
+ /** Currently-playing media info. Null when nothing is playing. */
47531
+ currentMedia: MediaInfoSchema.nullable(),
47532
+ /** Current playback position in ms. Null when not seekable or
47533
+ * nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
47534
+ position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
47535
+ /** Total duration of the current media in ms. Null when unknown
47536
+ * (live stream) or nothing is playing. */
47537
+ duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
47538
+ /** Shuffle toggle. Null when no shuffle surface.
47539
+ * Pair with `DeviceFeature.MediaPlayerShuffle`. */
47540
+ shuffle: boolean().nullable(),
47541
+ /** Repeat mode. Null when no repeat surface.
47542
+ * Pair with `DeviceFeature.MediaPlayerRepeat`. */
47543
+ repeat: MediaPlayerRepeatSchema.nullable(),
47544
+ /** Ms epoch when the slice was last updated. */
47545
+ lastChangedAt: number()
47546
+ });
47547
+ var stepInput = object({
47548
+ deviceId: number().int().nonnegative(),
47549
+ /** How many presses: the caller's count (Alexa `volumeSteps`, `channelCount`). */
47550
+ steps: number().int().min(1).max(50).default(1)
47551
+ });
47552
+ var deviceOnly = object({ deviceId: number().int().nonnegative() });
47553
+ DeviceType.MediaPlayer, method(deviceOnly, _void(), {
47554
+ kind: "mutation",
47555
+ auth: "protected"
47556
+ }), method(deviceOnly, _void(), {
47557
+ kind: "mutation",
47558
+ auth: "protected"
47559
+ }), method(stepInput, _void(), {
47560
+ kind: "mutation",
47561
+ auth: "protected"
47562
+ }), method(stepInput, _void(), {
47563
+ kind: "mutation",
47564
+ auth: "protected"
47565
+ }), method(stepInput, _void(), {
47566
+ kind: "mutation",
47567
+ auth: "protected"
47568
+ }), method(stepInput, _void(), {
47569
+ kind: "mutation",
47570
+ auth: "protected"
47571
+ }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
47572
+ kind: "mutation",
47573
+ auth: "protected"
47574
+ }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
47575
+ kind: "mutation",
47576
+ auth: "protected"
47577
+ }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
47578
+ kind: "mutation",
47579
+ auth: "protected"
47580
+ }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
47581
+ kind: "mutation",
47582
+ auth: "protected"
47583
+ }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
47584
+ kind: "mutation",
47585
+ auth: "protected"
47586
+ }), method(object({
47587
+ deviceId: number().int().nonnegative(),
47588
+ position: number().int().nonnegative()
47589
+ }), _void(), {
47590
+ kind: "mutation",
47591
+ auth: "protected"
47592
+ }), method(object({
47593
+ deviceId: number().int().nonnegative(),
47594
+ volumeLevel: number().min(0).max(100)
47595
+ }), _void(), {
47596
+ kind: "mutation",
47597
+ auth: "protected"
47598
+ }), method(object({
47599
+ deviceId: number().int().nonnegative(),
47600
+ muted: boolean()
47601
+ }), _void(), {
47602
+ kind: "mutation",
47603
+ auth: "protected"
47604
+ }), method(object({
47605
+ deviceId: number().int().nonnegative(),
47606
+ shuffle: boolean()
47607
+ }), _void(), {
47608
+ kind: "mutation",
47609
+ auth: "protected"
47610
+ }), method(object({
47611
+ deviceId: number().int().nonnegative(),
47612
+ repeat: MediaPlayerRepeatSchema
47613
+ }), _void(), {
47614
+ kind: "mutation",
47615
+ auth: "protected"
47616
+ }), method(object({
47617
+ deviceId: number().int().nonnegative(),
47618
+ source: string().min(1)
47619
+ }), _void(), {
47620
+ kind: "mutation",
47621
+ auth: "protected"
47622
+ }), method(object({
47623
+ deviceId: number().int().nonnegative(),
47624
+ /** Media identifier / URL. */
47625
+ mediaId: string().min(1),
47626
+ /** Media kind (`music`, `tvshow`, `movie`, `app`, …) — provider
47627
+ * passes it through to the upstream service. */
47628
+ mediaType: string().min(1)
47629
+ }), _void(), {
47630
+ kind: "mutation",
47631
+ auth: "protected"
47632
+ });
47318
47633
  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.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, 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.Heater, 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.Heater, 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.Heater, 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.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, 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, DeviceType.Heater;
47319
47634
  var NUMBER = {
47320
47635
  kind: "fixed",
@@ -50900,7 +51215,7 @@ object({
50900
51215
  /** Ms epoch of the last value received from the appliance; 0 = never. */
50901
51216
  lastFetchedAt: number()
50902
51217
  });
50903
- var DeviceIdSchema$1 = number().int().nonnegative();
51218
+ var DeviceIdSchema$2 = number().int().nonnegative();
50904
51219
  /** A value a program option or setting can take. */
50905
51220
  var DishwasherValueSchema = union([
50906
51221
  boolean(),
@@ -50964,77 +51279,77 @@ var DishwasherOptionsSchema = object({
50964
51279
  options: array(DishwasherOptionDescriptorSchema)
50965
51280
  });
50966
51281
  DeviceType.Dishwasher, method(object({
50967
- deviceId: DeviceIdSchema$1,
51282
+ deviceId: DeviceIdSchema$2,
50968
51283
  program: string().min(1).optional(),
50969
51284
  options: record(string(), DishwasherValueSchema).optional()
50970
51285
  }), _void(), {
50971
51286
  kind: "mutation",
50972
51287
  auth: "protected"
50973
- }), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
51288
+ }), method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
50974
51289
  kind: "mutation",
50975
51290
  auth: "protected"
50976
- }), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
51291
+ }), method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
50977
51292
  kind: "mutation",
50978
51293
  auth: "protected"
50979
- }), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
51294
+ }), method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
50980
51295
  kind: "mutation",
50981
51296
  auth: "protected"
50982
51297
  }), method(object({
50983
- deviceId: DeviceIdSchema$1,
51298
+ deviceId: DeviceIdSchema$2,
50984
51299
  program: string().min(1)
50985
51300
  }), _void(), {
50986
51301
  kind: "mutation",
50987
51302
  auth: "protected"
50988
51303
  }), method(object({
50989
- deviceId: DeviceIdSchema$1,
51304
+ deviceId: DeviceIdSchema$2,
50990
51305
  on: boolean()
50991
51306
  }), _void(), {
50992
51307
  kind: "mutation",
50993
51308
  auth: "protected"
50994
51309
  }), method(object({
50995
- deviceId: DeviceIdSchema$1,
51310
+ deviceId: DeviceIdSchema$2,
50996
51311
  on: boolean()
50997
51312
  }), _void(), {
50998
51313
  kind: "mutation",
50999
51314
  auth: "protected"
51000
51315
  }), method(object({
51001
- deviceId: DeviceIdSchema$1,
51316
+ deviceId: DeviceIdSchema$2,
51002
51317
  on: boolean()
51003
51318
  }), _void(), {
51004
51319
  kind: "mutation",
51005
51320
  auth: "protected"
51006
51321
  }), method(object({
51007
- deviceId: DeviceIdSchema$1,
51322
+ deviceId: DeviceIdSchema$2,
51008
51323
  on: boolean()
51009
51324
  }), _void(), {
51010
51325
  kind: "mutation",
51011
51326
  auth: "protected"
51012
51327
  }), method(object({
51013
- deviceId: DeviceIdSchema$1,
51328
+ deviceId: DeviceIdSchema$2,
51014
51329
  on: boolean()
51015
51330
  }), _void(), {
51016
51331
  kind: "mutation",
51017
51332
  auth: "protected"
51018
51333
  }), method(object({
51019
- deviceId: DeviceIdSchema$1,
51334
+ deviceId: DeviceIdSchema$2,
51020
51335
  on: boolean()
51021
51336
  }), _void(), {
51022
51337
  kind: "mutation",
51023
51338
  auth: "protected"
51024
51339
  }), method(object({
51025
- deviceId: DeviceIdSchema$1,
51340
+ deviceId: DeviceIdSchema$2,
51026
51341
  on: boolean()
51027
51342
  }), _void(), {
51028
51343
  kind: "mutation",
51029
51344
  auth: "protected"
51030
51345
  }), method(object({
51031
- deviceId: DeviceIdSchema$1,
51346
+ deviceId: DeviceIdSchema$2,
51032
51347
  key: string().min(1),
51033
51348
  value: DishwasherValueSchema
51034
51349
  }), _void(), {
51035
51350
  kind: "mutation",
51036
51351
  auth: "protected"
51037
- }), method(object({ deviceId: DeviceIdSchema$1 }), DishwasherOptionsSchema, { auth: "protected" });
51352
+ }), method(object({ deviceId: DeviceIdSchema$2 }), DishwasherOptionsSchema, { auth: "protected" });
51038
51353
  /**
51039
51354
  * Palette entry ids (D939). Audio is the one gradient; `audio-*` leaves are
51040
51355
  * not entries. `heatmapScrub` is a mark, not an event kind.
@@ -54797,164 +55112,6 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
54797
55112
  ]);
54798
55113
  method(_void(), array(LoginMethodContributionSchema).readonly());
54799
55114
  /**
54800
- * Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
54801
- * Apple TV, Spotify, Roku, generic OTT receivers, …) on
54802
- * `DeviceType.MediaPlayer`. Disjoint from the camera streaming
54803
- * surface — those use `DeviceType.Camera` + the broker pipeline.
54804
- *
54805
- * The cap declares a wide method surface; not every backend supports
54806
- * every method. Drivers signal sub-capability via the
54807
- * `DeviceFeature.MediaPlayerXxx` flags (paired one-to-one with the
54808
- * corresponding method) so the UI gates buttons without a slice
54809
- * fetch — same pattern as `PanTiltZoom` for cameras.
54810
- */
54811
- var MediaPlayerStateSchema = _enum([
54812
- "off",
54813
- "on",
54814
- "idle",
54815
- "playing",
54816
- "paused",
54817
- "buffering",
54818
- "standby"
54819
- ]);
54820
- var MediaPlayerRepeatSchema = _enum([
54821
- "off",
54822
- "all",
54823
- "one"
54824
- ]);
54825
- var MediaInfoSchema = object({
54826
- /** Free-form media kind (`music`, `tvshow`, `movie`, `app`, `channel`,
54827
- * `podcast`, …). */
54828
- type: string(),
54829
- /** Human-readable title. */
54830
- title: string(),
54831
- /** Optional artist / channel / station label. */
54832
- artist: string().optional(),
54833
- /** Optional album / season / show name. */
54834
- album: string().optional(),
54835
- /** Optional cover-art / thumbnail URL. */
54836
- imageUrl: string().optional()
54837
- });
54838
- /**
54839
- * Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
54840
- * the device said so. `assumed`: the driver has no feedback (infrared) and
54841
- * tracks what it last SENT; it moves only after a send was accepted, and a
54842
- * human at the real remote makes it wrong. A UI shows an assumed value as a
54843
- * guess, never as a reading.
54844
- */
54845
- var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
54846
- /** The fields of a media-player status a driver can only guess. */
54847
- var MediaPlayerAssumedFieldSchema = _enum([
54848
- "state",
54849
- "volumeLevel",
54850
- "isMuted",
54851
- "source"
54852
- ]);
54853
- object({
54854
- /** Playback lifecycle state. */
54855
- state: MediaPlayerStateSchema,
54856
- /**
54857
- * Whether the state fields are readings or the driver's own bookkeeping.
54858
- * A slice written before this field existed parses as `reported`.
54859
- */
54860
- stateSource: MediaPlayerStateSourceSchema.default("reported"),
54861
- /**
54862
- * Which fields are the driver's own guess. `stateSource` is `assumed` when
54863
- * this is not empty; a field not listed here is a reading even then (power
54864
- * from a running-state source, mute guessed from the last send).
54865
- */
54866
- assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
54867
- /** Volume as 0..100 inclusive. Null when the device has no volume
54868
- * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
54869
- volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
54870
- /** Mute toggle distinct from volume=0. Null when no mute surface.
54871
- * Pair with `DeviceFeature.MediaPlayerMute`. */
54872
- isMuted: boolean().nullable(),
54873
- /** Active source / input. Empty when no source surface. */
54874
- source: string(),
54875
- /** Selectable sources. Empty when no source surface.
54876
- * Pair with `DeviceFeature.MediaPlayerSelectSource`. */
54877
- availableSources: array(string()),
54878
- /** Currently-playing media info. Null when nothing is playing. */
54879
- currentMedia: MediaInfoSchema.nullable(),
54880
- /** Current playback position in ms. Null when not seekable or
54881
- * nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
54882
- position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
54883
- /** Total duration of the current media in ms. Null when unknown
54884
- * (live stream) or nothing is playing. */
54885
- duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
54886
- /** Shuffle toggle. Null when no shuffle surface.
54887
- * Pair with `DeviceFeature.MediaPlayerShuffle`. */
54888
- shuffle: boolean().nullable(),
54889
- /** Repeat mode. Null when no repeat surface.
54890
- * Pair with `DeviceFeature.MediaPlayerRepeat`. */
54891
- repeat: MediaPlayerRepeatSchema.nullable(),
54892
- /** Ms epoch when the slice was last updated. */
54893
- lastChangedAt: number()
54894
- });
54895
- DeviceType.MediaPlayer, method(object({ deviceId: number().int().nonnegative() }), _void(), {
54896
- kind: "mutation",
54897
- auth: "protected"
54898
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54899
- kind: "mutation",
54900
- auth: "protected"
54901
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54902
- kind: "mutation",
54903
- auth: "protected"
54904
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54905
- kind: "mutation",
54906
- auth: "protected"
54907
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54908
- kind: "mutation",
54909
- auth: "protected"
54910
- }), method(object({
54911
- deviceId: number().int().nonnegative(),
54912
- position: number().int().nonnegative()
54913
- }), _void(), {
54914
- kind: "mutation",
54915
- auth: "protected"
54916
- }), method(object({
54917
- deviceId: number().int().nonnegative(),
54918
- volumeLevel: number().min(0).max(100)
54919
- }), _void(), {
54920
- kind: "mutation",
54921
- auth: "protected"
54922
- }), method(object({
54923
- deviceId: number().int().nonnegative(),
54924
- muted: boolean()
54925
- }), _void(), {
54926
- kind: "mutation",
54927
- auth: "protected"
54928
- }), method(object({
54929
- deviceId: number().int().nonnegative(),
54930
- shuffle: boolean()
54931
- }), _void(), {
54932
- kind: "mutation",
54933
- auth: "protected"
54934
- }), method(object({
54935
- deviceId: number().int().nonnegative(),
54936
- repeat: MediaPlayerRepeatSchema
54937
- }), _void(), {
54938
- kind: "mutation",
54939
- auth: "protected"
54940
- }), method(object({
54941
- deviceId: number().int().nonnegative(),
54942
- source: string().min(1)
54943
- }), _void(), {
54944
- kind: "mutation",
54945
- auth: "protected"
54946
- }), method(object({
54947
- deviceId: number().int().nonnegative(),
54948
- /** Media identifier / URL. */
54949
- mediaId: string().min(1),
54950
- /** Media kind (`music`, `tvshow`, `movie`, `app`, …) — provider
54951
- * passes it through to the upstream service. */
54952
- mediaType: string().min(1)
54953
- }), _void(), {
54954
- kind: "mutation",
54955
- auth: "protected"
54956
- });
54957
- /**
54958
55115
  * mesh-network — collection cap for mesh-VPN providers.
54959
55116
  *
54960
55117
  * Different shape from `network-access` (public tunnels):
@@ -63247,6 +63404,21 @@ var NcTemplateVarKindSchema = _enum([
63247
63404
  "sound",
63248
63405
  "system"
63249
63406
  ]);
63407
+ /**
63408
+ * The default title/body a rule of one SITUATION is delivered with when the
63409
+ * operator wrote no template — served so an editor can pre-fill it (and the
63410
+ * operator can rebuild it from placeholders) instead of starting from a blank
63411
+ * box that, once saved, silently replaces it. `id` names the situation inside
63412
+ * a rule `kind`: `appliance-cycle` is a `sensor` rule whose device is an
63413
+ * appliance finishing a cycle. Texts are raw templates (`{{var}}` intact), in
63414
+ * the hub's current language and with its overrides applied.
63415
+ */
63416
+ var NcTemplateDefaultSchema = object({
63417
+ id: _enum(["appliance-cycle"]),
63418
+ kind: NcRuleKindSchema,
63419
+ title: string(),
63420
+ body: string()
63421
+ });
63250
63422
  /** Which producer renders a template: an ordinary rule, a timelapse, a digest. */
63251
63423
  var NcTemplateFamilySchema = _enum([
63252
63424
  "rule",
@@ -64102,7 +64274,11 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
64102
64274
  }), method(object({}), object({
64103
64275
  catalog: array(NcConditionDescriptorSchema),
64104
64276
  taxonomy: NcTaxonomySchema.optional()
64105
- })), method(object({}), object({ vars: array(NcTemplateVarDescriptorSchema) })), method(NcTemplatePreviewInputSchema, NcTemplatePreviewSchema, {
64277
+ })), method(object({}), object({
64278
+ vars: array(NcTemplateVarDescriptorSchema),
64279
+ /** Per-situation default texts; absent on a hub that predates them. */
64280
+ defaults: array(NcTemplateDefaultSchema)
64281
+ })), method(NcTemplatePreviewInputSchema, NcTemplatePreviewSchema, {
64106
64282
  kind: "mutation",
64107
64283
  access: "view"
64108
64284
  }), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }), method(object({}), NcRuleLastRunsSchema, { auth: "admin" }), method(object({ artifactId: string().min(1) }), object({ url: string().nullable() }), { auth: "admin" }), method(object({}), object({ snoozes: array(NcSnoozeSchema) }), { caller: "required" }), method(object({ snooze: NcSnoozeInputSchema }), object({ snooze: NcSnoozeSchema }), {
@@ -64850,52 +65026,27 @@ object({
64850
65026
  empty: boolean().nullable(),
64851
65027
  /** True while the pump is running. Null while unknown. */
64852
65028
  pumpRunning: boolean().nullable(),
64853
- /** True when the pump works on an on/off duty cycle rather than continuously. */
64854
- pumpIntervalEnabled: boolean().nullable(),
64855
- /** How long the pump runs per cycle, in seconds. */
64856
- pumpOnTime: number().min(0).nullable().meta(readingMeta("duration")),
64857
- /** How long the pump rests per cycle, in seconds. */
64858
- pumpOffTime: number().min(0).nullable().meta(readingMeta("duration")),
64859
65029
  /** Water drunk in the last drink, in litres. */
64860
65030
  lastDrink: number().min(0).nullable().meta(readingMeta("volume")),
64861
65031
  /** Water drunk in the current hour, in litres. */
64862
65032
  currentHourDrink: number().min(0).nullable().meta(readingMeta("volume")),
64863
65033
  /** Water drunk over the last 24 hours (rolling), in litres. */
64864
65034
  last24hDrink: number().min(0).nullable().meta(readingMeta("volume")),
64865
- /** Water drunk since local midnight, in litres. */
65035
+ /** Water drunk since local midnight, in litres. Null when the fountain has no such sensor. */
64866
65036
  todayDrink: number().min(0).nullable().meta(readingMeta("volume")),
64867
65037
  /** Decoded fault message. Null means healthy; a non-null string is an active fault. */
64868
65038
  error: string().nullable(),
64869
65039
  /** Ms epoch when the slice was last refreshed. */
64870
65040
  lastFetchedAt: number()
64871
65041
  });
64872
- var DeviceIdSchema = number().int().nonnegative();
64873
- var MinutesSchema = number().int().min(0);
65042
+ var DeviceIdSchema$1 = number().int().nonnegative();
64874
65043
  DeviceType.PetFountain, method(object({
64875
- deviceId: DeviceIdSchema,
64876
- on: boolean()
64877
- }), _void(), {
64878
- kind: "mutation",
64879
- auth: "protected"
64880
- }), method(object({
64881
- deviceId: DeviceIdSchema,
65044
+ deviceId: DeviceIdSchema$1,
64882
65045
  on: boolean()
64883
65046
  }), _void(), {
64884
65047
  kind: "mutation",
64885
65048
  auth: "protected"
64886
- }), method(object({
64887
- deviceId: DeviceIdSchema,
64888
- minutes: MinutesSchema
64889
- }), _void(), {
64890
- kind: "mutation",
64891
- auth: "protected"
64892
- }), method(object({
64893
- deviceId: DeviceIdSchema,
64894
- minutes: MinutesSchema
64895
- }), _void(), {
64896
- kind: "mutation",
64897
- auth: "protected"
64898
- }), method(object({ deviceId: DeviceIdSchema }), _void(), {
65049
+ }), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
64899
65050
  kind: "mutation",
64900
65051
  auth: "protected"
64901
65052
  });
@@ -66855,6 +67006,37 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
66855
67006
  deviceId: number(),
66856
67007
  status: PtzAutotrackStatusSchema
66857
67008
  });
67009
+ object({
67010
+ /** True when the pump works on the on/off cycle, false when it runs continuously. Null while unknown. */
67011
+ enabled: boolean().nullable(),
67012
+ /** How long the pump runs per cycle, in seconds. Null while unknown. */
67013
+ onTime: number().min(0).nullable().meta(readingMeta("duration")),
67014
+ /** How long the pump rests per cycle, in seconds. Null while unknown. */
67015
+ offTime: number().min(0).nullable().meta(readingMeta("duration")),
67016
+ /** Ms epoch when the slice was last refreshed. */
67017
+ lastFetchedAt: number()
67018
+ });
67019
+ var DeviceIdSchema = number().int().nonnegative();
67020
+ var MinutesSchema = number().int().min(0);
67021
+ DeviceType.PetFountain, method(object({
67022
+ deviceId: DeviceIdSchema,
67023
+ on: boolean()
67024
+ }), _void(), {
67025
+ kind: "mutation",
67026
+ auth: "protected"
67027
+ }), method(object({
67028
+ deviceId: DeviceIdSchema,
67029
+ minutes: MinutesSchema
67030
+ }), _void(), {
67031
+ kind: "mutation",
67032
+ auth: "protected"
67033
+ }), method(object({
67034
+ deviceId: DeviceIdSchema,
67035
+ minutes: MinutesSchema
67036
+ }), _void(), {
67037
+ kind: "mutation",
67038
+ auth: "protected"
67039
+ });
66858
67040
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, DeviceType.Gateway, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
66859
67041
  kind: "mutation",
66860
67042
  auth: "admin"
@@ -69568,7 +69750,13 @@ var RemoteMediaCommandSchema = _enum([
69568
69750
  "next",
69569
69751
  "previous",
69570
69752
  "setMute",
69571
- "selectSource"
69753
+ "selectSource",
69754
+ "turnOn",
69755
+ "turnOff",
69756
+ "volumeUp",
69757
+ "volumeDown",
69758
+ "channelUp",
69759
+ "channelDown"
69572
69760
  ]);
69573
69761
  /** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
69574
69762
  var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
@@ -69589,7 +69777,7 @@ method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.e
69589
69777
  }), RemoteSendResultSchema, {
69590
69778
  kind: "mutation",
69591
69779
  auth: "protected"
69592
- }), method(deviceInput.extend({
69780
+ }), method(deviceInput, MediaPlayerStatusSchema.nullable(), { auth: "protected" }), method(deviceInput.extend({
69593
69781
  command: RemoteMediaCommandSchema,
69594
69782
  muted: boolean().optional(),
69595
69783
  source: string().optional(),
@@ -71417,7 +71605,11 @@ object({
71417
71605
  });
71418
71606
  Object.values(DeviceType), method(_void(), array(StreamSignalSchema).readonly());
71419
71607
  object({
71420
- on: boolean().meta({ label: "On" }),
71608
+ /**
71609
+ * `null` = the device has never reported its state (a measurement that
71610
+ * has not happened is unknown, never `false`).
71611
+ */
71612
+ on: boolean().nullable().meta({ label: "On" }),
71421
71613
  /** Ms epoch of the last state change. Useful for UI "X minutes ago". */
71422
71614
  lastChangedAt: number()
71423
71615
  });
@@ -71429,7 +71621,7 @@ DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceTyp
71429
71621
  auth: "protected"
71430
71622
  }), object({
71431
71623
  deviceId: number(),
71432
- on: boolean(),
71624
+ on: boolean().nullable(),
71433
71625
  lastChangedAt: number()
71434
71626
  });
71435
71627
  /** C0 controls, DEL and the C1 range: none of them belongs in a name. */
@@ -74441,6 +74633,7 @@ function buildDescriptor(capName, kind) {
74441
74633
  * contributes one entry per bound cap present in this map.
74442
74634
  */
74443
74635
  var EVENT_KIND_BY_CAP = Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
74636
+ DeviceFeature.MediaPlayerPower, DeviceFeature.MediaPlayerVolumeStep, DeviceFeature.MediaPlayerChannelStep, DeviceFeature.MediaPlayerMute, DeviceFeature.MediaPlayerStop, DeviceFeature.MediaPlayerNext, DeviceFeature.MediaPlayerPrevious;
74444
74637
  var btn = (idSuffix, row, col, init) => ({
74445
74638
  idSuffix,
74446
74639
  row,
@@ -75548,6 +75741,27 @@ Object.freeze({
75548
75741
  access: "view",
75549
75742
  role: "viewer"
75550
75743
  },
75744
+ "boardKeySource.getBoardKey": {
75745
+ capName: "board-key-source",
75746
+ capScope: "system",
75747
+ addonId: null,
75748
+ access: "view",
75749
+ role: "admin"
75750
+ },
75751
+ "boardKeySource.listBoards": {
75752
+ capName: "board-key-source",
75753
+ capScope: "system",
75754
+ addonId: null,
75755
+ access: "view",
75756
+ role: "admin"
75757
+ },
75758
+ "boardKeySource.listSources": {
75759
+ capName: "board-key-source",
75760
+ capScope: "system",
75761
+ addonId: null,
75762
+ access: "view",
75763
+ role: "admin"
75764
+ },
75551
75765
  "brightness.getStatus": {
75552
75766
  capName: "brightness",
75553
75767
  capScope: "device",
@@ -79034,6 +79248,20 @@ Object.freeze({
79034
79248
  access: "view",
79035
79249
  role: "admin"
79036
79250
  },
79251
+ "mediaPlayer.channelDown": {
79252
+ capName: "media-player",
79253
+ capScope: "device",
79254
+ addonId: null,
79255
+ access: "create",
79256
+ role: "viewer"
79257
+ },
79258
+ "mediaPlayer.channelUp": {
79259
+ capName: "media-player",
79260
+ capScope: "device",
79261
+ addonId: null,
79262
+ access: "create",
79263
+ role: "viewer"
79264
+ },
79037
79265
  "mediaPlayer.getStatus": {
79038
79266
  capName: "media-player",
79039
79267
  capScope: "device",
@@ -79125,6 +79353,34 @@ Object.freeze({
79125
79353
  access: "create",
79126
79354
  role: "viewer"
79127
79355
  },
79356
+ "mediaPlayer.turnOff": {
79357
+ capName: "media-player",
79358
+ capScope: "device",
79359
+ addonId: null,
79360
+ access: "create",
79361
+ role: "viewer"
79362
+ },
79363
+ "mediaPlayer.turnOn": {
79364
+ capName: "media-player",
79365
+ capScope: "device",
79366
+ addonId: null,
79367
+ access: "create",
79368
+ role: "viewer"
79369
+ },
79370
+ "mediaPlayer.volumeDown": {
79371
+ capName: "media-player",
79372
+ capScope: "device",
79373
+ addonId: null,
79374
+ access: "create",
79375
+ role: "viewer"
79376
+ },
79377
+ "mediaPlayer.volumeUp": {
79378
+ capName: "media-player",
79379
+ capScope: "device",
79380
+ addonId: null,
79381
+ access: "create",
79382
+ role: "viewer"
79383
+ },
79128
79384
  "meshNetwork.getStatus": {
79129
79385
  capName: "mesh-network",
79130
79386
  capScope: "system",
@@ -80371,27 +80627,6 @@ Object.freeze({
80371
80627
  access: "create",
80372
80628
  role: "viewer"
80373
80629
  },
80374
- "petFountain.setPumpInterval": {
80375
- capName: "pet-fountain",
80376
- capScope: "device",
80377
- addonId: null,
80378
- access: "create",
80379
- role: "viewer"
80380
- },
80381
- "petFountain.setPumpOffMinutes": {
80382
- capName: "pet-fountain",
80383
- capScope: "device",
80384
- addonId: null,
80385
- access: "create",
80386
- role: "viewer"
80387
- },
80388
- "petFountain.setPumpOnMinutes": {
80389
- capName: "pet-fountain",
80390
- capScope: "device",
80391
- addonId: null,
80392
- access: "create",
80393
- role: "viewer"
80394
- },
80395
80630
  "pipelineAnalytics.addRetrainFrameFromRecording": {
80396
80631
  capName: "pipeline-analytics",
80397
80632
  capScope: "device",
@@ -82170,6 +82405,34 @@ Object.freeze({
82170
82405
  access: "create",
82171
82406
  role: "admin"
82172
82407
  },
82408
+ "pumpCycle.getStatus": {
82409
+ capName: "pump-cycle",
82410
+ capScope: "device",
82411
+ addonId: null,
82412
+ access: "view",
82413
+ role: "viewer"
82414
+ },
82415
+ "pumpCycle.setEnabled": {
82416
+ capName: "pump-cycle",
82417
+ capScope: "device",
82418
+ addonId: null,
82419
+ access: "create",
82420
+ role: "viewer"
82421
+ },
82422
+ "pumpCycle.setOffMinutes": {
82423
+ capName: "pump-cycle",
82424
+ capScope: "device",
82425
+ addonId: null,
82426
+ access: "create",
82427
+ role: "viewer"
82428
+ },
82429
+ "pumpCycle.setOnMinutes": {
82430
+ capName: "pump-cycle",
82431
+ capScope: "device",
82432
+ addonId: null,
82433
+ access: "create",
82434
+ role: "viewer"
82435
+ },
82173
82436
  "reboot.reboot": {
82174
82437
  capName: "reboot",
82175
82438
  capScope: "device",
@@ -82674,6 +82937,13 @@ Object.freeze({
82674
82937
  access: "create",
82675
82938
  role: "admin"
82676
82939
  },
82940
+ "remote.getAssumedStatus": {
82941
+ capName: "remote",
82942
+ capScope: "system",
82943
+ addonId: null,
82944
+ access: "view",
82945
+ role: "admin"
82946
+ },
82677
82947
  "remote.getConfig": {
82678
82948
  capName: "remote",
82679
82949
  capScope: "system",
@@ -86340,6 +86610,16 @@ Object.freeze({
86340
86610
  form: "single",
86341
86611
  optional: true
86342
86612
  }],
86613
+ "mediaPlayer.channelDown": [{
86614
+ name: "deviceId",
86615
+ form: "single",
86616
+ optional: false
86617
+ }],
86618
+ "mediaPlayer.channelUp": [{
86619
+ name: "deviceId",
86620
+ form: "single",
86621
+ optional: false
86622
+ }],
86343
86623
  "mediaPlayer.getStatus": [{
86344
86624
  name: "deviceId",
86345
86625
  form: "single",
@@ -86405,6 +86685,26 @@ Object.freeze({
86405
86685
  form: "single",
86406
86686
  optional: false
86407
86687
  }],
86688
+ "mediaPlayer.turnOff": [{
86689
+ name: "deviceId",
86690
+ form: "single",
86691
+ optional: false
86692
+ }],
86693
+ "mediaPlayer.turnOn": [{
86694
+ name: "deviceId",
86695
+ form: "single",
86696
+ optional: false
86697
+ }],
86698
+ "mediaPlayer.volumeDown": [{
86699
+ name: "deviceId",
86700
+ form: "single",
86701
+ optional: false
86702
+ }],
86703
+ "mediaPlayer.volumeUp": [{
86704
+ name: "deviceId",
86705
+ form: "single",
86706
+ optional: false
86707
+ }],
86408
86708
  "meter.getStatus": [{
86409
86709
  name: "deviceId",
86410
86710
  form: "single",
@@ -86714,21 +87014,6 @@ Object.freeze({
86714
87014
  form: "single",
86715
87015
  optional: false
86716
87016
  }],
86717
- "petFountain.setPumpInterval": [{
86718
- name: "deviceId",
86719
- form: "single",
86720
- optional: false
86721
- }],
86722
- "petFountain.setPumpOffMinutes": [{
86723
- name: "deviceId",
86724
- form: "single",
86725
- optional: false
86726
- }],
86727
- "petFountain.setPumpOnMinutes": [{
86728
- name: "deviceId",
86729
- form: "single",
86730
- optional: false
86731
- }],
86732
87017
  "pipelineAnalytics.addRetrainFrameFromRecording": [{
86733
87018
  name: "deviceId",
86734
87019
  form: "single",
@@ -87364,6 +87649,26 @@ Object.freeze({
87364
87649
  form: "single",
87365
87650
  optional: false
87366
87651
  }],
87652
+ "pumpCycle.getStatus": [{
87653
+ name: "deviceId",
87654
+ form: "single",
87655
+ optional: false
87656
+ }],
87657
+ "pumpCycle.setEnabled": [{
87658
+ name: "deviceId",
87659
+ form: "single",
87660
+ optional: false
87661
+ }],
87662
+ "pumpCycle.setOffMinutes": [{
87663
+ name: "deviceId",
87664
+ form: "single",
87665
+ optional: false
87666
+ }],
87667
+ "pumpCycle.setOnMinutes": [{
87668
+ name: "deviceId",
87669
+ form: "single",
87670
+ optional: false
87671
+ }],
87367
87672
  "reboot.reboot": [{
87368
87673
  name: "deviceId",
87369
87674
  form: "single",
@@ -87565,6 +87870,11 @@ Object.freeze({
87565
87870
  form: "single",
87566
87871
  optional: true
87567
87872
  }],
87873
+ "remote.getAssumedStatus": [{
87874
+ name: "deviceId",
87875
+ form: "single",
87876
+ optional: false
87877
+ }],
87568
87878
  "remote.getConfig": [{
87569
87879
  name: "deviceId",
87570
87880
  form: "single",
@@ -88820,6 +89130,7 @@ var STATE_SUMMARY_VARS = [
88820
89130
  [...RULE_TEXT],
88821
89131
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
88822
89132
  ([...RULE_TEXT], [...COMBINED_ALARM]),
89133
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
88823
89134
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
88824
89135
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
88825
89136
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -89555,7 +89866,7 @@ var AgentUIAddon = class extends BaseAddon {
89555
89866
  capability: adminUiCapability,
89556
89867
  provider: {
89557
89868
  getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
89558
- getVersion: async () => ({ version: "1.2.316" })
89869
+ getVersion: async () => ({ version: "1.2.318" })
89559
89870
  }
89560
89871
  }];
89561
89872
  }