@camstack/addon-provider-wyze 0.2.154 → 0.2.156

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 +193 -123
  2. package/dist/addon.mjs +193 -123
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -5463,7 +5463,7 @@ var ZodIssueCode = {
5463
5463
  var ZodFirstPartyTypeKind;
5464
5464
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5465
5465
  //#endregion
5466
- //#region ../types/dist/sleep-DJFUfKvA.mjs
5466
+ //#region ../types/dist/sleep-CUp20JkO.mjs
5467
5467
  /**
5468
5468
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5469
5469
  * window to float samples (D455).
@@ -8355,7 +8355,11 @@ var ContributionSectionSchema = object({
8355
8355
  literal(4)
8356
8356
  ]).optional(),
8357
8357
  tab: string().optional(),
8358
- location: _enum(["settings", "top-tab"]).optional(),
8358
+ location: _enum([
8359
+ "settings",
8360
+ "top-tab",
8361
+ "hero"
8362
+ ]).optional(),
8359
8363
  order: number().optional(),
8360
8364
  fields: array(any())
8361
8365
  });
@@ -13322,7 +13326,11 @@ var ConfigSectionWithValuesSchema = object({
13322
13326
  literal(4)
13323
13327
  ]).optional(),
13324
13328
  tab: string().optional(),
13325
- location: _enum(["settings", "top-tab"]).optional(),
13329
+ location: _enum([
13330
+ "settings",
13331
+ "top-tab",
13332
+ "hero"
13333
+ ]).optional(),
13326
13334
  order: number().optional(),
13327
13335
  fields: array(any())
13328
13336
  });
@@ -17202,6 +17210,52 @@ var TierStatusSchema = object({
17202
17210
  countedAt: number().nullable()
17203
17211
  });
17204
17212
  /** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
17213
+ /**
17214
+ * Why a series is orphan. `device-gone`: its device is absent from the
17215
+ * successful device listings (the departure clock). `undeclared`: its `cap:`
17216
+ * key is declared by no capability any more (a field a cap removed).
17217
+ */
17218
+ var DeviceHistoryOrphanReasonSchema = _enum(["device-gone", "undeclared"]);
17219
+ /** Rows held per stored tier. */
17220
+ var TierRowsSchema = object({
17221
+ raw: number().int(),
17222
+ "5m": number().int(),
17223
+ "1h": number().int(),
17224
+ "1d": number().int()
17225
+ });
17226
+ var OrphanSeriesSchema = object({
17227
+ seriesId: number().int(),
17228
+ deviceId: number().int(),
17229
+ key: string(),
17230
+ scope: string(),
17231
+ /** The metric's display name; `null` when its metric row is gone too. */
17232
+ displayName: string().nullable(),
17233
+ reason: DeviceHistoryOrphanReasonSchema,
17234
+ /** `device-gone`: since when the device has been absent; `null` otherwise. */
17235
+ missingSince: number().nullable(),
17236
+ firstTs: number(),
17237
+ lastTs: number(),
17238
+ rows: TierRowsSchema
17239
+ });
17240
+ var DeviceHistoryOrphanDeleteRefusalSchema = _enum([
17241
+ "not-found",
17242
+ "not-orphan",
17243
+ "failed"
17244
+ ]);
17245
+ var OrphanDeleteEntrySchema = discriminatedUnion("ok", [object({
17246
+ seriesId: number().int(),
17247
+ ok: literal(true),
17248
+ deleted: TierRowsSchema
17249
+ }), object({
17250
+ seriesId: number().int(),
17251
+ ok: literal(false),
17252
+ reason: DeviceHistoryOrphanDeleteRefusalSchema
17253
+ })]);
17254
+ var OrphanListSchema = object({
17255
+ series: array(OrphanSeriesSchema).readonly(),
17256
+ /** More orphans exist than {@link DEVICE_HISTORY_ORPHAN_LIST_MAX}. */
17257
+ truncated: boolean()
17258
+ });
17205
17259
  var DeviceHistoryStatusSchema = object({
17206
17260
  startedAt: number(),
17207
17261
  /** The store is declared, series loaded and the first reconcile has answered. */
@@ -17299,7 +17353,10 @@ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly())
17299
17353
  }), object({ enabled: boolean() }), {
17300
17354
  kind: "mutation",
17301
17355
  auth: "admin"
17302
- }), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" });
17356
+ }), 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() }), {
17357
+ kind: "mutation",
17358
+ auth: "admin"
17359
+ });
17303
17360
  var DeviceCaStatusSchema = discriminatedUnion("state", [
17304
17361
  object({ state: literal("absent") }),
17305
17362
  object({
@@ -48027,7 +48084,6 @@ var RecommendationReasonSchema = discriminatedUnion("kind", [
48027
48084
  modelId: string()
48028
48085
  }),
48029
48086
  object({ kind: literal("cpu-device") }),
48030
- object({ kind: literal("coral-untouched") }),
48031
48087
  object({ kind: literal("device-disabled") }),
48032
48088
  object({ kind: literal("device-unavailable") }),
48033
48089
  object({ kind: literal("node-offline") }),
@@ -48125,11 +48181,6 @@ var AutoTuneWarningSchema = discriminatedUnion("kind", [
48125
48181
  kind: literal("detector-store-unreadable"),
48126
48182
  error: string()
48127
48183
  }),
48128
- object({
48129
- kind: literal("coral-enabled"),
48130
- nodeId: string(),
48131
- deviceKey: string()
48132
- }),
48133
48184
  object({
48134
48185
  kind: literal("custom-pin-kept"),
48135
48186
  nodeId: string(),
@@ -55277,17 +55328,69 @@ var connectivityCapability = {
55277
55328
  volatileStateFields: ["lastChangedAt"]
55278
55329
  };
55279
55330
  /**
55280
- * Generic device-consumables capability — surfaces a device's
55281
- * maintenance items (vacuum filters/brushes, replaceable cartridges,
55282
- * descaling cycles, …) with their remaining life and an optional
55283
- * "Replaced" reset action. Device-agnostic: any provider that knows its
55284
- * device tracks consumables can register it; the cap declares no
55285
- * vocabulary of its own — the provider names each item verbatim.
55331
+ * Generic device-consumables capability — the ONE place a device reports what
55332
+ * it uses up or fills: wear parts (vacuum filters/brushes, cartridges,
55333
+ * descaling cycles), supplies it draws from (a vacuum's clean-water tank and
55334
+ * detergent, a dishwasher's salt and rinse aid) and waste it collects (a dirty
55335
+ * water tank, a dust bin). Each item carries its remaining life or fill and an
55336
+ * optional "Replaced" reset action. Device-agnostic: any provider that knows
55337
+ * its device tracks consumables registers it; the provider names each item
55338
+ * verbatim and says which `kind` it is.
55339
+ *
55340
+ * The admin UI renders it as ONE collapsible section directly under the
55341
+ * device page's hero card (`placement: 'hero'`), for every device bound to
55342
+ * this cap — never drawn by a device type's hero card itself (D915).
55286
55343
  *
55287
55344
  * Like `childLayout`, the cap is INERT until a provider sets items: no
55288
55345
  * provider populates it by guessing (no HA inference). The UI renders a
55289
55346
  * "No consumables reported" placeholder when `items` is empty.
55290
55347
  */
55348
+ /**
55349
+ * What an item IS, which decides which direction is bad:
55350
+ * - `wear` — a part that wears out (a brush, a filter); low life is bad.
55351
+ * - `supply` — something the device draws from (clean water, detergent,
55352
+ * salt, rinse aid); low or empty is bad.
55353
+ * - `waste` — something the device fills (dirty water, a dust bin); full is
55354
+ * bad.
55355
+ * Absent = `wear`.
55356
+ */
55357
+ var ConsumableKindSchema = _enum([
55358
+ "wear",
55359
+ "supply",
55360
+ "waste"
55361
+ ]);
55362
+ /**
55363
+ * What an item LOOKS like, which decides how a client draws it — independent
55364
+ * of `kind`, which decides which direction is bad:
55365
+ * - `part` — a part that wears (a brush, a filter, a mop pad): a wear bar,
55366
+ * remaining time and a reset.
55367
+ * - `tank` — a container of liquid (clean water, dirty water): a fill gauge.
55368
+ * - `product` — something bought and refilled (detergent, salt, rinse aid):
55369
+ * a stepped level and "refill".
55370
+ * - `bin` — a container that collects waste (a dust bin): a fill gauge
55371
+ * that warns when full.
55372
+ * Absent = derived from the kind ({@link consumableFormOf}).
55373
+ */
55374
+ var ConsumableFormSchema = _enum([
55375
+ "part",
55376
+ "tank",
55377
+ "product",
55378
+ "bin"
55379
+ ]);
55380
+ /** The provider's own discrete verdict on an item. */
55381
+ var ConsumableStatusSchema = _enum([
55382
+ "ok",
55383
+ "low",
55384
+ "empty",
55385
+ "full",
55386
+ "replace"
55387
+ ]);
55388
+ _enum([
55389
+ "ok",
55390
+ "low",
55391
+ "empty",
55392
+ "full"
55393
+ ]);
55291
55394
  /** Units a remaining-life counter is reported in. Closed: the panel renders
55292
55395
  * each. */
55293
55396
  var ConsumableRemainingUnitSchema = _enum([
@@ -55302,18 +55405,23 @@ var ConsumableRemainingSchema = object({
55302
55405
  unit: ConsumableRemainingUnitSchema
55303
55406
  });
55304
55407
  /** A single consumable item. Either a continuous `level` (remaining
55305
- * life %) or a discrete `status` may be known — both may be null when a
55306
- * provider only knows the item exists. `level` and `status` are not
55307
- * mutually exclusive; a provider may report both. */
55408
+ * life %, or fill % for a `supply` / `waste` item) or a discrete `status`
55409
+ * may be known — both may be null when a provider only knows the item
55410
+ * exists. `level` and `status` are not mutually exclusive; a provider may
55411
+ * report both. */
55308
55412
  var ConsumableItemSchema = object({
55309
55413
  /** Stable id, e.g. 'main-brush'. */
55310
55414
  key: string().min(1),
55311
55415
  /** Display name. */
55312
55416
  label: string().min(1),
55313
- /** Remaining life % when known (0..100). */
55417
+ /** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
55314
55418
  level: number().min(0).max(100).nullable(),
55315
- /** Discrete state when known (binary mode). */
55316
- status: _enum(["ok", "replace"]).nullable(),
55419
+ /** The provider's discrete verdict when known (binary mode). */
55420
+ status: ConsumableStatusSchema.nullable(),
55421
+ /** What the item is — decides whether low or full is bad. Absent = `wear`. */
55422
+ kind: ConsumableKindSchema.optional(),
55423
+ /** How the item is drawn (part, tank, product, bin). Absent = derived from `kind`. */
55424
+ form: ConsumableFormSchema.optional(),
55317
55425
  /** Ms epoch of the last replace, when known. */
55318
55426
  lastResetAt: number().nullable(),
55319
55427
  /** Whether `reset()` is meaningful for this item. */
@@ -55336,7 +55444,7 @@ var consumablesCapability = {
55336
55444
  kind: "widget",
55337
55445
  widgetId: "host/consumables-panel",
55338
55446
  tab: "consumables",
55339
- topTab: true,
55447
+ placement: "hero",
55340
55448
  label: "Consumables",
55341
55449
  order: 5
55342
55450
  } },
@@ -55397,9 +55505,37 @@ reset: method(object({
55397
55505
  */
55398
55506
  durability: "restored",
55399
55507
  /**
55400
- * History (D850): none — `items` is an array keyed by runtime ids; a history path never enters it.
55508
+ * History (D850, D917): one series per (item field, item `key`) — the item key
55509
+ * is the series scope, the item `label` names it. A vacuum tank's fill, a
55510
+ * brush's remaining life and a dishwasher's salt are each recorded the moment
55511
+ * their provider reports them; an item that appears later gets its series.
55401
55512
  */
55402
- history: "none",
55513
+ history: {
55514
+ fields: {},
55515
+ items: {
55516
+ path: "items",
55517
+ key: "key",
55518
+ label: "label",
55519
+ fields: {
55520
+ level: {
55521
+ kind: "gauge",
55522
+ unit: "%",
55523
+ deadband: 2,
55524
+ displayName: "Level"
55525
+ },
55526
+ status: {
55527
+ kind: "enum",
55528
+ displayName: "Status"
55529
+ },
55530
+ "remaining.value": {
55531
+ kind: "gauge",
55532
+ unitFrom: "remaining.unit",
55533
+ deadband: 1,
55534
+ displayName: "Remaining"
55535
+ }
55536
+ }
55537
+ }
55538
+ },
55403
55539
  /** Clocks, not content: a re-read that changed no item costs no commit. */
55404
55540
  volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
55405
55541
  };
@@ -55814,8 +55950,9 @@ onStatusChanged: { data: object({
55814
55950
  volatileStateFields: ["lastChangedAt"]
55815
55951
  };
55816
55952
  /**
55817
- * Smart-dishwasher cap — program lifecycle, door / remote-start gates,
55818
- * consumable levels (salt, rinse aid) and common program options.
55953
+ * Smart-dishwasher cap — program lifecycle, door / remote-start gates and
55954
+ * common program options. Salt and rinse aid are NOT here: they are items of
55955
+ * the device's `consumables` cap, like every other device's (D915).
55819
55956
  *
55820
55957
  * Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
55821
55958
  * by any integration that exposes the same program / option surface.
@@ -55863,11 +56000,6 @@ var DishwasherAvailabilitySchema = _enum([
55863
56000
  "offline",
55864
56001
  "description-missing"
55865
56002
  ]);
55866
- var DishwasherConsumableLevelSchema = _enum([
55867
- "ok",
55868
- "low",
55869
- "empty"
55870
- ]);
55871
56003
  var DishwasherStatusSchema = object({
55872
56004
  availability: DishwasherAvailabilitySchema,
55873
56005
  /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
@@ -55900,8 +56032,6 @@ var DishwasherStatusSchema = object({
55900
56032
  powerOn: boolean().nullable(),
55901
56033
  /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
55902
56034
  powerState: string().nullable(),
55903
- saltLevel: DishwasherConsumableLevelSchema.nullable(),
55904
- rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
55905
56035
  /**
55906
56036
  * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
55907
56037
  * combined care-and-filter reminder raised); false when every such reminder reads clear; null
@@ -64717,60 +64847,17 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
64717
64847
  auth: "admin",
64718
64848
  access: "delete"
64719
64849
  });
64720
- /**
64721
- * Robot-vacuum cap. Models HA `vacuum.*` entities — anything with a
64722
- * cleaning lifecycle plus a return-to-base / locate surface and an
64723
- * optional fan-speed selector.
64724
- *
64725
- * State follows HA's canonical vacuum lifecycle: `idle` / `cleaning` /
64726
- * `paused` / `returning` / `docked` / `error`. `batteryLevel`
64727
- * (0..100) is nullable — some vacuums don't report a battery
64728
- * percentage. `fanSpeed` is the current speed token (provider-verbatim,
64729
- * e.g. `'standard'` / `'turbo'`) and `availableFanSpeeds` lists the
64730
- * tokens the hardware accepts so the UI renders only supported choices.
64731
- *
64732
- * The `setFanSpeed` method takes the bare `speed` token — the provider
64733
- * validates it against the vacuum's own list. `locate` triggers the
64734
- * find-me chirp; `returnToBase` sends it home.
64735
- *
64736
- * Consumable / waste tanks: `cleanWater` / `dirtyWater` / `detergent` /
64737
- * `dustBin` each carry a nullable `{ level (0..100 %), status ('ok' |
64738
- * 'low' | 'full') }` reading. Native providers (e.g. Dreame, Roborock)
64739
- * SHOULD populate whichever tanks the hardware has — leave a field `null`
64740
- * only when the device has no such tank at all, and use a `TankStatus`
64741
- * with both inner fields `null` when the tank exists but its level is
64742
- * currently unknown. HA `vacuum.*` entities expose no per-tank telemetry,
64743
- * so the HA provider leaves all four `null`.
64744
- */
64745
- var VacuumStateSchema = _enum([
64746
- "idle",
64747
- "cleaning",
64748
- "paused",
64749
- "returning",
64750
- "docked",
64751
- "drying",
64752
- "error"
64753
- ]);
64754
- /**
64755
- * One consumable / waste tank on a robot vacuum (clean-water, dirty-water,
64756
- * detergent or dust-bin). A tank can report a numeric fill `level` (0..100),
64757
- * a discrete `status` (binary-style hardware), or both. Both `null` means the
64758
- * level is currently unknown; the OWNING field being `null` means the
64759
- * hardware has no such tank at all.
64760
- */
64761
- var TankStatusSchema = object({
64762
- /** Numeric fill 0..100 when the hardware reports a percentage; null otherwise. */
64763
- level: number().min(0).max(100).nullable(),
64764
- /** Discrete state when the hardware is binary-mode; null otherwise. */
64765
- status: _enum([
64766
- "ok",
64767
- "low",
64768
- "full"
64769
- ]).nullable()
64770
- });
64771
64850
  var VacuumControlStatusSchema = object({
64772
64851
  /** Lifecycle state of the vacuum. */
64773
- state: VacuumStateSchema,
64852
+ state: _enum([
64853
+ "idle",
64854
+ "cleaning",
64855
+ "paused",
64856
+ "returning",
64857
+ "docked",
64858
+ "drying",
64859
+ "error"
64860
+ ]),
64774
64861
  /** 0..100 battery percentage. Null when the device has no battery
64775
64862
  * reading. */
64776
64863
  batteryLevel: number().min(0).max(100).nullable(),
@@ -64779,14 +64866,6 @@ var VacuumControlStatusSchema = object({
64779
64866
  fanSpeed: string().nullable(),
64780
64867
  /** Speed tokens the hardware accepts — drives the UI selector. */
64781
64868
  availableFanSpeeds: array(string()),
64782
- /** Clean-water (mop) tank. Null when the hardware has no clean-water tank. */
64783
- cleanWater: TankStatusSchema.nullable(),
64784
- /** Dirty-water (recovery) tank. Null when the hardware has no dirty-water tank. */
64785
- dirtyWater: TankStatusSchema.nullable(),
64786
- /** Detergent tank. Null when the hardware has no detergent tank. */
64787
- detergent: TankStatusSchema.nullable(),
64788
- /** Dust bin. Null when the hardware has no dust bin. */
64789
- dustBin: TankStatusSchema.nullable(),
64790
64869
  /** 0..100 cleaning-completion percentage of the current task, or null. */
64791
64870
  progressPercent: number().min(0).max(100).nullable(),
64792
64871
  /** Current error code (0 / null = no error). */
@@ -64848,35 +64927,14 @@ var vacuumControlCapability = {
64848
64927
  */
64849
64928
  durability: "session",
64850
64929
  /**
64851
- * History (D850): recorded series. Tank levels are fixed-object paths (`cleanWater.level`, ...).
64930
+ * History (D850): recorded series. The tanks moved to `consumables` (D915), whose
64931
+ * items are keyed by runtime ids and record no history.
64852
64932
  */
64853
- history: { fields: {
64854
- batteryLevel: {
64855
- kind: "gauge",
64856
- unit: "%",
64857
- deadband: 2
64858
- },
64859
- "cleanWater.level": {
64860
- kind: "gauge",
64861
- unit: "%",
64862
- deadband: 2
64863
- },
64864
- "dirtyWater.level": {
64865
- kind: "gauge",
64866
- unit: "%",
64867
- deadband: 2
64868
- },
64869
- "detergent.level": {
64870
- kind: "gauge",
64871
- unit: "%",
64872
- deadband: 2
64873
- },
64874
- "dustBin.level": {
64875
- kind: "gauge",
64876
- unit: "%",
64877
- deadband: 2
64878
- }
64879
- } }
64933
+ history: { fields: { batteryLevel: {
64934
+ kind: "gauge",
64935
+ unit: "%",
64936
+ deadband: 2
64937
+ } } }
64880
64938
  };
64881
64939
  var ValveStatusSchema = object({
64882
64940
  /** Lifecycle state of the valve. */
@@ -69270,6 +69328,12 @@ Object.freeze({
69270
69328
  addonId: null,
69271
69329
  access: "create"
69272
69330
  },
69331
+ "deviceHistory.deleteOrphanSeries": {
69332
+ capName: "device-history",
69333
+ capScope: "system",
69334
+ addonId: null,
69335
+ access: "delete"
69336
+ },
69273
69337
  "deviceHistory.getDeviceEnabled": {
69274
69338
  capName: "device-history",
69275
69339
  capScope: "system",
@@ -69288,6 +69352,12 @@ Object.freeze({
69288
69352
  addonId: null,
69289
69353
  access: "view"
69290
69354
  },
69355
+ "deviceHistory.listOrphanSeries": {
69356
+ capName: "device-history",
69357
+ capScope: "system",
69358
+ addonId: null,
69359
+ access: "view"
69360
+ },
69291
69361
  "deviceHistory.listSeries": {
69292
69362
  capName: "device-history",
69293
69363
  capScope: "system",
@@ -79293,7 +79363,7 @@ var STATE_SUMMARY_VARS = [
79293
79363
  ([...RULE_TEXT], [...COMBINED_ALARM]),
79294
79364
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
79295
79365
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
79296
- ([...RULE_TEXT], [...CONSUMABLE]),
79366
+ ([...RULE_TEXT], [...CONSUMABLE, ...TANK]),
79297
79367
  ([...RULE_TEXT], [...TANK]),
79298
79368
  [...RULE_TEXT],
79299
79369
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
package/dist/addon.mjs CHANGED
@@ -5442,7 +5442,7 @@ var ZodIssueCode = {
5442
5442
  var ZodFirstPartyTypeKind;
5443
5443
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5444
5444
  //#endregion
5445
- //#region ../types/dist/sleep-DJFUfKvA.mjs
5445
+ //#region ../types/dist/sleep-CUp20JkO.mjs
5446
5446
  /**
5447
5447
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5448
5448
  * window to float samples (D455).
@@ -8334,7 +8334,11 @@ var ContributionSectionSchema = object({
8334
8334
  literal(4)
8335
8335
  ]).optional(),
8336
8336
  tab: string().optional(),
8337
- location: _enum(["settings", "top-tab"]).optional(),
8337
+ location: _enum([
8338
+ "settings",
8339
+ "top-tab",
8340
+ "hero"
8341
+ ]).optional(),
8338
8342
  order: number().optional(),
8339
8343
  fields: array(any())
8340
8344
  });
@@ -13301,7 +13305,11 @@ var ConfigSectionWithValuesSchema = object({
13301
13305
  literal(4)
13302
13306
  ]).optional(),
13303
13307
  tab: string().optional(),
13304
- location: _enum(["settings", "top-tab"]).optional(),
13308
+ location: _enum([
13309
+ "settings",
13310
+ "top-tab",
13311
+ "hero"
13312
+ ]).optional(),
13305
13313
  order: number().optional(),
13306
13314
  fields: array(any())
13307
13315
  });
@@ -17181,6 +17189,52 @@ var TierStatusSchema = object({
17181
17189
  countedAt: number().nullable()
17182
17190
  });
17183
17191
  /** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
17192
+ /**
17193
+ * Why a series is orphan. `device-gone`: its device is absent from the
17194
+ * successful device listings (the departure clock). `undeclared`: its `cap:`
17195
+ * key is declared by no capability any more (a field a cap removed).
17196
+ */
17197
+ var DeviceHistoryOrphanReasonSchema = _enum(["device-gone", "undeclared"]);
17198
+ /** Rows held per stored tier. */
17199
+ var TierRowsSchema = object({
17200
+ raw: number().int(),
17201
+ "5m": number().int(),
17202
+ "1h": number().int(),
17203
+ "1d": number().int()
17204
+ });
17205
+ var OrphanSeriesSchema = object({
17206
+ seriesId: number().int(),
17207
+ deviceId: number().int(),
17208
+ key: string(),
17209
+ scope: string(),
17210
+ /** The metric's display name; `null` when its metric row is gone too. */
17211
+ displayName: string().nullable(),
17212
+ reason: DeviceHistoryOrphanReasonSchema,
17213
+ /** `device-gone`: since when the device has been absent; `null` otherwise. */
17214
+ missingSince: number().nullable(),
17215
+ firstTs: number(),
17216
+ lastTs: number(),
17217
+ rows: TierRowsSchema
17218
+ });
17219
+ var DeviceHistoryOrphanDeleteRefusalSchema = _enum([
17220
+ "not-found",
17221
+ "not-orphan",
17222
+ "failed"
17223
+ ]);
17224
+ var OrphanDeleteEntrySchema = discriminatedUnion("ok", [object({
17225
+ seriesId: number().int(),
17226
+ ok: literal(true),
17227
+ deleted: TierRowsSchema
17228
+ }), object({
17229
+ seriesId: number().int(),
17230
+ ok: literal(false),
17231
+ reason: DeviceHistoryOrphanDeleteRefusalSchema
17232
+ })]);
17233
+ var OrphanListSchema = object({
17234
+ series: array(OrphanSeriesSchema).readonly(),
17235
+ /** More orphans exist than {@link DEVICE_HISTORY_ORPHAN_LIST_MAX}. */
17236
+ truncated: boolean()
17237
+ });
17184
17238
  var DeviceHistoryStatusSchema = object({
17185
17239
  startedAt: number(),
17186
17240
  /** The store is declared, series loaded and the first reconcile has answered. */
@@ -17278,7 +17332,10 @@ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly())
17278
17332
  }), object({ enabled: boolean() }), {
17279
17333
  kind: "mutation",
17280
17334
  auth: "admin"
17281
- }), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" });
17335
+ }), 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() }), {
17336
+ kind: "mutation",
17337
+ auth: "admin"
17338
+ });
17282
17339
  var DeviceCaStatusSchema = discriminatedUnion("state", [
17283
17340
  object({ state: literal("absent") }),
17284
17341
  object({
@@ -48006,7 +48063,6 @@ var RecommendationReasonSchema = discriminatedUnion("kind", [
48006
48063
  modelId: string()
48007
48064
  }),
48008
48065
  object({ kind: literal("cpu-device") }),
48009
- object({ kind: literal("coral-untouched") }),
48010
48066
  object({ kind: literal("device-disabled") }),
48011
48067
  object({ kind: literal("device-unavailable") }),
48012
48068
  object({ kind: literal("node-offline") }),
@@ -48104,11 +48160,6 @@ var AutoTuneWarningSchema = discriminatedUnion("kind", [
48104
48160
  kind: literal("detector-store-unreadable"),
48105
48161
  error: string()
48106
48162
  }),
48107
- object({
48108
- kind: literal("coral-enabled"),
48109
- nodeId: string(),
48110
- deviceKey: string()
48111
- }),
48112
48163
  object({
48113
48164
  kind: literal("custom-pin-kept"),
48114
48165
  nodeId: string(),
@@ -55256,17 +55307,69 @@ var connectivityCapability = {
55256
55307
  volatileStateFields: ["lastChangedAt"]
55257
55308
  };
55258
55309
  /**
55259
- * Generic device-consumables capability — surfaces a device's
55260
- * maintenance items (vacuum filters/brushes, replaceable cartridges,
55261
- * descaling cycles, …) with their remaining life and an optional
55262
- * "Replaced" reset action. Device-agnostic: any provider that knows its
55263
- * device tracks consumables can register it; the cap declares no
55264
- * vocabulary of its own — the provider names each item verbatim.
55310
+ * Generic device-consumables capability — the ONE place a device reports what
55311
+ * it uses up or fills: wear parts (vacuum filters/brushes, cartridges,
55312
+ * descaling cycles), supplies it draws from (a vacuum's clean-water tank and
55313
+ * detergent, a dishwasher's salt and rinse aid) and waste it collects (a dirty
55314
+ * water tank, a dust bin). Each item carries its remaining life or fill and an
55315
+ * optional "Replaced" reset action. Device-agnostic: any provider that knows
55316
+ * its device tracks consumables registers it; the provider names each item
55317
+ * verbatim and says which `kind` it is.
55318
+ *
55319
+ * The admin UI renders it as ONE collapsible section directly under the
55320
+ * device page's hero card (`placement: 'hero'`), for every device bound to
55321
+ * this cap — never drawn by a device type's hero card itself (D915).
55265
55322
  *
55266
55323
  * Like `childLayout`, the cap is INERT until a provider sets items: no
55267
55324
  * provider populates it by guessing (no HA inference). The UI renders a
55268
55325
  * "No consumables reported" placeholder when `items` is empty.
55269
55326
  */
55327
+ /**
55328
+ * What an item IS, which decides which direction is bad:
55329
+ * - `wear` — a part that wears out (a brush, a filter); low life is bad.
55330
+ * - `supply` — something the device draws from (clean water, detergent,
55331
+ * salt, rinse aid); low or empty is bad.
55332
+ * - `waste` — something the device fills (dirty water, a dust bin); full is
55333
+ * bad.
55334
+ * Absent = `wear`.
55335
+ */
55336
+ var ConsumableKindSchema = _enum([
55337
+ "wear",
55338
+ "supply",
55339
+ "waste"
55340
+ ]);
55341
+ /**
55342
+ * What an item LOOKS like, which decides how a client draws it — independent
55343
+ * of `kind`, which decides which direction is bad:
55344
+ * - `part` — a part that wears (a brush, a filter, a mop pad): a wear bar,
55345
+ * remaining time and a reset.
55346
+ * - `tank` — a container of liquid (clean water, dirty water): a fill gauge.
55347
+ * - `product` — something bought and refilled (detergent, salt, rinse aid):
55348
+ * a stepped level and "refill".
55349
+ * - `bin` — a container that collects waste (a dust bin): a fill gauge
55350
+ * that warns when full.
55351
+ * Absent = derived from the kind ({@link consumableFormOf}).
55352
+ */
55353
+ var ConsumableFormSchema = _enum([
55354
+ "part",
55355
+ "tank",
55356
+ "product",
55357
+ "bin"
55358
+ ]);
55359
+ /** The provider's own discrete verdict on an item. */
55360
+ var ConsumableStatusSchema = _enum([
55361
+ "ok",
55362
+ "low",
55363
+ "empty",
55364
+ "full",
55365
+ "replace"
55366
+ ]);
55367
+ _enum([
55368
+ "ok",
55369
+ "low",
55370
+ "empty",
55371
+ "full"
55372
+ ]);
55270
55373
  /** Units a remaining-life counter is reported in. Closed: the panel renders
55271
55374
  * each. */
55272
55375
  var ConsumableRemainingUnitSchema = _enum([
@@ -55281,18 +55384,23 @@ var ConsumableRemainingSchema = object({
55281
55384
  unit: ConsumableRemainingUnitSchema
55282
55385
  });
55283
55386
  /** A single consumable item. Either a continuous `level` (remaining
55284
- * life %) or a discrete `status` may be known — both may be null when a
55285
- * provider only knows the item exists. `level` and `status` are not
55286
- * mutually exclusive; a provider may report both. */
55387
+ * life %, or fill % for a `supply` / `waste` item) or a discrete `status`
55388
+ * may be known — both may be null when a provider only knows the item
55389
+ * exists. `level` and `status` are not mutually exclusive; a provider may
55390
+ * report both. */
55287
55391
  var ConsumableItemSchema = object({
55288
55392
  /** Stable id, e.g. 'main-brush'. */
55289
55393
  key: string().min(1),
55290
55394
  /** Display name. */
55291
55395
  label: string().min(1),
55292
- /** Remaining life % when known (0..100). */
55396
+ /** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
55293
55397
  level: number().min(0).max(100).nullable(),
55294
- /** Discrete state when known (binary mode). */
55295
- status: _enum(["ok", "replace"]).nullable(),
55398
+ /** The provider's discrete verdict when known (binary mode). */
55399
+ status: ConsumableStatusSchema.nullable(),
55400
+ /** What the item is — decides whether low or full is bad. Absent = `wear`. */
55401
+ kind: ConsumableKindSchema.optional(),
55402
+ /** How the item is drawn (part, tank, product, bin). Absent = derived from `kind`. */
55403
+ form: ConsumableFormSchema.optional(),
55296
55404
  /** Ms epoch of the last replace, when known. */
55297
55405
  lastResetAt: number().nullable(),
55298
55406
  /** Whether `reset()` is meaningful for this item. */
@@ -55315,7 +55423,7 @@ var consumablesCapability = {
55315
55423
  kind: "widget",
55316
55424
  widgetId: "host/consumables-panel",
55317
55425
  tab: "consumables",
55318
- topTab: true,
55426
+ placement: "hero",
55319
55427
  label: "Consumables",
55320
55428
  order: 5
55321
55429
  } },
@@ -55376,9 +55484,37 @@ reset: method(object({
55376
55484
  */
55377
55485
  durability: "restored",
55378
55486
  /**
55379
- * History (D850): none — `items` is an array keyed by runtime ids; a history path never enters it.
55487
+ * History (D850, D917): one series per (item field, item `key`) — the item key
55488
+ * is the series scope, the item `label` names it. A vacuum tank's fill, a
55489
+ * brush's remaining life and a dishwasher's salt are each recorded the moment
55490
+ * their provider reports them; an item that appears later gets its series.
55380
55491
  */
55381
- history: "none",
55492
+ history: {
55493
+ fields: {},
55494
+ items: {
55495
+ path: "items",
55496
+ key: "key",
55497
+ label: "label",
55498
+ fields: {
55499
+ level: {
55500
+ kind: "gauge",
55501
+ unit: "%",
55502
+ deadband: 2,
55503
+ displayName: "Level"
55504
+ },
55505
+ status: {
55506
+ kind: "enum",
55507
+ displayName: "Status"
55508
+ },
55509
+ "remaining.value": {
55510
+ kind: "gauge",
55511
+ unitFrom: "remaining.unit",
55512
+ deadband: 1,
55513
+ displayName: "Remaining"
55514
+ }
55515
+ }
55516
+ }
55517
+ },
55382
55518
  /** Clocks, not content: a re-read that changed no item costs no commit. */
55383
55519
  volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
55384
55520
  };
@@ -55793,8 +55929,9 @@ onStatusChanged: { data: object({
55793
55929
  volatileStateFields: ["lastChangedAt"]
55794
55930
  };
55795
55931
  /**
55796
- * Smart-dishwasher cap — program lifecycle, door / remote-start gates,
55797
- * consumable levels (salt, rinse aid) and common program options.
55932
+ * Smart-dishwasher cap — program lifecycle, door / remote-start gates and
55933
+ * common program options. Salt and rinse aid are NOT here: they are items of
55934
+ * the device's `consumables` cap, like every other device's (D915).
55798
55935
  *
55799
55936
  * Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
55800
55937
  * by any integration that exposes the same program / option surface.
@@ -55842,11 +55979,6 @@ var DishwasherAvailabilitySchema = _enum([
55842
55979
  "offline",
55843
55980
  "description-missing"
55844
55981
  ]);
55845
- var DishwasherConsumableLevelSchema = _enum([
55846
- "ok",
55847
- "low",
55848
- "empty"
55849
- ]);
55850
55982
  var DishwasherStatusSchema = object({
55851
55983
  availability: DishwasherAvailabilitySchema,
55852
55984
  /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
@@ -55879,8 +56011,6 @@ var DishwasherStatusSchema = object({
55879
56011
  powerOn: boolean().nullable(),
55880
56012
  /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
55881
56013
  powerState: string().nullable(),
55882
- saltLevel: DishwasherConsumableLevelSchema.nullable(),
55883
- rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
55884
56014
  /**
55885
56015
  * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
55886
56016
  * combined care-and-filter reminder raised); false when every such reminder reads clear; null
@@ -64696,60 +64826,17 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
64696
64826
  auth: "admin",
64697
64827
  access: "delete"
64698
64828
  });
64699
- /**
64700
- * Robot-vacuum cap. Models HA `vacuum.*` entities — anything with a
64701
- * cleaning lifecycle plus a return-to-base / locate surface and an
64702
- * optional fan-speed selector.
64703
- *
64704
- * State follows HA's canonical vacuum lifecycle: `idle` / `cleaning` /
64705
- * `paused` / `returning` / `docked` / `error`. `batteryLevel`
64706
- * (0..100) is nullable — some vacuums don't report a battery
64707
- * percentage. `fanSpeed` is the current speed token (provider-verbatim,
64708
- * e.g. `'standard'` / `'turbo'`) and `availableFanSpeeds` lists the
64709
- * tokens the hardware accepts so the UI renders only supported choices.
64710
- *
64711
- * The `setFanSpeed` method takes the bare `speed` token — the provider
64712
- * validates it against the vacuum's own list. `locate` triggers the
64713
- * find-me chirp; `returnToBase` sends it home.
64714
- *
64715
- * Consumable / waste tanks: `cleanWater` / `dirtyWater` / `detergent` /
64716
- * `dustBin` each carry a nullable `{ level (0..100 %), status ('ok' |
64717
- * 'low' | 'full') }` reading. Native providers (e.g. Dreame, Roborock)
64718
- * SHOULD populate whichever tanks the hardware has — leave a field `null`
64719
- * only when the device has no such tank at all, and use a `TankStatus`
64720
- * with both inner fields `null` when the tank exists but its level is
64721
- * currently unknown. HA `vacuum.*` entities expose no per-tank telemetry,
64722
- * so the HA provider leaves all four `null`.
64723
- */
64724
- var VacuumStateSchema = _enum([
64725
- "idle",
64726
- "cleaning",
64727
- "paused",
64728
- "returning",
64729
- "docked",
64730
- "drying",
64731
- "error"
64732
- ]);
64733
- /**
64734
- * One consumable / waste tank on a robot vacuum (clean-water, dirty-water,
64735
- * detergent or dust-bin). A tank can report a numeric fill `level` (0..100),
64736
- * a discrete `status` (binary-style hardware), or both. Both `null` means the
64737
- * level is currently unknown; the OWNING field being `null` means the
64738
- * hardware has no such tank at all.
64739
- */
64740
- var TankStatusSchema = object({
64741
- /** Numeric fill 0..100 when the hardware reports a percentage; null otherwise. */
64742
- level: number().min(0).max(100).nullable(),
64743
- /** Discrete state when the hardware is binary-mode; null otherwise. */
64744
- status: _enum([
64745
- "ok",
64746
- "low",
64747
- "full"
64748
- ]).nullable()
64749
- });
64750
64829
  var VacuumControlStatusSchema = object({
64751
64830
  /** Lifecycle state of the vacuum. */
64752
- state: VacuumStateSchema,
64831
+ state: _enum([
64832
+ "idle",
64833
+ "cleaning",
64834
+ "paused",
64835
+ "returning",
64836
+ "docked",
64837
+ "drying",
64838
+ "error"
64839
+ ]),
64753
64840
  /** 0..100 battery percentage. Null when the device has no battery
64754
64841
  * reading. */
64755
64842
  batteryLevel: number().min(0).max(100).nullable(),
@@ -64758,14 +64845,6 @@ var VacuumControlStatusSchema = object({
64758
64845
  fanSpeed: string().nullable(),
64759
64846
  /** Speed tokens the hardware accepts — drives the UI selector. */
64760
64847
  availableFanSpeeds: array(string()),
64761
- /** Clean-water (mop) tank. Null when the hardware has no clean-water tank. */
64762
- cleanWater: TankStatusSchema.nullable(),
64763
- /** Dirty-water (recovery) tank. Null when the hardware has no dirty-water tank. */
64764
- dirtyWater: TankStatusSchema.nullable(),
64765
- /** Detergent tank. Null when the hardware has no detergent tank. */
64766
- detergent: TankStatusSchema.nullable(),
64767
- /** Dust bin. Null when the hardware has no dust bin. */
64768
- dustBin: TankStatusSchema.nullable(),
64769
64848
  /** 0..100 cleaning-completion percentage of the current task, or null. */
64770
64849
  progressPercent: number().min(0).max(100).nullable(),
64771
64850
  /** Current error code (0 / null = no error). */
@@ -64827,35 +64906,14 @@ var vacuumControlCapability = {
64827
64906
  */
64828
64907
  durability: "session",
64829
64908
  /**
64830
- * History (D850): recorded series. Tank levels are fixed-object paths (`cleanWater.level`, ...).
64909
+ * History (D850): recorded series. The tanks moved to `consumables` (D915), whose
64910
+ * items are keyed by runtime ids and record no history.
64831
64911
  */
64832
- history: { fields: {
64833
- batteryLevel: {
64834
- kind: "gauge",
64835
- unit: "%",
64836
- deadband: 2
64837
- },
64838
- "cleanWater.level": {
64839
- kind: "gauge",
64840
- unit: "%",
64841
- deadband: 2
64842
- },
64843
- "dirtyWater.level": {
64844
- kind: "gauge",
64845
- unit: "%",
64846
- deadband: 2
64847
- },
64848
- "detergent.level": {
64849
- kind: "gauge",
64850
- unit: "%",
64851
- deadband: 2
64852
- },
64853
- "dustBin.level": {
64854
- kind: "gauge",
64855
- unit: "%",
64856
- deadband: 2
64857
- }
64858
- } }
64912
+ history: { fields: { batteryLevel: {
64913
+ kind: "gauge",
64914
+ unit: "%",
64915
+ deadband: 2
64916
+ } } }
64859
64917
  };
64860
64918
  var ValveStatusSchema = object({
64861
64919
  /** Lifecycle state of the valve. */
@@ -69249,6 +69307,12 @@ Object.freeze({
69249
69307
  addonId: null,
69250
69308
  access: "create"
69251
69309
  },
69310
+ "deviceHistory.deleteOrphanSeries": {
69311
+ capName: "device-history",
69312
+ capScope: "system",
69313
+ addonId: null,
69314
+ access: "delete"
69315
+ },
69252
69316
  "deviceHistory.getDeviceEnabled": {
69253
69317
  capName: "device-history",
69254
69318
  capScope: "system",
@@ -69267,6 +69331,12 @@ Object.freeze({
69267
69331
  addonId: null,
69268
69332
  access: "view"
69269
69333
  },
69334
+ "deviceHistory.listOrphanSeries": {
69335
+ capName: "device-history",
69336
+ capScope: "system",
69337
+ addonId: null,
69338
+ access: "view"
69339
+ },
69270
69340
  "deviceHistory.listSeries": {
69271
69341
  capName: "device-history",
69272
69342
  capScope: "system",
@@ -79272,7 +79342,7 @@ var STATE_SUMMARY_VARS = [
79272
79342
  ([...RULE_TEXT], [...COMBINED_ALARM]),
79273
79343
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
79274
79344
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
79275
- ([...RULE_TEXT], [...CONSUMABLE]),
79345
+ ([...RULE_TEXT], [...CONSUMABLE, ...TANK]),
79276
79346
  ([...RULE_TEXT], [...TANK]),
79277
79347
  [...RULE_TEXT],
79278
79348
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-wyze",
3
- "version": "0.2.154",
3
+ "version": "0.2.156",
4
4
  "description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
5
5
  "keywords": [
6
6
  "camstack",