@camstack/addon-provider-reolink 1.2.204 → 1.2.206

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.
Files changed (3) hide show
  1. package/dist/addon.js +297 -122
  2. package/dist/addon.mjs +297 -122
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -5468,7 +5468,7 @@ var ZodIssueCode = {
5468
5468
  var ZodFirstPartyTypeKind;
5469
5469
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5470
5470
  //#endregion
5471
- //#region ../types/dist/sleep-DJFUfKvA.mjs
5471
+ //#region ../types/dist/sleep-CUp20JkO.mjs
5472
5472
  /**
5473
5473
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5474
5474
  * window to float samples (D455).
@@ -8364,7 +8364,11 @@ var ContributionSectionSchema = object({
8364
8364
  literal(4)
8365
8365
  ]).optional(),
8366
8366
  tab: string().optional(),
8367
- location: _enum(["settings", "top-tab"]).optional(),
8367
+ location: _enum([
8368
+ "settings",
8369
+ "top-tab",
8370
+ "hero"
8371
+ ]).optional(),
8368
8372
  order: number().optional(),
8369
8373
  fields: array(any())
8370
8374
  });
@@ -13911,7 +13915,11 @@ var ConfigSectionWithValuesSchema = object({
13911
13915
  literal(4)
13912
13916
  ]).optional(),
13913
13917
  tab: string().optional(),
13914
- location: _enum(["settings", "top-tab"]).optional(),
13918
+ location: _enum([
13919
+ "settings",
13920
+ "top-tab",
13921
+ "hero"
13922
+ ]).optional(),
13915
13923
  order: number().optional(),
13916
13924
  fields: array(any())
13917
13925
  });
@@ -17791,6 +17799,52 @@ var TierStatusSchema = object({
17791
17799
  countedAt: number().nullable()
17792
17800
  });
17793
17801
  /** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
17802
+ /**
17803
+ * Why a series is orphan. `device-gone`: its device is absent from the
17804
+ * successful device listings (the departure clock). `undeclared`: its `cap:`
17805
+ * key is declared by no capability any more (a field a cap removed).
17806
+ */
17807
+ var DeviceHistoryOrphanReasonSchema = _enum(["device-gone", "undeclared"]);
17808
+ /** Rows held per stored tier. */
17809
+ var TierRowsSchema = object({
17810
+ raw: number().int(),
17811
+ "5m": number().int(),
17812
+ "1h": number().int(),
17813
+ "1d": number().int()
17814
+ });
17815
+ var OrphanSeriesSchema = object({
17816
+ seriesId: number().int(),
17817
+ deviceId: number().int(),
17818
+ key: string(),
17819
+ scope: string(),
17820
+ /** The metric's display name; `null` when its metric row is gone too. */
17821
+ displayName: string().nullable(),
17822
+ reason: DeviceHistoryOrphanReasonSchema,
17823
+ /** `device-gone`: since when the device has been absent; `null` otherwise. */
17824
+ missingSince: number().nullable(),
17825
+ firstTs: number(),
17826
+ lastTs: number(),
17827
+ rows: TierRowsSchema
17828
+ });
17829
+ var DeviceHistoryOrphanDeleteRefusalSchema = _enum([
17830
+ "not-found",
17831
+ "not-orphan",
17832
+ "failed"
17833
+ ]);
17834
+ var OrphanDeleteEntrySchema = discriminatedUnion("ok", [object({
17835
+ seriesId: number().int(),
17836
+ ok: literal(true),
17837
+ deleted: TierRowsSchema
17838
+ }), object({
17839
+ seriesId: number().int(),
17840
+ ok: literal(false),
17841
+ reason: DeviceHistoryOrphanDeleteRefusalSchema
17842
+ })]);
17843
+ var OrphanListSchema = object({
17844
+ series: array(OrphanSeriesSchema).readonly(),
17845
+ /** More orphans exist than {@link DEVICE_HISTORY_ORPHAN_LIST_MAX}. */
17846
+ truncated: boolean()
17847
+ });
17794
17848
  var DeviceHistoryStatusSchema = object({
17795
17849
  startedAt: number(),
17796
17850
  /** The store is declared, series loaded and the first reconcile has answered. */
@@ -17888,7 +17942,10 @@ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly())
17888
17942
  }), object({ enabled: boolean() }), {
17889
17943
  kind: "mutation",
17890
17944
  auth: "admin"
17891
- }), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" });
17945
+ }), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" }), method(object({}), OrphanListSchema, { auth: "admin" }), method(object({ seriesIds: array(number().int()).min(1).max(50) }), object({ results: array(OrphanDeleteEntrySchema).readonly() }), {
17946
+ kind: "mutation",
17947
+ auth: "admin"
17948
+ });
17892
17949
  var DeviceCaStatusSchema = discriminatedUnion("state", [
17893
17950
  object({ state: literal("absent") }),
17894
17951
  object({
@@ -50995,6 +51052,19 @@ var NodeInferenceDeviceSchema = object({
50995
51052
  /** Whether the node's live probe reports the device as usable right now. */
50996
51053
  available: boolean(),
50997
51054
  /**
51055
+ * Is the device on the node at all (D919)? `present` — the live probe
51056
+ * reported it; `absent` — the probe ANSWERED and did not report it, so only
51057
+ * its stored settings remain (unplugged, moved to another node): never
51058
+ * eligible, whatever its stored `enabled`, and forgettable with
51059
+ * `forgetInferenceDevice`; `unknown` — the probe did not answer, nothing is
51060
+ * claimed (D315). Optional only for an orchestrator older than the field.
51061
+ */
51062
+ presence: _enum([
51063
+ "present",
51064
+ "absent",
51065
+ "unknown"
51066
+ ]).optional(),
51067
+ /**
50998
51068
  * Whether this device participates in dispatch. AUTO default (spec C2):
50999
51069
  * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
51000
51070
  * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
@@ -51220,7 +51290,13 @@ method(object({
51220
51290
  }), object({ success: literal(true) }), {
51221
51291
  kind: "mutation",
51222
51292
  auth: "admin"
51223
- }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
51293
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({
51294
+ agentNodeId: string(),
51295
+ deviceKey: string()
51296
+ }), object({ success: literal(true) }), {
51297
+ kind: "mutation",
51298
+ auth: "admin"
51299
+ }), method(object({ agentNodeId: string() }), object({
51224
51300
  success: literal(true),
51225
51301
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
51226
51302
  effectiveModelId: string().nullable(),
@@ -56406,17 +56482,69 @@ var connectivityCapability = {
56406
56482
  volatileStateFields: ["lastChangedAt"]
56407
56483
  };
56408
56484
  /**
56409
- * Generic device-consumables capability — surfaces a device's
56410
- * maintenance items (vacuum filters/brushes, replaceable cartridges,
56411
- * descaling cycles, …) with their remaining life and an optional
56412
- * "Replaced" reset action. Device-agnostic: any provider that knows its
56413
- * device tracks consumables can register it; the cap declares no
56414
- * vocabulary of its own — the provider names each item verbatim.
56485
+ * Generic device-consumables capability — the ONE place a device reports what
56486
+ * it uses up or fills: wear parts (vacuum filters/brushes, cartridges,
56487
+ * descaling cycles), supplies it draws from (a vacuum's clean-water tank and
56488
+ * detergent, a dishwasher's salt and rinse aid) and waste it collects (a dirty
56489
+ * water tank, a dust bin). Each item carries its remaining life or fill and an
56490
+ * optional "Replaced" reset action. Device-agnostic: any provider that knows
56491
+ * its device tracks consumables registers it; the provider names each item
56492
+ * verbatim and says which `kind` it is.
56493
+ *
56494
+ * The admin UI renders it as ONE collapsible section directly under the
56495
+ * device page's hero card (`placement: 'hero'`), for every device bound to
56496
+ * this cap — never drawn by a device type's hero card itself (D915).
56415
56497
  *
56416
56498
  * Like `childLayout`, the cap is INERT until a provider sets items: no
56417
56499
  * provider populates it by guessing (no HA inference). The UI renders a
56418
56500
  * "No consumables reported" placeholder when `items` is empty.
56419
56501
  */
56502
+ /**
56503
+ * What an item IS, which decides which direction is bad:
56504
+ * - `wear` — a part that wears out (a brush, a filter); low life is bad.
56505
+ * - `supply` — something the device draws from (clean water, detergent,
56506
+ * salt, rinse aid); low or empty is bad.
56507
+ * - `waste` — something the device fills (dirty water, a dust bin); full is
56508
+ * bad.
56509
+ * Absent = `wear`.
56510
+ */
56511
+ var ConsumableKindSchema = _enum([
56512
+ "wear",
56513
+ "supply",
56514
+ "waste"
56515
+ ]);
56516
+ /**
56517
+ * What an item LOOKS like, which decides how a client draws it — independent
56518
+ * of `kind`, which decides which direction is bad:
56519
+ * - `part` — a part that wears (a brush, a filter, a mop pad): a wear bar,
56520
+ * remaining time and a reset.
56521
+ * - `tank` — a container of liquid (clean water, dirty water): a fill gauge.
56522
+ * - `product` — something bought and refilled (detergent, salt, rinse aid):
56523
+ * a stepped level and "refill".
56524
+ * - `bin` — a container that collects waste (a dust bin): a fill gauge
56525
+ * that warns when full.
56526
+ * Absent = derived from the kind ({@link consumableFormOf}).
56527
+ */
56528
+ var ConsumableFormSchema = _enum([
56529
+ "part",
56530
+ "tank",
56531
+ "product",
56532
+ "bin"
56533
+ ]);
56534
+ /** The provider's own discrete verdict on an item. */
56535
+ var ConsumableStatusSchema = _enum([
56536
+ "ok",
56537
+ "low",
56538
+ "empty",
56539
+ "full",
56540
+ "replace"
56541
+ ]);
56542
+ _enum([
56543
+ "ok",
56544
+ "low",
56545
+ "empty",
56546
+ "full"
56547
+ ]);
56420
56548
  /** Units a remaining-life counter is reported in. Closed: the panel renders
56421
56549
  * each. */
56422
56550
  var ConsumableRemainingUnitSchema = _enum([
@@ -56431,18 +56559,23 @@ var ConsumableRemainingSchema = object({
56431
56559
  unit: ConsumableRemainingUnitSchema
56432
56560
  });
56433
56561
  /** A single consumable item. Either a continuous `level` (remaining
56434
- * life %) or a discrete `status` may be known — both may be null when a
56435
- * provider only knows the item exists. `level` and `status` are not
56436
- * mutually exclusive; a provider may report both. */
56562
+ * life %, or fill % for a `supply` / `waste` item) or a discrete `status`
56563
+ * may be known — both may be null when a provider only knows the item
56564
+ * exists. `level` and `status` are not mutually exclusive; a provider may
56565
+ * report both. */
56437
56566
  var ConsumableItemSchema = object({
56438
56567
  /** Stable id, e.g. 'main-brush'. */
56439
56568
  key: string().min(1),
56440
56569
  /** Display name. */
56441
56570
  label: string().min(1),
56442
- /** Remaining life % when known (0..100). */
56571
+ /** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
56443
56572
  level: number().min(0).max(100).nullable(),
56444
- /** Discrete state when known (binary mode). */
56445
- status: _enum(["ok", "replace"]).nullable(),
56573
+ /** The provider's discrete verdict when known (binary mode). */
56574
+ status: ConsumableStatusSchema.nullable(),
56575
+ /** What the item is — decides whether low or full is bad. Absent = `wear`. */
56576
+ kind: ConsumableKindSchema.optional(),
56577
+ /** How the item is drawn (part, tank, product, bin). Absent = derived from `kind`. */
56578
+ form: ConsumableFormSchema.optional(),
56446
56579
  /** Ms epoch of the last replace, when known. */
56447
56580
  lastResetAt: number().nullable(),
56448
56581
  /** Whether `reset()` is meaningful for this item. */
@@ -56465,7 +56598,7 @@ var consumablesCapability = {
56465
56598
  kind: "widget",
56466
56599
  widgetId: "host/consumables-panel",
56467
56600
  tab: "consumables",
56468
- topTab: true,
56601
+ placement: "hero",
56469
56602
  label: "Consumables",
56470
56603
  order: 5
56471
56604
  } },
@@ -56526,9 +56659,37 @@ reset: method(object({
56526
56659
  */
56527
56660
  durability: "restored",
56528
56661
  /**
56529
- * History (D850): none — `items` is an array keyed by runtime ids; a history path never enters it.
56662
+ * History (D850, D917): one series per (item field, item `key`) — the item key
56663
+ * is the series scope, the item `label` names it. A vacuum tank's fill, a
56664
+ * brush's remaining life and a dishwasher's salt are each recorded the moment
56665
+ * their provider reports them; an item that appears later gets its series.
56530
56666
  */
56531
- history: "none",
56667
+ history: {
56668
+ fields: {},
56669
+ items: {
56670
+ path: "items",
56671
+ key: "key",
56672
+ label: "label",
56673
+ fields: {
56674
+ level: {
56675
+ kind: "gauge",
56676
+ unit: "%",
56677
+ deadband: 2,
56678
+ displayName: "Level"
56679
+ },
56680
+ status: {
56681
+ kind: "enum",
56682
+ displayName: "Status"
56683
+ },
56684
+ "remaining.value": {
56685
+ kind: "gauge",
56686
+ unitFrom: "remaining.unit",
56687
+ deadband: 1,
56688
+ displayName: "Remaining"
56689
+ }
56690
+ }
56691
+ }
56692
+ },
56532
56693
  /** Clocks, not content: a re-read that changed no item costs no commit. */
56533
56694
  volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
56534
56695
  };
@@ -56943,8 +57104,9 @@ onStatusChanged: { data: object({
56943
57104
  volatileStateFields: ["lastChangedAt"]
56944
57105
  };
56945
57106
  /**
56946
- * Smart-dishwasher cap — program lifecycle, door / remote-start gates,
56947
- * consumable levels (salt, rinse aid) and common program options.
57107
+ * Smart-dishwasher cap — program lifecycle, door / remote-start gates and
57108
+ * common program options. Salt and rinse aid are NOT here: they are items of
57109
+ * the device's `consumables` cap, like every other device's (D915).
56948
57110
  *
56949
57111
  * Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
56950
57112
  * by any integration that exposes the same program / option surface.
@@ -56992,11 +57154,6 @@ var DishwasherAvailabilitySchema = _enum([
56992
57154
  "offline",
56993
57155
  "description-missing"
56994
57156
  ]);
56995
- var DishwasherConsumableLevelSchema = _enum([
56996
- "ok",
56997
- "low",
56998
- "empty"
56999
- ]);
57000
57157
  var DishwasherStatusSchema = object({
57001
57158
  availability: DishwasherAvailabilitySchema,
57002
57159
  /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
@@ -57029,8 +57186,6 @@ var DishwasherStatusSchema = object({
57029
57186
  powerOn: boolean().nullable(),
57030
57187
  /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
57031
57188
  powerState: string().nullable(),
57032
- saltLevel: DishwasherConsumableLevelSchema.nullable(),
57033
- rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
57034
57189
  /**
57035
57190
  * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
57036
57191
  * combined care-and-filter reminder raised); false when every such reminder reads clear; null
@@ -59906,7 +60061,7 @@ var motionTriggerCapability = {
59906
60061
  enabled: boolean()
59907
60062
  }), _void(), {
59908
60063
  kind: "mutation",
59909
- auth: "admin"
60064
+ auth: "protected"
59910
60065
  }) },
59911
60066
  events: { onMotionTriggerChanged: { data: object({
59912
60067
  deviceId: number(),
@@ -60656,6 +60811,13 @@ var TopologyNodeSchema = object({
60656
60811
  cpuModel: string().nullable(),
60657
60812
  cpuCores: number(),
60658
60813
  memoryMB: number(),
60814
+ /**
60815
+ * The inference RUNTIMES installed on the node (`pythonRuntimes`: onnx,
60816
+ * openvino, edgetpu …) — not its devices. An installed runtime says nothing
60817
+ * about whether its hardware is there (a Coral delegate stays installed
60818
+ * after the stick leaves, D919); the live device set is
60819
+ * `pipelineOrchestrator.getNodeInferenceDevices`.
60820
+ */
60659
60821
  engines: array(string()).readonly(),
60660
60822
  isHub: boolean(),
60661
60823
  isOnline: boolean(),
@@ -61819,7 +61981,28 @@ var ResolvedInferenceConfigSchema = object({
61819
61981
  format: ModelFormatSchema,
61820
61982
  reason: string()
61821
61983
  });
61822
- method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema);
61984
+ /**
61985
+ * The answer of an accelerator rescan (D919): the node's device list after
61986
+ * the re-probe, what changed, and the evidence that decided the Coral answer
61987
+ * (`usbBus` — could the USB bus be read at all; `decidedBy` — USB ids, the PCI
61988
+ * bus, the installed-delegate fallback, or nothing).
61989
+ */
61990
+ var AcceleratorRescanSchema = object({
61991
+ devices: array(InferenceDeviceDescriptorSchema).readonly(),
61992
+ appeared: array(string()).readonly(),
61993
+ disappeared: array(string()).readonly(),
61994
+ usbBus: _enum(["observed", "unobservable"]),
61995
+ decidedBy: _enum([
61996
+ "usb-ids",
61997
+ "pci",
61998
+ "delegate-fallback",
61999
+ "none"
62000
+ ])
62001
+ });
62002
+ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema), method(_void(), AcceleratorRescanSchema, {
62003
+ kind: "mutation",
62004
+ auth: "admin"
62005
+ });
61823
62006
  /**
61824
62007
  * Multi-metric electrical meter. One slice can carry any combination
61825
62008
  * of instantaneous power (W), cumulative energy (kWh), voltage (V),
@@ -66416,60 +66599,17 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
66416
66599
  auth: "admin",
66417
66600
  access: "delete"
66418
66601
  });
66419
- /**
66420
- * Robot-vacuum cap. Models HA `vacuum.*` entities — anything with a
66421
- * cleaning lifecycle plus a return-to-base / locate surface and an
66422
- * optional fan-speed selector.
66423
- *
66424
- * State follows HA's canonical vacuum lifecycle: `idle` / `cleaning` /
66425
- * `paused` / `returning` / `docked` / `error`. `batteryLevel`
66426
- * (0..100) is nullable — some vacuums don't report a battery
66427
- * percentage. `fanSpeed` is the current speed token (provider-verbatim,
66428
- * e.g. `'standard'` / `'turbo'`) and `availableFanSpeeds` lists the
66429
- * tokens the hardware accepts so the UI renders only supported choices.
66430
- *
66431
- * The `setFanSpeed` method takes the bare `speed` token — the provider
66432
- * validates it against the vacuum's own list. `locate` triggers the
66433
- * find-me chirp; `returnToBase` sends it home.
66434
- *
66435
- * Consumable / waste tanks: `cleanWater` / `dirtyWater` / `detergent` /
66436
- * `dustBin` each carry a nullable `{ level (0..100 %), status ('ok' |
66437
- * 'low' | 'full') }` reading. Native providers (e.g. Dreame, Roborock)
66438
- * SHOULD populate whichever tanks the hardware has — leave a field `null`
66439
- * only when the device has no such tank at all, and use a `TankStatus`
66440
- * with both inner fields `null` when the tank exists but its level is
66441
- * currently unknown. HA `vacuum.*` entities expose no per-tank telemetry,
66442
- * so the HA provider leaves all four `null`.
66443
- */
66444
- var VacuumStateSchema = _enum([
66445
- "idle",
66446
- "cleaning",
66447
- "paused",
66448
- "returning",
66449
- "docked",
66450
- "drying",
66451
- "error"
66452
- ]);
66453
- /**
66454
- * One consumable / waste tank on a robot vacuum (clean-water, dirty-water,
66455
- * detergent or dust-bin). A tank can report a numeric fill `level` (0..100),
66456
- * a discrete `status` (binary-style hardware), or both. Both `null` means the
66457
- * level is currently unknown; the OWNING field being `null` means the
66458
- * hardware has no such tank at all.
66459
- */
66460
- var TankStatusSchema = object({
66461
- /** Numeric fill 0..100 when the hardware reports a percentage; null otherwise. */
66462
- level: number().min(0).max(100).nullable(),
66463
- /** Discrete state when the hardware is binary-mode; null otherwise. */
66464
- status: _enum([
66465
- "ok",
66466
- "low",
66467
- "full"
66468
- ]).nullable()
66469
- });
66470
66602
  var VacuumControlStatusSchema = object({
66471
66603
  /** Lifecycle state of the vacuum. */
66472
- state: VacuumStateSchema,
66604
+ state: _enum([
66605
+ "idle",
66606
+ "cleaning",
66607
+ "paused",
66608
+ "returning",
66609
+ "docked",
66610
+ "drying",
66611
+ "error"
66612
+ ]),
66473
66613
  /** 0..100 battery percentage. Null when the device has no battery
66474
66614
  * reading. */
66475
66615
  batteryLevel: number().min(0).max(100).nullable(),
@@ -66478,14 +66618,6 @@ var VacuumControlStatusSchema = object({
66478
66618
  fanSpeed: string().nullable(),
66479
66619
  /** Speed tokens the hardware accepts — drives the UI selector. */
66480
66620
  availableFanSpeeds: array(string()),
66481
- /** Clean-water (mop) tank. Null when the hardware has no clean-water tank. */
66482
- cleanWater: TankStatusSchema.nullable(),
66483
- /** Dirty-water (recovery) tank. Null when the hardware has no dirty-water tank. */
66484
- dirtyWater: TankStatusSchema.nullable(),
66485
- /** Detergent tank. Null when the hardware has no detergent tank. */
66486
- detergent: TankStatusSchema.nullable(),
66487
- /** Dust bin. Null when the hardware has no dust bin. */
66488
- dustBin: TankStatusSchema.nullable(),
66489
66621
  /** 0..100 cleaning-completion percentage of the current task, or null. */
66490
66622
  progressPercent: number().min(0).max(100).nullable(),
66491
66623
  /** Current error code (0 / null = no error). */
@@ -66547,35 +66679,14 @@ var vacuumControlCapability = {
66547
66679
  */
66548
66680
  durability: "session",
66549
66681
  /**
66550
- * History (D850): recorded series. Tank levels are fixed-object paths (`cleanWater.level`, ...).
66682
+ * History (D850): recorded series. The tanks moved to `consumables` (D915), whose
66683
+ * items are keyed by runtime ids and record no history.
66551
66684
  */
66552
- history: { fields: {
66553
- batteryLevel: {
66554
- kind: "gauge",
66555
- unit: "%",
66556
- deadband: 2
66557
- },
66558
- "cleanWater.level": {
66559
- kind: "gauge",
66560
- unit: "%",
66561
- deadband: 2
66562
- },
66563
- "dirtyWater.level": {
66564
- kind: "gauge",
66565
- unit: "%",
66566
- deadband: 2
66567
- },
66568
- "detergent.level": {
66569
- kind: "gauge",
66570
- unit: "%",
66571
- deadband: 2
66572
- },
66573
- "dustBin.level": {
66574
- kind: "gauge",
66575
- unit: "%",
66576
- deadband: 2
66577
- }
66578
- } }
66685
+ history: { fields: { batteryLevel: {
66686
+ kind: "gauge",
66687
+ unit: "%",
66688
+ deadband: 2
66689
+ } } }
66579
66690
  };
66580
66691
  var ValveStatusSchema = object({
66581
66692
  /** Lifecycle state of the valve. */
@@ -70984,6 +71095,12 @@ Object.freeze({
70984
71095
  addonId: null,
70985
71096
  access: "create"
70986
71097
  },
71098
+ "deviceHistory.deleteOrphanSeries": {
71099
+ capName: "device-history",
71100
+ capScope: "system",
71101
+ addonId: null,
71102
+ access: "delete"
71103
+ },
70987
71104
  "deviceHistory.getDeviceEnabled": {
70988
71105
  capName: "device-history",
70989
71106
  capScope: "system",
@@ -71002,6 +71119,12 @@ Object.freeze({
71002
71119
  addonId: null,
71003
71120
  access: "view"
71004
71121
  },
71122
+ "deviceHistory.listOrphanSeries": {
71123
+ capName: "device-history",
71124
+ capScope: "system",
71125
+ addonId: null,
71126
+ access: "view"
71127
+ },
71005
71128
  "deviceHistory.listSeries": {
71006
71129
  capName: "device-history",
71007
71130
  capScope: "system",
@@ -74626,6 +74749,12 @@ Object.freeze({
74626
74749
  addonId: null,
74627
74750
  access: "delete"
74628
74751
  },
74752
+ "pipelineOrchestrator.forgetInferenceDevice": {
74753
+ capName: "pipeline-orchestrator",
74754
+ capScope: "system",
74755
+ addonId: null,
74756
+ access: "delete"
74757
+ },
74629
74758
  "pipelineOrchestrator.getAgentLoad": {
74630
74759
  capName: "pipeline-orchestrator",
74631
74760
  capScope: "system",
@@ -75202,6 +75331,12 @@ Object.freeze({
75202
75331
  addonId: null,
75203
75332
  access: "view"
75204
75333
  },
75334
+ "platformProbe.rescanAccelerators": {
75335
+ capName: "platform-probe",
75336
+ capScope: "system",
75337
+ addonId: null,
75338
+ access: "create"
75339
+ },
75205
75340
  "platformProbe.resolveHwAccel": {
75206
75341
  capName: "platform-probe",
75207
75342
  capScope: "system",
@@ -81159,7 +81294,7 @@ var STATE_SUMMARY_VARS = [
81159
81294
  ([...RULE_TEXT], [...COMBINED_ALARM]),
81160
81295
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
81161
81296
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
81162
- ([...RULE_TEXT], [...CONSUMABLE]),
81297
+ ([...RULE_TEXT], [...CONSUMABLE, ...TANK]),
81163
81298
  ([...RULE_TEXT], [...TANK]),
81164
81299
  [...RULE_TEXT],
81165
81300
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
@@ -190721,6 +190856,21 @@ var reolinkAccessoryBaseSchema = object({
190721
190856
  kind: string()
190722
190857
  });
190723
190858
  //#endregion
190859
+ //#region src/accessories/siren-play-duration.ts
190860
+ /**
190861
+ * The duration argument for `setSiren(channel, on, duration)`.
190862
+ *
190863
+ * The library's Baichuan path picks the "times" mode for ANY defined duration
190864
+ * (`duration !== undefined`), so a 0 sent as "until switched off" asked the
190865
+ * camera to play the alarm zero times: it acknowledged and stayed silent. Only
190866
+ * a positive count is a duration; everything else is the manual mode, where
190867
+ * `on` alone starts and stops the siren.
190868
+ */
190869
+ function sirenPlayDuration(on, configuredTimes) {
190870
+ if (!on) return void 0;
190871
+ return configuredTimes !== void 0 && configuredTimes > 0 ? configuredTimes : void 0;
190872
+ }
190873
+ //#endregion
190724
190874
  //#region src/accessories/siren.ts
190725
190875
  /**
190726
190876
  * SirenAccessory — child IDevice for the on-camera siren endpoint.
@@ -190914,8 +191064,33 @@ var SirenAccessory = class extends BaseDevice {
190914
191064
  setState: async ({ deviceId, on }) => {
190915
191065
  if (deviceId !== this.id) return;
190916
191066
  const api = await this.api;
190917
- const duration = on ? this.config.get("sirenDurationS") ?? 0 : void 0;
190918
- await api.setSiren(this.channel, on, duration);
191067
+ const duration = sirenPlayDuration(on, this.config.get("sirenDurationS"));
191068
+ try {
191069
+ await api.setSiren(this.channel, on, duration);
191070
+ } catch (err) {
191071
+ this.ctx.logger.warn("siren setState failed", {
191072
+ tags: {
191073
+ deviceId: this.id,
191074
+ channel: this.channel
191075
+ },
191076
+ meta: {
191077
+ on,
191078
+ duration: duration ?? "manual",
191079
+ error: err instanceof Error ? err.message : String(err)
191080
+ }
191081
+ });
191082
+ throw err;
191083
+ }
191084
+ this.ctx.logger.info("siren setState", {
191085
+ tags: {
191086
+ deviceId: this.id,
191087
+ channel: this.channel
191088
+ },
191089
+ meta: {
191090
+ on,
191091
+ duration: duration ?? "manual"
191092
+ }
191093
+ });
190919
191094
  this.setCapSlice(switchCapability, {
190920
191095
  on,
190921
191096
  lastChangedAt: Date.now()
package/dist/addon.mjs CHANGED
@@ -5460,7 +5460,7 @@ var ZodIssueCode = {
5460
5460
  var ZodFirstPartyTypeKind;
5461
5461
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5462
5462
  //#endregion
5463
- //#region ../types/dist/sleep-DJFUfKvA.mjs
5463
+ //#region ../types/dist/sleep-CUp20JkO.mjs
5464
5464
  /**
5465
5465
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5466
5466
  * window to float samples (D455).
@@ -8356,7 +8356,11 @@ var ContributionSectionSchema = object({
8356
8356
  literal(4)
8357
8357
  ]).optional(),
8358
8358
  tab: string().optional(),
8359
- location: _enum(["settings", "top-tab"]).optional(),
8359
+ location: _enum([
8360
+ "settings",
8361
+ "top-tab",
8362
+ "hero"
8363
+ ]).optional(),
8360
8364
  order: number().optional(),
8361
8365
  fields: array(any())
8362
8366
  });
@@ -13903,7 +13907,11 @@ var ConfigSectionWithValuesSchema = object({
13903
13907
  literal(4)
13904
13908
  ]).optional(),
13905
13909
  tab: string().optional(),
13906
- location: _enum(["settings", "top-tab"]).optional(),
13910
+ location: _enum([
13911
+ "settings",
13912
+ "top-tab",
13913
+ "hero"
13914
+ ]).optional(),
13907
13915
  order: number().optional(),
13908
13916
  fields: array(any())
13909
13917
  });
@@ -17783,6 +17791,52 @@ var TierStatusSchema = object({
17783
17791
  countedAt: number().nullable()
17784
17792
  });
17785
17793
  /** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
17794
+ /**
17795
+ * Why a series is orphan. `device-gone`: its device is absent from the
17796
+ * successful device listings (the departure clock). `undeclared`: its `cap:`
17797
+ * key is declared by no capability any more (a field a cap removed).
17798
+ */
17799
+ var DeviceHistoryOrphanReasonSchema = _enum(["device-gone", "undeclared"]);
17800
+ /** Rows held per stored tier. */
17801
+ var TierRowsSchema = object({
17802
+ raw: number().int(),
17803
+ "5m": number().int(),
17804
+ "1h": number().int(),
17805
+ "1d": number().int()
17806
+ });
17807
+ var OrphanSeriesSchema = object({
17808
+ seriesId: number().int(),
17809
+ deviceId: number().int(),
17810
+ key: string(),
17811
+ scope: string(),
17812
+ /** The metric's display name; `null` when its metric row is gone too. */
17813
+ displayName: string().nullable(),
17814
+ reason: DeviceHistoryOrphanReasonSchema,
17815
+ /** `device-gone`: since when the device has been absent; `null` otherwise. */
17816
+ missingSince: number().nullable(),
17817
+ firstTs: number(),
17818
+ lastTs: number(),
17819
+ rows: TierRowsSchema
17820
+ });
17821
+ var DeviceHistoryOrphanDeleteRefusalSchema = _enum([
17822
+ "not-found",
17823
+ "not-orphan",
17824
+ "failed"
17825
+ ]);
17826
+ var OrphanDeleteEntrySchema = discriminatedUnion("ok", [object({
17827
+ seriesId: number().int(),
17828
+ ok: literal(true),
17829
+ deleted: TierRowsSchema
17830
+ }), object({
17831
+ seriesId: number().int(),
17832
+ ok: literal(false),
17833
+ reason: DeviceHistoryOrphanDeleteRefusalSchema
17834
+ })]);
17835
+ var OrphanListSchema = object({
17836
+ series: array(OrphanSeriesSchema).readonly(),
17837
+ /** More orphans exist than {@link DEVICE_HISTORY_ORPHAN_LIST_MAX}. */
17838
+ truncated: boolean()
17839
+ });
17786
17840
  var DeviceHistoryStatusSchema = object({
17787
17841
  startedAt: number(),
17788
17842
  /** The store is declared, series loaded and the first reconcile has answered. */
@@ -17880,7 +17934,10 @@ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly())
17880
17934
  }), object({ enabled: boolean() }), {
17881
17935
  kind: "mutation",
17882
17936
  auth: "admin"
17883
- }), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" });
17937
+ }), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" }), method(object({}), OrphanListSchema, { auth: "admin" }), method(object({ seriesIds: array(number().int()).min(1).max(50) }), object({ results: array(OrphanDeleteEntrySchema).readonly() }), {
17938
+ kind: "mutation",
17939
+ auth: "admin"
17940
+ });
17884
17941
  var DeviceCaStatusSchema = discriminatedUnion("state", [
17885
17942
  object({ state: literal("absent") }),
17886
17943
  object({
@@ -50987,6 +51044,19 @@ var NodeInferenceDeviceSchema = object({
50987
51044
  /** Whether the node's live probe reports the device as usable right now. */
50988
51045
  available: boolean(),
50989
51046
  /**
51047
+ * Is the device on the node at all (D919)? `present` — the live probe
51048
+ * reported it; `absent` — the probe ANSWERED and did not report it, so only
51049
+ * its stored settings remain (unplugged, moved to another node): never
51050
+ * eligible, whatever its stored `enabled`, and forgettable with
51051
+ * `forgetInferenceDevice`; `unknown` — the probe did not answer, nothing is
51052
+ * claimed (D315). Optional only for an orchestrator older than the field.
51053
+ */
51054
+ presence: _enum([
51055
+ "present",
51056
+ "absent",
51057
+ "unknown"
51058
+ ]).optional(),
51059
+ /**
50990
51060
  * Whether this device participates in dispatch. AUTO default (spec C2):
50991
51061
  * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
50992
51062
  * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
@@ -51212,7 +51282,13 @@ method(object({
51212
51282
  }), object({ success: literal(true) }), {
51213
51283
  kind: "mutation",
51214
51284
  auth: "admin"
51215
- }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
51285
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({
51286
+ agentNodeId: string(),
51287
+ deviceKey: string()
51288
+ }), object({ success: literal(true) }), {
51289
+ kind: "mutation",
51290
+ auth: "admin"
51291
+ }), method(object({ agentNodeId: string() }), object({
51216
51292
  success: literal(true),
51217
51293
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
51218
51294
  effectiveModelId: string().nullable(),
@@ -56398,17 +56474,69 @@ var connectivityCapability = {
56398
56474
  volatileStateFields: ["lastChangedAt"]
56399
56475
  };
56400
56476
  /**
56401
- * Generic device-consumables capability — surfaces a device's
56402
- * maintenance items (vacuum filters/brushes, replaceable cartridges,
56403
- * descaling cycles, …) with their remaining life and an optional
56404
- * "Replaced" reset action. Device-agnostic: any provider that knows its
56405
- * device tracks consumables can register it; the cap declares no
56406
- * vocabulary of its own — the provider names each item verbatim.
56477
+ * Generic device-consumables capability — the ONE place a device reports what
56478
+ * it uses up or fills: wear parts (vacuum filters/brushes, cartridges,
56479
+ * descaling cycles), supplies it draws from (a vacuum's clean-water tank and
56480
+ * detergent, a dishwasher's salt and rinse aid) and waste it collects (a dirty
56481
+ * water tank, a dust bin). Each item carries its remaining life or fill and an
56482
+ * optional "Replaced" reset action. Device-agnostic: any provider that knows
56483
+ * its device tracks consumables registers it; the provider names each item
56484
+ * verbatim and says which `kind` it is.
56485
+ *
56486
+ * The admin UI renders it as ONE collapsible section directly under the
56487
+ * device page's hero card (`placement: 'hero'`), for every device bound to
56488
+ * this cap — never drawn by a device type's hero card itself (D915).
56407
56489
  *
56408
56490
  * Like `childLayout`, the cap is INERT until a provider sets items: no
56409
56491
  * provider populates it by guessing (no HA inference). The UI renders a
56410
56492
  * "No consumables reported" placeholder when `items` is empty.
56411
56493
  */
56494
+ /**
56495
+ * What an item IS, which decides which direction is bad:
56496
+ * - `wear` — a part that wears out (a brush, a filter); low life is bad.
56497
+ * - `supply` — something the device draws from (clean water, detergent,
56498
+ * salt, rinse aid); low or empty is bad.
56499
+ * - `waste` — something the device fills (dirty water, a dust bin); full is
56500
+ * bad.
56501
+ * Absent = `wear`.
56502
+ */
56503
+ var ConsumableKindSchema = _enum([
56504
+ "wear",
56505
+ "supply",
56506
+ "waste"
56507
+ ]);
56508
+ /**
56509
+ * What an item LOOKS like, which decides how a client draws it — independent
56510
+ * of `kind`, which decides which direction is bad:
56511
+ * - `part` — a part that wears (a brush, a filter, a mop pad): a wear bar,
56512
+ * remaining time and a reset.
56513
+ * - `tank` — a container of liquid (clean water, dirty water): a fill gauge.
56514
+ * - `product` — something bought and refilled (detergent, salt, rinse aid):
56515
+ * a stepped level and "refill".
56516
+ * - `bin` — a container that collects waste (a dust bin): a fill gauge
56517
+ * that warns when full.
56518
+ * Absent = derived from the kind ({@link consumableFormOf}).
56519
+ */
56520
+ var ConsumableFormSchema = _enum([
56521
+ "part",
56522
+ "tank",
56523
+ "product",
56524
+ "bin"
56525
+ ]);
56526
+ /** The provider's own discrete verdict on an item. */
56527
+ var ConsumableStatusSchema = _enum([
56528
+ "ok",
56529
+ "low",
56530
+ "empty",
56531
+ "full",
56532
+ "replace"
56533
+ ]);
56534
+ _enum([
56535
+ "ok",
56536
+ "low",
56537
+ "empty",
56538
+ "full"
56539
+ ]);
56412
56540
  /** Units a remaining-life counter is reported in. Closed: the panel renders
56413
56541
  * each. */
56414
56542
  var ConsumableRemainingUnitSchema = _enum([
@@ -56423,18 +56551,23 @@ var ConsumableRemainingSchema = object({
56423
56551
  unit: ConsumableRemainingUnitSchema
56424
56552
  });
56425
56553
  /** A single consumable item. Either a continuous `level` (remaining
56426
- * life %) or a discrete `status` may be known — both may be null when a
56427
- * provider only knows the item exists. `level` and `status` are not
56428
- * mutually exclusive; a provider may report both. */
56554
+ * life %, or fill % for a `supply` / `waste` item) or a discrete `status`
56555
+ * may be known — both may be null when a provider only knows the item
56556
+ * exists. `level` and `status` are not mutually exclusive; a provider may
56557
+ * report both. */
56429
56558
  var ConsumableItemSchema = object({
56430
56559
  /** Stable id, e.g. 'main-brush'. */
56431
56560
  key: string().min(1),
56432
56561
  /** Display name. */
56433
56562
  label: string().min(1),
56434
- /** Remaining life % when known (0..100). */
56563
+ /** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
56435
56564
  level: number().min(0).max(100).nullable(),
56436
- /** Discrete state when known (binary mode). */
56437
- status: _enum(["ok", "replace"]).nullable(),
56565
+ /** The provider's discrete verdict when known (binary mode). */
56566
+ status: ConsumableStatusSchema.nullable(),
56567
+ /** What the item is — decides whether low or full is bad. Absent = `wear`. */
56568
+ kind: ConsumableKindSchema.optional(),
56569
+ /** How the item is drawn (part, tank, product, bin). Absent = derived from `kind`. */
56570
+ form: ConsumableFormSchema.optional(),
56438
56571
  /** Ms epoch of the last replace, when known. */
56439
56572
  lastResetAt: number().nullable(),
56440
56573
  /** Whether `reset()` is meaningful for this item. */
@@ -56457,7 +56590,7 @@ var consumablesCapability = {
56457
56590
  kind: "widget",
56458
56591
  widgetId: "host/consumables-panel",
56459
56592
  tab: "consumables",
56460
- topTab: true,
56593
+ placement: "hero",
56461
56594
  label: "Consumables",
56462
56595
  order: 5
56463
56596
  } },
@@ -56518,9 +56651,37 @@ reset: method(object({
56518
56651
  */
56519
56652
  durability: "restored",
56520
56653
  /**
56521
- * History (D850): none — `items` is an array keyed by runtime ids; a history path never enters it.
56654
+ * History (D850, D917): one series per (item field, item `key`) — the item key
56655
+ * is the series scope, the item `label` names it. A vacuum tank's fill, a
56656
+ * brush's remaining life and a dishwasher's salt are each recorded the moment
56657
+ * their provider reports them; an item that appears later gets its series.
56522
56658
  */
56523
- history: "none",
56659
+ history: {
56660
+ fields: {},
56661
+ items: {
56662
+ path: "items",
56663
+ key: "key",
56664
+ label: "label",
56665
+ fields: {
56666
+ level: {
56667
+ kind: "gauge",
56668
+ unit: "%",
56669
+ deadband: 2,
56670
+ displayName: "Level"
56671
+ },
56672
+ status: {
56673
+ kind: "enum",
56674
+ displayName: "Status"
56675
+ },
56676
+ "remaining.value": {
56677
+ kind: "gauge",
56678
+ unitFrom: "remaining.unit",
56679
+ deadband: 1,
56680
+ displayName: "Remaining"
56681
+ }
56682
+ }
56683
+ }
56684
+ },
56524
56685
  /** Clocks, not content: a re-read that changed no item costs no commit. */
56525
56686
  volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
56526
56687
  };
@@ -56935,8 +57096,9 @@ onStatusChanged: { data: object({
56935
57096
  volatileStateFields: ["lastChangedAt"]
56936
57097
  };
56937
57098
  /**
56938
- * Smart-dishwasher cap — program lifecycle, door / remote-start gates,
56939
- * consumable levels (salt, rinse aid) and common program options.
57099
+ * Smart-dishwasher cap — program lifecycle, door / remote-start gates and
57100
+ * common program options. Salt and rinse aid are NOT here: they are items of
57101
+ * the device's `consumables` cap, like every other device's (D915).
56940
57102
  *
56941
57103
  * Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
56942
57104
  * by any integration that exposes the same program / option surface.
@@ -56984,11 +57146,6 @@ var DishwasherAvailabilitySchema = _enum([
56984
57146
  "offline",
56985
57147
  "description-missing"
56986
57148
  ]);
56987
- var DishwasherConsumableLevelSchema = _enum([
56988
- "ok",
56989
- "low",
56990
- "empty"
56991
- ]);
56992
57149
  var DishwasherStatusSchema = object({
56993
57150
  availability: DishwasherAvailabilitySchema,
56994
57151
  /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
@@ -57021,8 +57178,6 @@ var DishwasherStatusSchema = object({
57021
57178
  powerOn: boolean().nullable(),
57022
57179
  /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
57023
57180
  powerState: string().nullable(),
57024
- saltLevel: DishwasherConsumableLevelSchema.nullable(),
57025
- rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
57026
57181
  /**
57027
57182
  * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
57028
57183
  * combined care-and-filter reminder raised); false when every such reminder reads clear; null
@@ -59898,7 +60053,7 @@ var motionTriggerCapability = {
59898
60053
  enabled: boolean()
59899
60054
  }), _void(), {
59900
60055
  kind: "mutation",
59901
- auth: "admin"
60056
+ auth: "protected"
59902
60057
  }) },
59903
60058
  events: { onMotionTriggerChanged: { data: object({
59904
60059
  deviceId: number(),
@@ -60648,6 +60803,13 @@ var TopologyNodeSchema = object({
60648
60803
  cpuModel: string().nullable(),
60649
60804
  cpuCores: number(),
60650
60805
  memoryMB: number(),
60806
+ /**
60807
+ * The inference RUNTIMES installed on the node (`pythonRuntimes`: onnx,
60808
+ * openvino, edgetpu …) — not its devices. An installed runtime says nothing
60809
+ * about whether its hardware is there (a Coral delegate stays installed
60810
+ * after the stick leaves, D919); the live device set is
60811
+ * `pipelineOrchestrator.getNodeInferenceDevices`.
60812
+ */
60651
60813
  engines: array(string()).readonly(),
60652
60814
  isHub: boolean(),
60653
60815
  isOnline: boolean(),
@@ -61811,7 +61973,28 @@ var ResolvedInferenceConfigSchema = object({
61811
61973
  format: ModelFormatSchema,
61812
61974
  reason: string()
61813
61975
  });
61814
- method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema);
61976
+ /**
61977
+ * The answer of an accelerator rescan (D919): the node's device list after
61978
+ * the re-probe, what changed, and the evidence that decided the Coral answer
61979
+ * (`usbBus` — could the USB bus be read at all; `decidedBy` — USB ids, the PCI
61980
+ * bus, the installed-delegate fallback, or nothing).
61981
+ */
61982
+ var AcceleratorRescanSchema = object({
61983
+ devices: array(InferenceDeviceDescriptorSchema).readonly(),
61984
+ appeared: array(string()).readonly(),
61985
+ disappeared: array(string()).readonly(),
61986
+ usbBus: _enum(["observed", "unobservable"]),
61987
+ decidedBy: _enum([
61988
+ "usb-ids",
61989
+ "pci",
61990
+ "delegate-fallback",
61991
+ "none"
61992
+ ])
61993
+ });
61994
+ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema), method(_void(), AcceleratorRescanSchema, {
61995
+ kind: "mutation",
61996
+ auth: "admin"
61997
+ });
61815
61998
  /**
61816
61999
  * Multi-metric electrical meter. One slice can carry any combination
61817
62000
  * of instantaneous power (W), cumulative energy (kWh), voltage (V),
@@ -66408,60 +66591,17 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
66408
66591
  auth: "admin",
66409
66592
  access: "delete"
66410
66593
  });
66411
- /**
66412
- * Robot-vacuum cap. Models HA `vacuum.*` entities — anything with a
66413
- * cleaning lifecycle plus a return-to-base / locate surface and an
66414
- * optional fan-speed selector.
66415
- *
66416
- * State follows HA's canonical vacuum lifecycle: `idle` / `cleaning` /
66417
- * `paused` / `returning` / `docked` / `error`. `batteryLevel`
66418
- * (0..100) is nullable — some vacuums don't report a battery
66419
- * percentage. `fanSpeed` is the current speed token (provider-verbatim,
66420
- * e.g. `'standard'` / `'turbo'`) and `availableFanSpeeds` lists the
66421
- * tokens the hardware accepts so the UI renders only supported choices.
66422
- *
66423
- * The `setFanSpeed` method takes the bare `speed` token — the provider
66424
- * validates it against the vacuum's own list. `locate` triggers the
66425
- * find-me chirp; `returnToBase` sends it home.
66426
- *
66427
- * Consumable / waste tanks: `cleanWater` / `dirtyWater` / `detergent` /
66428
- * `dustBin` each carry a nullable `{ level (0..100 %), status ('ok' |
66429
- * 'low' | 'full') }` reading. Native providers (e.g. Dreame, Roborock)
66430
- * SHOULD populate whichever tanks the hardware has — leave a field `null`
66431
- * only when the device has no such tank at all, and use a `TankStatus`
66432
- * with both inner fields `null` when the tank exists but its level is
66433
- * currently unknown. HA `vacuum.*` entities expose no per-tank telemetry,
66434
- * so the HA provider leaves all four `null`.
66435
- */
66436
- var VacuumStateSchema = _enum([
66437
- "idle",
66438
- "cleaning",
66439
- "paused",
66440
- "returning",
66441
- "docked",
66442
- "drying",
66443
- "error"
66444
- ]);
66445
- /**
66446
- * One consumable / waste tank on a robot vacuum (clean-water, dirty-water,
66447
- * detergent or dust-bin). A tank can report a numeric fill `level` (0..100),
66448
- * a discrete `status` (binary-style hardware), or both. Both `null` means the
66449
- * level is currently unknown; the OWNING field being `null` means the
66450
- * hardware has no such tank at all.
66451
- */
66452
- var TankStatusSchema = object({
66453
- /** Numeric fill 0..100 when the hardware reports a percentage; null otherwise. */
66454
- level: number().min(0).max(100).nullable(),
66455
- /** Discrete state when the hardware is binary-mode; null otherwise. */
66456
- status: _enum([
66457
- "ok",
66458
- "low",
66459
- "full"
66460
- ]).nullable()
66461
- });
66462
66594
  var VacuumControlStatusSchema = object({
66463
66595
  /** Lifecycle state of the vacuum. */
66464
- state: VacuumStateSchema,
66596
+ state: _enum([
66597
+ "idle",
66598
+ "cleaning",
66599
+ "paused",
66600
+ "returning",
66601
+ "docked",
66602
+ "drying",
66603
+ "error"
66604
+ ]),
66465
66605
  /** 0..100 battery percentage. Null when the device has no battery
66466
66606
  * reading. */
66467
66607
  batteryLevel: number().min(0).max(100).nullable(),
@@ -66470,14 +66610,6 @@ var VacuumControlStatusSchema = object({
66470
66610
  fanSpeed: string().nullable(),
66471
66611
  /** Speed tokens the hardware accepts — drives the UI selector. */
66472
66612
  availableFanSpeeds: array(string()),
66473
- /** Clean-water (mop) tank. Null when the hardware has no clean-water tank. */
66474
- cleanWater: TankStatusSchema.nullable(),
66475
- /** Dirty-water (recovery) tank. Null when the hardware has no dirty-water tank. */
66476
- dirtyWater: TankStatusSchema.nullable(),
66477
- /** Detergent tank. Null when the hardware has no detergent tank. */
66478
- detergent: TankStatusSchema.nullable(),
66479
- /** Dust bin. Null when the hardware has no dust bin. */
66480
- dustBin: TankStatusSchema.nullable(),
66481
66613
  /** 0..100 cleaning-completion percentage of the current task, or null. */
66482
66614
  progressPercent: number().min(0).max(100).nullable(),
66483
66615
  /** Current error code (0 / null = no error). */
@@ -66539,35 +66671,14 @@ var vacuumControlCapability = {
66539
66671
  */
66540
66672
  durability: "session",
66541
66673
  /**
66542
- * History (D850): recorded series. Tank levels are fixed-object paths (`cleanWater.level`, ...).
66674
+ * History (D850): recorded series. The tanks moved to `consumables` (D915), whose
66675
+ * items are keyed by runtime ids and record no history.
66543
66676
  */
66544
- history: { fields: {
66545
- batteryLevel: {
66546
- kind: "gauge",
66547
- unit: "%",
66548
- deadband: 2
66549
- },
66550
- "cleanWater.level": {
66551
- kind: "gauge",
66552
- unit: "%",
66553
- deadband: 2
66554
- },
66555
- "dirtyWater.level": {
66556
- kind: "gauge",
66557
- unit: "%",
66558
- deadband: 2
66559
- },
66560
- "detergent.level": {
66561
- kind: "gauge",
66562
- unit: "%",
66563
- deadband: 2
66564
- },
66565
- "dustBin.level": {
66566
- kind: "gauge",
66567
- unit: "%",
66568
- deadband: 2
66569
- }
66570
- } }
66677
+ history: { fields: { batteryLevel: {
66678
+ kind: "gauge",
66679
+ unit: "%",
66680
+ deadband: 2
66681
+ } } }
66571
66682
  };
66572
66683
  var ValveStatusSchema = object({
66573
66684
  /** Lifecycle state of the valve. */
@@ -70976,6 +71087,12 @@ Object.freeze({
70976
71087
  addonId: null,
70977
71088
  access: "create"
70978
71089
  },
71090
+ "deviceHistory.deleteOrphanSeries": {
71091
+ capName: "device-history",
71092
+ capScope: "system",
71093
+ addonId: null,
71094
+ access: "delete"
71095
+ },
70979
71096
  "deviceHistory.getDeviceEnabled": {
70980
71097
  capName: "device-history",
70981
71098
  capScope: "system",
@@ -70994,6 +71111,12 @@ Object.freeze({
70994
71111
  addonId: null,
70995
71112
  access: "view"
70996
71113
  },
71114
+ "deviceHistory.listOrphanSeries": {
71115
+ capName: "device-history",
71116
+ capScope: "system",
71117
+ addonId: null,
71118
+ access: "view"
71119
+ },
70997
71120
  "deviceHistory.listSeries": {
70998
71121
  capName: "device-history",
70999
71122
  capScope: "system",
@@ -74618,6 +74741,12 @@ Object.freeze({
74618
74741
  addonId: null,
74619
74742
  access: "delete"
74620
74743
  },
74744
+ "pipelineOrchestrator.forgetInferenceDevice": {
74745
+ capName: "pipeline-orchestrator",
74746
+ capScope: "system",
74747
+ addonId: null,
74748
+ access: "delete"
74749
+ },
74621
74750
  "pipelineOrchestrator.getAgentLoad": {
74622
74751
  capName: "pipeline-orchestrator",
74623
74752
  capScope: "system",
@@ -75194,6 +75323,12 @@ Object.freeze({
75194
75323
  addonId: null,
75195
75324
  access: "view"
75196
75325
  },
75326
+ "platformProbe.rescanAccelerators": {
75327
+ capName: "platform-probe",
75328
+ capScope: "system",
75329
+ addonId: null,
75330
+ access: "create"
75331
+ },
75197
75332
  "platformProbe.resolveHwAccel": {
75198
75333
  capName: "platform-probe",
75199
75334
  capScope: "system",
@@ -81151,7 +81286,7 @@ var STATE_SUMMARY_VARS = [
81151
81286
  ([...RULE_TEXT], [...COMBINED_ALARM]),
81152
81287
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
81153
81288
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
81154
- ([...RULE_TEXT], [...CONSUMABLE]),
81289
+ ([...RULE_TEXT], [...CONSUMABLE, ...TANK]),
81155
81290
  ([...RULE_TEXT], [...TANK]),
81156
81291
  [...RULE_TEXT],
81157
81292
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
@@ -190713,6 +190848,21 @@ var reolinkAccessoryBaseSchema = object({
190713
190848
  kind: string()
190714
190849
  });
190715
190850
  //#endregion
190851
+ //#region src/accessories/siren-play-duration.ts
190852
+ /**
190853
+ * The duration argument for `setSiren(channel, on, duration)`.
190854
+ *
190855
+ * The library's Baichuan path picks the "times" mode for ANY defined duration
190856
+ * (`duration !== undefined`), so a 0 sent as "until switched off" asked the
190857
+ * camera to play the alarm zero times: it acknowledged and stayed silent. Only
190858
+ * a positive count is a duration; everything else is the manual mode, where
190859
+ * `on` alone starts and stops the siren.
190860
+ */
190861
+ function sirenPlayDuration(on, configuredTimes) {
190862
+ if (!on) return void 0;
190863
+ return configuredTimes !== void 0 && configuredTimes > 0 ? configuredTimes : void 0;
190864
+ }
190865
+ //#endregion
190716
190866
  //#region src/accessories/siren.ts
190717
190867
  /**
190718
190868
  * SirenAccessory — child IDevice for the on-camera siren endpoint.
@@ -190906,8 +191056,33 @@ var SirenAccessory = class extends BaseDevice {
190906
191056
  setState: async ({ deviceId, on }) => {
190907
191057
  if (deviceId !== this.id) return;
190908
191058
  const api = await this.api;
190909
- const duration = on ? this.config.get("sirenDurationS") ?? 0 : void 0;
190910
- await api.setSiren(this.channel, on, duration);
191059
+ const duration = sirenPlayDuration(on, this.config.get("sirenDurationS"));
191060
+ try {
191061
+ await api.setSiren(this.channel, on, duration);
191062
+ } catch (err) {
191063
+ this.ctx.logger.warn("siren setState failed", {
191064
+ tags: {
191065
+ deviceId: this.id,
191066
+ channel: this.channel
191067
+ },
191068
+ meta: {
191069
+ on,
191070
+ duration: duration ?? "manual",
191071
+ error: err instanceof Error ? err.message : String(err)
191072
+ }
191073
+ });
191074
+ throw err;
191075
+ }
191076
+ this.ctx.logger.info("siren setState", {
191077
+ tags: {
191078
+ deviceId: this.id,
191079
+ channel: this.channel
191080
+ },
191081
+ meta: {
191082
+ on,
191083
+ duration: duration ?? "manual"
191084
+ }
191085
+ });
190911
191086
  this.setCapSlice(switchCapability, {
190912
191087
  on,
190913
191088
  lastChangedAt: Date.now()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-reolink",
3
- "version": "1.2.204",
3
+ "version": "1.2.206",
4
4
  "description": "Reolink camera device provider addon for CamStack — native Baichuan protocol",
5
5
  "keywords": [
6
6
  "camstack",