@camstack/addon-provider-homeassistant 1.2.606 → 1.2.607

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/addon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dist = require("./dist-DrmU50mp.js");
2
+ const require_dist = require("./dist-DpZriMEh.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_zlib = require("node:zlib");
5
5
  //#region src/ha-admin-link.ts
package/dist/addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as connectivityCapability, At as boolean, B as floodCapability, Bt as EventCategory, C as buildAddonRouteProvider, Ct as defineEntryKind, D as carbonMonoxideCapability, Dt as settingsBrokersAdoptsFrom, E as calendarSourceCapability, F as deviceAdoptionCapability, Ft as record, G as lawnMowerControlCapability, H as humidifierCapability, It as string, J as motionCapability, K as lockControlCapability, L as enumSensorCapability, Lt as union, M as controlCapability, Mt as literal, N as coverCapability, Nt as number, O as climateControlCapability, Ot as _enum, P as deviceAdminLinkCapability, Pt as object, Q as numericSensorCapability, R as eventEmitterCapability, Rt as unknown, S as brokerCapability, St as createEvent, T as buttonCapability, Tt as entryBody, U as humiditySensorCapability, V as gasCapability, W as imageCapability, X as notificationOutputCapability, Y as normalizeUnit, Z as notifierCapability, _ as automationControlCapability, _t as DeviceRole, at as scriptRunnerCapability, b as binaryCapability, ct as tamperCapability, d as TargetSchema, dt as vacuumControlCapability, et as parseAdminBase, f as accessoriesCapability, ft as valveCapability, g as ambientLightSensorCapability, gt as DeviceFeature, h as alarmPanelCapability, ht as weatherCapability, it as pressureSensorCapability, j as contactCapability, jt as discriminatedUnion, k as colorCapability, kt as array, lt as temperatureSensorCapability, m as airQualitySensorCapability, mt as waterHeaterCapability, n as BaseDevice, nt as prepareNotification, ot as smokeCapability, p as addonRoutesCapability, pt as vibrationCapability, q as mediaPlayerCapability, r as BaseDeviceProvider, rt as presenceCapability, s as EnumSensorDateTimeFormatSchema, st as switchCapability, tt as powerMeterCapability, ut as updateCapability, v as batteryCapability, vt as DeviceType, w as buildDeviceAdminUrl, wt as defineRecordKinds, x as brightnessCapability, xt as RecordSecretUnavailableError, y as bestLocationMatch, yt as errMsg, z as fanControlCapability, zt as url } from "./dist-CyQP92x0.mjs";
1
+ import { A as connectivityCapability, At as boolean, B as floodCapability, Bt as EventCategory, C as buildAddonRouteProvider, Ct as defineEntryKind, D as carbonMonoxideCapability, Dt as settingsBrokersAdoptsFrom, E as calendarSourceCapability, F as deviceAdoptionCapability, Ft as record, G as lawnMowerControlCapability, H as humidifierCapability, It as string, J as motionCapability, K as lockControlCapability, L as enumSensorCapability, Lt as union, M as controlCapability, Mt as literal, N as coverCapability, Nt as number, O as climateControlCapability, Ot as _enum, P as deviceAdminLinkCapability, Pt as object, Q as numericSensorCapability, R as eventEmitterCapability, Rt as unknown, S as brokerCapability, St as createEvent, T as buttonCapability, Tt as entryBody, U as humiditySensorCapability, V as gasCapability, W as imageCapability, X as notificationOutputCapability, Y as normalizeUnit, Z as notifierCapability, _ as automationControlCapability, _t as DeviceRole, at as scriptRunnerCapability, b as binaryCapability, ct as tamperCapability, d as TargetSchema, dt as vacuumControlCapability, et as parseAdminBase, f as accessoriesCapability, ft as valveCapability, g as ambientLightSensorCapability, gt as DeviceFeature, h as alarmPanelCapability, ht as weatherCapability, it as pressureSensorCapability, j as contactCapability, jt as discriminatedUnion, k as colorCapability, kt as array, lt as temperatureSensorCapability, m as airQualitySensorCapability, mt as waterHeaterCapability, n as BaseDevice, nt as prepareNotification, ot as smokeCapability, p as addonRoutesCapability, pt as vibrationCapability, q as mediaPlayerCapability, r as BaseDeviceProvider, rt as presenceCapability, s as EnumSensorDateTimeFormatSchema, st as switchCapability, tt as powerMeterCapability, ut as updateCapability, v as batteryCapability, vt as DeviceType, w as buildDeviceAdminUrl, wt as defineRecordKinds, x as brightnessCapability, xt as RecordSecretUnavailableError, y as bestLocationMatch, yt as errMsg, z as fanControlCapability, zt as url } from "./dist-CziryNRD.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
4
4
  //#region src/ha-admin-link.ts
@@ -5546,7 +5546,7 @@ var ZodIssueCode = {
5546
5546
  var ZodFirstPartyTypeKind;
5547
5547
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5548
5548
  //#endregion
5549
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5549
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5550
5550
  /**
5551
5551
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5552
5552
  * window to float samples (D455).
@@ -17597,7 +17597,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17597
17597
  kind: literal("node"),
17598
17598
  nodeId: string().min(1)
17599
17599
  })]);
17600
+ /**
17601
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17602
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17603
+ * meaning); a rollup keeps the time spent in each state (`states`).
17604
+ */
17600
17605
  var DeviceHistoryKindSchema = _enum([
17606
+ "gauge",
17607
+ "counter",
17608
+ "boolean",
17609
+ "enum"
17610
+ ]);
17611
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17612
+ var DeviceHistoryProducerKindSchema = _enum([
17601
17613
  "gauge",
17602
17614
  "counter",
17603
17615
  "boolean"
@@ -17634,7 +17646,13 @@ var SeriesInfoSchema = object({
17634
17646
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17635
17647
  unit: string().nullable(),
17636
17648
  displayName: string(),
17637
- source: _enum(["cap", "addon"]),
17649
+ source: _enum([
17650
+ "cap",
17651
+ "addon",
17652
+ "derived"
17653
+ ]),
17654
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17655
+ values: array(string()).readonly().nullable(),
17638
17656
  firstTs: number(),
17639
17657
  lastTs: number()
17640
17658
  });
@@ -17648,17 +17666,31 @@ var QueryPointSchema = object({
17648
17666
  twMean: number().nullable(),
17649
17667
  min: number(),
17650
17668
  max: number(),
17651
- /** `null` is unknown, never zero (D393). */
17652
- last: number().nullable()
17669
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17670
+ last: number().nullable(),
17671
+ /**
17672
+ * The increase over the point: a `counter`'s growth since the previous point
17673
+ * or bucket (a drop is a reset, counted from zero), and for
17674
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17675
+ * every other kind, and when it cannot be known.
17676
+ */
17677
+ delta: number().nullable(),
17678
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17679
+ state: string().nullable(),
17680
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17681
+ states: record(string(), number()).nullable()
17653
17682
  });
17654
17683
  var QuerySeriesSchema = object({
17655
17684
  scope: string(),
17656
17685
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17657
17686
  before: object({
17658
17687
  t: number(),
17659
- value: number().nullable()
17688
+ value: number().nullable(),
17689
+ state: string().nullable()
17660
17690
  }).nullable(),
17661
- points: array(QueryPointSchema).readonly()
17691
+ points: array(QueryPointSchema).readonly(),
17692
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17693
+ derivedFrom: string().nullable()
17662
17694
  });
17663
17695
  /** The window part of a query, shared by the device and node forms. */
17664
17696
  var QueryWindowShape = {
@@ -17674,6 +17706,23 @@ var QueryResultSchema = object({
17674
17706
  series: array(QuerySeriesSchema).readonly(),
17675
17707
  truncated: boolean()
17676
17708
  });
17709
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17710
+ var QueryManyItemSchema = union([object({
17711
+ deviceId: number().int(),
17712
+ key: string(),
17713
+ scope: string().optional()
17714
+ }), object({
17715
+ forNodeId: string().min(1),
17716
+ key: string(),
17717
+ scope: string().optional()
17718
+ })]);
17719
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17720
+ ok: literal(true),
17721
+ result: QueryResultSchema
17722
+ }), object({
17723
+ ok: literal(false),
17724
+ error: string()
17725
+ })]);
17677
17726
  var TierStatusSchema = object({
17678
17727
  tier: DeviceHistoryResolutionSchema,
17679
17728
  /** `null` until the first background count answered. */
@@ -17729,16 +17778,22 @@ var DeviceHistoryStatusSchema = object({
17729
17778
  lastRefreshAt: number().nullable()
17730
17779
  })
17731
17780
  });
17732
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17781
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17733
17782
  deviceId: number().int(),
17734
17783
  ...QueryWindowShape
17735
17784
  }), QueryResultSchema), method(object({
17736
- nodeId: string().min(1),
17785
+ forNodeId: string().min(1),
17737
17786
  ...QueryWindowShape
17738
17787
  }), QueryResultSchema, { auth: "admin" }), method(object({
17788
+ items: array(QueryManyItemSchema).min(1).max(24),
17789
+ from: QueryWindowShape.from,
17790
+ to: QueryWindowShape.to,
17791
+ resolution: QueryWindowShape.resolution,
17792
+ maxPoints: QueryWindowShape.maxPoints
17793
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17739
17794
  name: string().regex(/^[a-z0-9-]+$/),
17740
17795
  subjectKind: _enum(["device", "node"]),
17741
- kind: DeviceHistoryKindSchema,
17796
+ kind: DeviceHistoryProducerKindSchema,
17742
17797
  unit: string().optional(),
17743
17798
  displayName: string().min(1),
17744
17799
  ingest: _enum(["points", "buckets"])
@@ -41181,14 +41236,106 @@ var LogEntrySchema = object({
41181
41236
  meta: record(string(), unknown()).optional(),
41182
41237
  tags: record(string(), string()).optional()
41183
41238
  });
41184
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
41185
- scope: array(string()).optional(),
41239
+ /**
41240
+ * A history READ against one destination (D898).
41241
+ *
41242
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
41243
+ * browser applied after the limit is what made a rare device's lines
41244
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
41245
+ * minted (opaque to everyone else): a file position for the rotated files, a
41246
+ * nanosecond timestamp for Loki.
41247
+ *
41248
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
41249
+ * store answers `done: false` with the cursor it reached and the bytes it
41250
+ * scanned, and the caller decides whether to go on. That is what makes a long
41251
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
41252
+ * flight, and not asking for the next slice ends the scan.
41253
+ */
41254
+ var LogReadQuerySchema = object({
41255
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
41256
+ requestId: string().min(1).max(64).optional(),
41257
+ /** The device the line is about (`tags.deviceId`, numeric). */
41258
+ deviceId: number().int().optional(),
41259
+ /**
41260
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
41261
+ * match. Not `addonId`: a cap router reads that name as "which provider".
41262
+ */
41263
+ fromAddonId: string().min(1).max(200).optional(),
41264
+ /**
41265
+ * The emitting node: matches the agent that emitted the line, the node
41266
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
41267
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
41268
+ * name as "which node's provider".
41269
+ */
41270
+ fromNodeId: string().min(1).max(200).optional(),
41271
+ /** Any other tag, exact match (AND). */
41272
+ tags: record(string(), union([string(), number()])).optional(),
41273
+ /** Severity FLOOR: this level and above. */
41186
41274
  level: LogLevelSchema.optional(),
41187
- since: date().optional(),
41188
- until: date().optional(),
41189
- limit: number().optional(),
41190
- tags: record(string(), string()).optional()
41191
- }), array(LogEntrySchema).readonly());
41275
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
41276
+ text: string().min(1).max(200).optional(),
41277
+ /** Epoch ms, inclusive. */
41278
+ since: number().optional(),
41279
+ /** Epoch ms, inclusive. */
41280
+ until: number().optional(),
41281
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
41282
+ before: string().min(1).max(1024).optional(),
41283
+ /** Newer than this cursor (exclusive). */
41284
+ after: string().min(1).max(1024).optional(),
41285
+ limit: number().int().min(1).max(1e3).optional(),
41286
+ /** Wall-clock bound of this slice. The provider caps it. */
41287
+ budgetMs: number().int().min(50).max(1e4).optional()
41288
+ });
41289
+ var LogReadResultSchema = object({
41290
+ /** Newest first. */
41291
+ entries: array(object({
41292
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
41293
+ id: string().optional(),
41294
+ /** Epoch ms. */
41295
+ timestamp: number(),
41296
+ level: LogLevelSchema,
41297
+ scope: string().optional(),
41298
+ message: string(),
41299
+ tags: record(string(), union([string(), number()])).optional(),
41300
+ meta: record(string(), unknown()).optional()
41301
+ })),
41302
+ /** Pass as `before` for the next older page; null when nothing older exists. */
41303
+ nextBefore: string().nullable(),
41304
+ /** Pass as `after` to read what arrived since; null when unknown. */
41305
+ nextAfter: string().nullable(),
41306
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
41307
+ scannedBytes: number().int().nonnegative(),
41308
+ /**
41309
+ * True when the scan in this direction reached the end of the store.
41310
+ * False with fewer than `limit` entries means the budget ran out first —
41311
+ * call again with `nextBefore` to go on.
41312
+ */
41313
+ done: boolean(),
41314
+ /** True when `cancelRead` ended this slice early. */
41315
+ cancelled: boolean().optional()
41316
+ });
41317
+ var LogReadCapabilitiesSchema = object({
41318
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
41319
+ readable: boolean(),
41320
+ /** Why not, when `readable` is false — rendered next to the source. */
41321
+ reason: string().nullable(),
41322
+ /** Filters the provider applies itself. A false one is applied by nobody. */
41323
+ filters: object({
41324
+ deviceId: boolean(),
41325
+ addonId: boolean(),
41326
+ nodeId: boolean(),
41327
+ tags: boolean(),
41328
+ level: boolean(),
41329
+ text: boolean(),
41330
+ timeRange: boolean()
41331
+ }),
41332
+ /** How far back the store reaches, when the provider knows (days). */
41333
+ retentionDays: number().nullable()
41334
+ });
41335
+ method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(_void(), LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string().min(1).max(64) }), object({ cancelled: boolean() }), {
41336
+ kind: "mutation",
41337
+ auth: "admin"
41338
+ });
41192
41339
  /**
41193
41340
  * `login-method` — collection cap through which auth addons contribute
41194
41341
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42928,9 +43075,11 @@ var alarmPanelCapability = {
42928
43075
  */
42929
43076
  durability: "restored",
42930
43077
  /**
42931
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
43078
+ * History (D850): the panel's lifecycle state as an `enum` series —
43079
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
43080
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42932
43081
  */
42933
- history: "none",
43082
+ history: { fields: { state: { kind: "enum" } } },
42934
43083
  /** Clock fields: written, but excluded from the compare that decides
42935
43084
  * whether persisting is worth a SQLite commit. */
42936
43085
  volatileStateFields: ["lastChangedAt"]
@@ -43808,6 +43957,33 @@ var NcRuleTargetSchema = object({
43808
43957
  params: record(string(), unknown()).optional()
43809
43958
  });
43810
43959
  /**
43960
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43961
+ *
43962
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43963
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43964
+ * to the zone that fired the rule) and renders it once at send time:
43965
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43966
+ * colour and every OTHER track visible at that instant outlined thin, each
43967
+ * labelled with class and confidence ("dog 87%").
43968
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43969
+ * - `clean` — the whole scene with nothing drawn on it.
43970
+ * - `none` — no picture.
43971
+ *
43972
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43973
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43974
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43975
+ * ship a crop on one event and a boxed scene on the next depending on which
43976
+ * stored kind had landed.
43977
+ */
43978
+ var NcMediaImageSchema = _enum([
43979
+ "scene-boxes",
43980
+ "crop",
43981
+ "clean",
43982
+ "none"
43983
+ ]);
43984
+ /**
43985
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43986
+ *
43811
43987
  * Media attachment policy (P1 still-image subset).
43812
43988
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43813
43989
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43821,6 +43997,8 @@ var NcRuleTargetSchema = object({
43821
43997
  * - `none` — no attachment.
43822
43998
  */
43823
43999
  /**
44000
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
44001
+ *
43824
44002
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43825
44003
  * conflate it with the selection strategy and betray the request: asking for
43826
44004
  * the clean scene frame on an object-event owner used to start at
@@ -43849,16 +44027,29 @@ var NcMediaFrameSchema = _enum([
43849
44027
  */
43850
44028
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43851
44029
  var NcMediaPolicySchema = object({
44030
+ /**
44031
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
44032
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
44033
+ * triple below, at load and at every write, and the store keeps only this.
44034
+ */
44035
+ image: NcMediaImageSchema.optional(),
44036
+ /**
44037
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
44038
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
44039
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
44040
+ * Replaces `zoneCrop`.
44041
+ */
44042
+ showTriggerZone: boolean().optional(),
44043
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43852
44044
  attach: _enum([
43853
44045
  "best",
43854
44046
  "best-matching",
43855
44047
  "keyFrame",
43856
44048
  "none"
43857
- ]).default("best"),
43858
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
44049
+ ]).optional(),
44050
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43859
44051
  frame: NcMediaFrameSchema.optional(),
43860
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43861
- * "show me the ZONE", not the whole scene or the subject crop. */
44052
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43862
44053
  zoneCrop: boolean().optional(),
43863
44054
  /**
43864
44055
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -44030,7 +44221,9 @@ var NcRuleInputSchema = object({
44030
44221
  * targets.
44031
44222
  */
44032
44223
  targetUsers: array(string()).optional(),
44033
- media: NcMediaPolicySchema.default({ attach: "best" }),
44224
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
44225
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
44226
+ media: NcMediaPolicySchema.default({}),
44034
44227
  throttle: NcThrottleSchema.default({
44035
44228
  cooldownSec: 60,
44036
44229
  scope: "rule-device"
@@ -44967,13 +45160,37 @@ var NcAlarmModeOpeningsSchema = object({
44967
45160
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44968
45161
  unknown: array(number().int())
44969
45162
  });
45163
+ /**
45164
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
45165
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
45166
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
45167
+ * never looks fully armed (D62: off must never look like broken).
45168
+ */
45169
+ var NcAlarmInputBypassViewSchema = object({
45170
+ ruleId: string(),
45171
+ /** The rule's current name (its frozen name when the rule is gone). */
45172
+ ruleName: string(),
45173
+ /** The input: the sensor of the match, else its camera. */
45174
+ deviceId: number().int(),
45175
+ /** The input's current name. */
45176
+ name: string(),
45177
+ /** When it was bypassed (ms epoch). */
45178
+ since: number(),
45179
+ /** Triggers from this input dropped since. */
45180
+ dropped: number().int().min(0)
45181
+ });
44970
45182
  var NcAlarmLiveSchema = object({
44971
45183
  state: AlarmStateSchema,
44972
45184
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44973
45185
  targetMode: AlarmArmModeSchema.nullable(),
44974
45186
  availableModes: array(AlarmArmModeSchema),
44975
45187
  openings: array(NcAlarmModeOpeningsSchema),
44976
- exclusions: array(NcAlarmExclusionViewSchema)
45188
+ exclusions: array(NcAlarmExclusionViewSchema),
45189
+ /**
45190
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
45191
+ * Defaulted so an older hub answer still parses (as "none known").
45192
+ */
45193
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44977
45194
  });
44978
45195
  var NcAlarmConfigSchema = object({
44979
45196
  /**
@@ -55807,9 +56024,11 @@ var connectivityCapability = {
55807
56024
  */
55808
56025
  durability: "restored",
55809
56026
  /**
55810
- * History (D850): none — duplicates device-status.online (one authority for availability).
56027
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
56028
+ * is the upstream entity's own link (a HA connectivity sensor), not the
56029
+ * device's reachability, which stays `device-status.online`.
55811
56030
  */
55812
- history: "none",
56031
+ history: { fields: { connected: { kind: "boolean" } } },
55813
56032
  /** Clock fields: written, but excluded from the compare that decides
55814
56033
  * whether persisting is worth a SQLite commit. */
55815
56034
  volatileStateFields: ["lastChangedAt"]
@@ -56633,11 +56852,22 @@ var dishwasherCapability = {
56633
56852
  },
56634
56853
  runtimeState: DishwasherStatusSchema,
56635
56854
  durability: "session",
56636
- history: { fields: { progressPercent: {
56637
- kind: "gauge",
56638
- unit: "%",
56639
- deadband: 2
56640
- } } }
56855
+ history: { fields: {
56856
+ progressPercent: {
56857
+ kind: "gauge",
56858
+ unit: "%",
56859
+ deadband: 2
56860
+ },
56861
+ state: { kind: "enum" },
56862
+ operationState: { kind: "enum" },
56863
+ remainingSeconds: {
56864
+ kind: "gauge",
56865
+ unit: "s",
56866
+ minIntervalMs: 6e4
56867
+ },
56868
+ doorOpen: { kind: "boolean" },
56869
+ powerOn: { kind: "boolean" }
56870
+ } }
56641
56871
  };
56642
56872
  var DoorbellStatusSchema = object({
56643
56873
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -56754,9 +56984,15 @@ var enumSensorCapability = {
56754
56984
  */
56755
56985
  durability: "restored",
56756
56986
  /**
56757
- * History (D850): none — text/enum state has no history (non-goal).
56987
+ * History (D850): the value as an `enum` series (an appliance's program or
56988
+ * operation state, an HVAC action). The option set is per device, so the
56989
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
56990
+ * `format` carries a timestamp, not a state, and is not recorded.
56758
56991
  */
56759
- history: "none",
56992
+ history: { fields: { value: {
56993
+ kind: "enum",
56994
+ skipWhenSet: "format"
56995
+ } } },
56760
56996
  /** Clock fields: written, but excluded from the compare that decides
56761
56997
  * whether persisting is worth a SQLite commit. */
56762
56998
  volatileStateFields: ["lastFetchedAt"]
@@ -58730,9 +58966,10 @@ var lockControlCapability = {
58730
58966
  */
58731
58967
  durability: "restored",
58732
58968
  /**
58733
- * History (D850): none — enum state; lock events belong in the events ledger.
58969
+ * History (D850): the lock's state as an `enum` series — change-only, no
58970
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
58734
58971
  */
58735
- history: "none",
58972
+ history: { fields: { state: { kind: "enum" } } },
58736
58973
  /** Clock fields: written, but excluded from the compare that decides
58737
58974
  * whether persisting is worth a SQLite commit. */
58738
58975
  volatileStateFields: ["lastChangedAt"]
@@ -58906,9 +59143,18 @@ var mediaPlayerCapability = {
58906
59143
  */
58907
59144
  durability: "session",
58908
59145
  /**
58909
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
59146
+ * History (D850): volume (a level an operator or an automation sets; the
59147
+ * default 10 s floor folds a slider drag into its end value) and mute.
59148
+ * `positionMs` is not recorded: it moves continuously while playing.
58910
59149
  */
58911
- history: "none"
59150
+ history: { fields: {
59151
+ volumeLevel: {
59152
+ kind: "gauge",
59153
+ unit: "%",
59154
+ deadband: 1
59155
+ },
59156
+ isMuted: { kind: "boolean" }
59157
+ } }
58912
59158
  };
58913
59159
  /**
58914
59160
  * mesh-network — collection cap for mesh-VPN providers.
@@ -64201,9 +64447,29 @@ var streamParamsCapability = {
64201
64447
  */
64202
64448
  durability: "restored",
64203
64449
  /**
64204
- * History (D850): none — encoder configuration.
64450
+ * History (D850): the configured bitrate and frame rate of the main and sub
64451
+ * profiles. Configuration, so change-only on the default floor: a point is an
64452
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
64453
+ * quality over time must show.
64205
64454
  */
64206
- history: "none",
64455
+ history: { fields: {
64456
+ "main.bitrate": {
64457
+ kind: "gauge",
64458
+ unit: "kbps"
64459
+ },
64460
+ "main.framerate": {
64461
+ kind: "gauge",
64462
+ unit: "fps"
64463
+ },
64464
+ "sub.bitrate": {
64465
+ kind: "gauge",
64466
+ unit: "kbps"
64467
+ },
64468
+ "sub.framerate": {
64469
+ kind: "gauge",
64470
+ unit: "fps"
64471
+ }
64472
+ } },
64207
64473
  /** Clock fields: written, but excluded from the compare that decides
64208
64474
  * whether persisting is worth a SQLite commit. */
64209
64475
  volatileStateFields: ["lastFetchedAt"]
@@ -67381,6 +67647,15 @@ var BaseDevice = class {
67381
67647
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
67382
67648
  * with a typed cast.
67383
67649
  *
67650
+ * Answer what you KNOW. A plain array is read as the complete list only
67651
+ * while this device is `online` and probed; return
67652
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
67653
+ * now (no credentials, parent not connected, a failed or partial read) —
67654
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
67655
+ * to say "connected, and this is the complete list" explicitly. A shrink is
67656
+ * deleted only after a second agreeing complete read on a later probe (D49;
67657
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
67658
+ *
67384
67659
  * Default: no children.
67385
67660
  */
67386
67661
  getAccessoryChildren() {
@@ -71512,7 +71787,19 @@ Object.freeze({
71512
71787
  addonId: null,
71513
71788
  access: "view"
71514
71789
  },
71515
- "logDestination.query": {
71790
+ "logDestination.cancelRead": {
71791
+ capName: "log-destination",
71792
+ capScope: "system",
71793
+ addonId: null,
71794
+ access: "create"
71795
+ },
71796
+ "logDestination.describeRead": {
71797
+ capName: "log-destination",
71798
+ capScope: "system",
71799
+ addonId: null,
71800
+ access: "view"
71801
+ },
71802
+ "logDestination.read": {
71516
71803
  capName: "log-destination",
71517
71804
  capScope: "system",
71518
71805
  addonId: null,
@@ -77519,6 +77806,11 @@ Object.freeze({
77519
77806
  form: "single",
77520
77807
  optional: false
77521
77808
  }],
77809
+ "logDestination.read": [{
77810
+ name: "deviceId",
77811
+ form: "single",
77812
+ optional: true
77813
+ }],
77522
77814
  "mediaPlayer.getStatus": [{
77523
77815
  name: "deviceId",
77524
77816
  form: "single",
@@ -5547,7 +5547,7 @@ var ZodIssueCode = {
5547
5547
  var ZodFirstPartyTypeKind;
5548
5548
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5549
5549
  //#endregion
5550
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5550
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5551
5551
  /**
5552
5552
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5553
5553
  * window to float samples (D455).
@@ -17598,7 +17598,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17598
17598
  kind: literal("node"),
17599
17599
  nodeId: string().min(1)
17600
17600
  })]);
17601
+ /**
17602
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17603
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17604
+ * meaning); a rollup keeps the time spent in each state (`states`).
17605
+ */
17601
17606
  var DeviceHistoryKindSchema = _enum([
17607
+ "gauge",
17608
+ "counter",
17609
+ "boolean",
17610
+ "enum"
17611
+ ]);
17612
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17613
+ var DeviceHistoryProducerKindSchema = _enum([
17602
17614
  "gauge",
17603
17615
  "counter",
17604
17616
  "boolean"
@@ -17635,7 +17647,13 @@ var SeriesInfoSchema = object({
17635
17647
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17636
17648
  unit: string().nullable(),
17637
17649
  displayName: string(),
17638
- source: _enum(["cap", "addon"]),
17650
+ source: _enum([
17651
+ "cap",
17652
+ "addon",
17653
+ "derived"
17654
+ ]),
17655
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17656
+ values: array(string()).readonly().nullable(),
17639
17657
  firstTs: number(),
17640
17658
  lastTs: number()
17641
17659
  });
@@ -17649,17 +17667,31 @@ var QueryPointSchema = object({
17649
17667
  twMean: number().nullable(),
17650
17668
  min: number(),
17651
17669
  max: number(),
17652
- /** `null` is unknown, never zero (D393). */
17653
- last: number().nullable()
17670
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17671
+ last: number().nullable(),
17672
+ /**
17673
+ * The increase over the point: a `counter`'s growth since the previous point
17674
+ * or bucket (a drop is a reset, counted from zero), and for
17675
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17676
+ * every other kind, and when it cannot be known.
17677
+ */
17678
+ delta: number().nullable(),
17679
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17680
+ state: string().nullable(),
17681
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17682
+ states: record(string(), number()).nullable()
17654
17683
  });
17655
17684
  var QuerySeriesSchema = object({
17656
17685
  scope: string(),
17657
17686
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17658
17687
  before: object({
17659
17688
  t: number(),
17660
- value: number().nullable()
17689
+ value: number().nullable(),
17690
+ state: string().nullable()
17661
17691
  }).nullable(),
17662
- points: array(QueryPointSchema).readonly()
17692
+ points: array(QueryPointSchema).readonly(),
17693
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17694
+ derivedFrom: string().nullable()
17663
17695
  });
17664
17696
  /** The window part of a query, shared by the device and node forms. */
17665
17697
  var QueryWindowShape = {
@@ -17675,6 +17707,23 @@ var QueryResultSchema = object({
17675
17707
  series: array(QuerySeriesSchema).readonly(),
17676
17708
  truncated: boolean()
17677
17709
  });
17710
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17711
+ var QueryManyItemSchema = union([object({
17712
+ deviceId: number().int(),
17713
+ key: string(),
17714
+ scope: string().optional()
17715
+ }), object({
17716
+ forNodeId: string().min(1),
17717
+ key: string(),
17718
+ scope: string().optional()
17719
+ })]);
17720
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17721
+ ok: literal(true),
17722
+ result: QueryResultSchema
17723
+ }), object({
17724
+ ok: literal(false),
17725
+ error: string()
17726
+ })]);
17678
17727
  var TierStatusSchema = object({
17679
17728
  tier: DeviceHistoryResolutionSchema,
17680
17729
  /** `null` until the first background count answered. */
@@ -17730,16 +17779,22 @@ var DeviceHistoryStatusSchema = object({
17730
17779
  lastRefreshAt: number().nullable()
17731
17780
  })
17732
17781
  });
17733
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17782
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17734
17783
  deviceId: number().int(),
17735
17784
  ...QueryWindowShape
17736
17785
  }), QueryResultSchema), method(object({
17737
- nodeId: string().min(1),
17786
+ forNodeId: string().min(1),
17738
17787
  ...QueryWindowShape
17739
17788
  }), QueryResultSchema, { auth: "admin" }), method(object({
17789
+ items: array(QueryManyItemSchema).min(1).max(24),
17790
+ from: QueryWindowShape.from,
17791
+ to: QueryWindowShape.to,
17792
+ resolution: QueryWindowShape.resolution,
17793
+ maxPoints: QueryWindowShape.maxPoints
17794
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17740
17795
  name: string().regex(/^[a-z0-9-]+$/),
17741
17796
  subjectKind: _enum(["device", "node"]),
17742
- kind: DeviceHistoryKindSchema,
17797
+ kind: DeviceHistoryProducerKindSchema,
17743
17798
  unit: string().optional(),
17744
17799
  displayName: string().min(1),
17745
17800
  ingest: _enum(["points", "buckets"])
@@ -41182,14 +41237,106 @@ var LogEntrySchema = object({
41182
41237
  meta: record(string(), unknown()).optional(),
41183
41238
  tags: record(string(), string()).optional()
41184
41239
  });
41185
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
41186
- scope: array(string()).optional(),
41240
+ /**
41241
+ * A history READ against one destination (D898).
41242
+ *
41243
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
41244
+ * browser applied after the limit is what made a rare device's lines
41245
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
41246
+ * minted (opaque to everyone else): a file position for the rotated files, a
41247
+ * nanosecond timestamp for Loki.
41248
+ *
41249
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
41250
+ * store answers `done: false` with the cursor it reached and the bytes it
41251
+ * scanned, and the caller decides whether to go on. That is what makes a long
41252
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
41253
+ * flight, and not asking for the next slice ends the scan.
41254
+ */
41255
+ var LogReadQuerySchema = object({
41256
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
41257
+ requestId: string().min(1).max(64).optional(),
41258
+ /** The device the line is about (`tags.deviceId`, numeric). */
41259
+ deviceId: number().int().optional(),
41260
+ /**
41261
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
41262
+ * match. Not `addonId`: a cap router reads that name as "which provider".
41263
+ */
41264
+ fromAddonId: string().min(1).max(200).optional(),
41265
+ /**
41266
+ * The emitting node: matches the agent that emitted the line, the node
41267
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
41268
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
41269
+ * name as "which node's provider".
41270
+ */
41271
+ fromNodeId: string().min(1).max(200).optional(),
41272
+ /** Any other tag, exact match (AND). */
41273
+ tags: record(string(), union([string(), number()])).optional(),
41274
+ /** Severity FLOOR: this level and above. */
41187
41275
  level: LogLevelSchema.optional(),
41188
- since: date().optional(),
41189
- until: date().optional(),
41190
- limit: number().optional(),
41191
- tags: record(string(), string()).optional()
41192
- }), array(LogEntrySchema).readonly());
41276
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
41277
+ text: string().min(1).max(200).optional(),
41278
+ /** Epoch ms, inclusive. */
41279
+ since: number().optional(),
41280
+ /** Epoch ms, inclusive. */
41281
+ until: number().optional(),
41282
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
41283
+ before: string().min(1).max(1024).optional(),
41284
+ /** Newer than this cursor (exclusive). */
41285
+ after: string().min(1).max(1024).optional(),
41286
+ limit: number().int().min(1).max(1e3).optional(),
41287
+ /** Wall-clock bound of this slice. The provider caps it. */
41288
+ budgetMs: number().int().min(50).max(1e4).optional()
41289
+ });
41290
+ var LogReadResultSchema = object({
41291
+ /** Newest first. */
41292
+ entries: array(object({
41293
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
41294
+ id: string().optional(),
41295
+ /** Epoch ms. */
41296
+ timestamp: number(),
41297
+ level: LogLevelSchema,
41298
+ scope: string().optional(),
41299
+ message: string(),
41300
+ tags: record(string(), union([string(), number()])).optional(),
41301
+ meta: record(string(), unknown()).optional()
41302
+ })),
41303
+ /** Pass as `before` for the next older page; null when nothing older exists. */
41304
+ nextBefore: string().nullable(),
41305
+ /** Pass as `after` to read what arrived since; null when unknown. */
41306
+ nextAfter: string().nullable(),
41307
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
41308
+ scannedBytes: number().int().nonnegative(),
41309
+ /**
41310
+ * True when the scan in this direction reached the end of the store.
41311
+ * False with fewer than `limit` entries means the budget ran out first —
41312
+ * call again with `nextBefore` to go on.
41313
+ */
41314
+ done: boolean(),
41315
+ /** True when `cancelRead` ended this slice early. */
41316
+ cancelled: boolean().optional()
41317
+ });
41318
+ var LogReadCapabilitiesSchema = object({
41319
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
41320
+ readable: boolean(),
41321
+ /** Why not, when `readable` is false — rendered next to the source. */
41322
+ reason: string().nullable(),
41323
+ /** Filters the provider applies itself. A false one is applied by nobody. */
41324
+ filters: object({
41325
+ deviceId: boolean(),
41326
+ addonId: boolean(),
41327
+ nodeId: boolean(),
41328
+ tags: boolean(),
41329
+ level: boolean(),
41330
+ text: boolean(),
41331
+ timeRange: boolean()
41332
+ }),
41333
+ /** How far back the store reaches, when the provider knows (days). */
41334
+ retentionDays: number().nullable()
41335
+ });
41336
+ method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(_void(), LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string().min(1).max(64) }), object({ cancelled: boolean() }), {
41337
+ kind: "mutation",
41338
+ auth: "admin"
41339
+ });
41193
41340
  /**
41194
41341
  * `login-method` — collection cap through which auth addons contribute
41195
41342
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42929,9 +43076,11 @@ var alarmPanelCapability = {
42929
43076
  */
42930
43077
  durability: "restored",
42931
43078
  /**
42932
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
43079
+ * History (D850): the panel's lifecycle state as an `enum` series —
43080
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
43081
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42933
43082
  */
42934
- history: "none",
43083
+ history: { fields: { state: { kind: "enum" } } },
42935
43084
  /** Clock fields: written, but excluded from the compare that decides
42936
43085
  * whether persisting is worth a SQLite commit. */
42937
43086
  volatileStateFields: ["lastChangedAt"]
@@ -43809,6 +43958,33 @@ var NcRuleTargetSchema = object({
43809
43958
  params: record(string(), unknown()).optional()
43810
43959
  });
43811
43960
  /**
43961
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43962
+ *
43963
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43964
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43965
+ * to the zone that fired the rule) and renders it once at send time:
43966
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43967
+ * colour and every OTHER track visible at that instant outlined thin, each
43968
+ * labelled with class and confidence ("dog 87%").
43969
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43970
+ * - `clean` — the whole scene with nothing drawn on it.
43971
+ * - `none` — no picture.
43972
+ *
43973
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43974
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43975
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43976
+ * ship a crop on one event and a boxed scene on the next depending on which
43977
+ * stored kind had landed.
43978
+ */
43979
+ var NcMediaImageSchema = _enum([
43980
+ "scene-boxes",
43981
+ "crop",
43982
+ "clean",
43983
+ "none"
43984
+ ]);
43985
+ /**
43986
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43987
+ *
43812
43988
  * Media attachment policy (P1 still-image subset).
43813
43989
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43814
43990
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43822,6 +43998,8 @@ var NcRuleTargetSchema = object({
43822
43998
  * - `none` — no attachment.
43823
43999
  */
43824
44000
  /**
44001
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
44002
+ *
43825
44003
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43826
44004
  * conflate it with the selection strategy and betray the request: asking for
43827
44005
  * the clean scene frame on an object-event owner used to start at
@@ -43850,16 +44028,29 @@ var NcMediaFrameSchema = _enum([
43850
44028
  */
43851
44029
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43852
44030
  var NcMediaPolicySchema = object({
44031
+ /**
44032
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
44033
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
44034
+ * triple below, at load and at every write, and the store keeps only this.
44035
+ */
44036
+ image: NcMediaImageSchema.optional(),
44037
+ /**
44038
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
44039
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
44040
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
44041
+ * Replaces `zoneCrop`.
44042
+ */
44043
+ showTriggerZone: boolean().optional(),
44044
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43853
44045
  attach: _enum([
43854
44046
  "best",
43855
44047
  "best-matching",
43856
44048
  "keyFrame",
43857
44049
  "none"
43858
- ]).default("best"),
43859
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
44050
+ ]).optional(),
44051
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43860
44052
  frame: NcMediaFrameSchema.optional(),
43861
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43862
- * "show me the ZONE", not the whole scene or the subject crop. */
44053
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43863
44054
  zoneCrop: boolean().optional(),
43864
44055
  /**
43865
44056
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -44031,7 +44222,9 @@ var NcRuleInputSchema = object({
44031
44222
  * targets.
44032
44223
  */
44033
44224
  targetUsers: array(string()).optional(),
44034
- media: NcMediaPolicySchema.default({ attach: "best" }),
44225
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
44226
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
44227
+ media: NcMediaPolicySchema.default({}),
44035
44228
  throttle: NcThrottleSchema.default({
44036
44229
  cooldownSec: 60,
44037
44230
  scope: "rule-device"
@@ -44968,13 +45161,37 @@ var NcAlarmModeOpeningsSchema = object({
44968
45161
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44969
45162
  unknown: array(number().int())
44970
45163
  });
45164
+ /**
45165
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
45166
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
45167
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
45168
+ * never looks fully armed (D62: off must never look like broken).
45169
+ */
45170
+ var NcAlarmInputBypassViewSchema = object({
45171
+ ruleId: string(),
45172
+ /** The rule's current name (its frozen name when the rule is gone). */
45173
+ ruleName: string(),
45174
+ /** The input: the sensor of the match, else its camera. */
45175
+ deviceId: number().int(),
45176
+ /** The input's current name. */
45177
+ name: string(),
45178
+ /** When it was bypassed (ms epoch). */
45179
+ since: number(),
45180
+ /** Triggers from this input dropped since. */
45181
+ dropped: number().int().min(0)
45182
+ });
44971
45183
  var NcAlarmLiveSchema = object({
44972
45184
  state: AlarmStateSchema,
44973
45185
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44974
45186
  targetMode: AlarmArmModeSchema.nullable(),
44975
45187
  availableModes: array(AlarmArmModeSchema),
44976
45188
  openings: array(NcAlarmModeOpeningsSchema),
44977
- exclusions: array(NcAlarmExclusionViewSchema)
45189
+ exclusions: array(NcAlarmExclusionViewSchema),
45190
+ /**
45191
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
45192
+ * Defaulted so an older hub answer still parses (as "none known").
45193
+ */
45194
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44978
45195
  });
44979
45196
  var NcAlarmConfigSchema = object({
44980
45197
  /**
@@ -55808,9 +56025,11 @@ var connectivityCapability = {
55808
56025
  */
55809
56026
  durability: "restored",
55810
56027
  /**
55811
- * History (D850): none — duplicates device-status.online (one authority for availability).
56028
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
56029
+ * is the upstream entity's own link (a HA connectivity sensor), not the
56030
+ * device's reachability, which stays `device-status.online`.
55812
56031
  */
55813
- history: "none",
56032
+ history: { fields: { connected: { kind: "boolean" } } },
55814
56033
  /** Clock fields: written, but excluded from the compare that decides
55815
56034
  * whether persisting is worth a SQLite commit. */
55816
56035
  volatileStateFields: ["lastChangedAt"]
@@ -56634,11 +56853,22 @@ var dishwasherCapability = {
56634
56853
  },
56635
56854
  runtimeState: DishwasherStatusSchema,
56636
56855
  durability: "session",
56637
- history: { fields: { progressPercent: {
56638
- kind: "gauge",
56639
- unit: "%",
56640
- deadband: 2
56641
- } } }
56856
+ history: { fields: {
56857
+ progressPercent: {
56858
+ kind: "gauge",
56859
+ unit: "%",
56860
+ deadband: 2
56861
+ },
56862
+ state: { kind: "enum" },
56863
+ operationState: { kind: "enum" },
56864
+ remainingSeconds: {
56865
+ kind: "gauge",
56866
+ unit: "s",
56867
+ minIntervalMs: 6e4
56868
+ },
56869
+ doorOpen: { kind: "boolean" },
56870
+ powerOn: { kind: "boolean" }
56871
+ } }
56642
56872
  };
56643
56873
  var DoorbellStatusSchema = object({
56644
56874
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -56755,9 +56985,15 @@ var enumSensorCapability = {
56755
56985
  */
56756
56986
  durability: "restored",
56757
56987
  /**
56758
- * History (D850): none — text/enum state has no history (non-goal).
56988
+ * History (D850): the value as an `enum` series (an appliance's program or
56989
+ * operation state, an HVAC action). The option set is per device, so the
56990
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
56991
+ * `format` carries a timestamp, not a state, and is not recorded.
56759
56992
  */
56760
- history: "none",
56993
+ history: { fields: { value: {
56994
+ kind: "enum",
56995
+ skipWhenSet: "format"
56996
+ } } },
56761
56997
  /** Clock fields: written, but excluded from the compare that decides
56762
56998
  * whether persisting is worth a SQLite commit. */
56763
56999
  volatileStateFields: ["lastFetchedAt"]
@@ -58731,9 +58967,10 @@ var lockControlCapability = {
58731
58967
  */
58732
58968
  durability: "restored",
58733
58969
  /**
58734
- * History (D850): none — enum state; lock events belong in the events ledger.
58970
+ * History (D850): the lock's state as an `enum` series — change-only, no
58971
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
58735
58972
  */
58736
- history: "none",
58973
+ history: { fields: { state: { kind: "enum" } } },
58737
58974
  /** Clock fields: written, but excluded from the compare that decides
58738
58975
  * whether persisting is worth a SQLite commit. */
58739
58976
  volatileStateFields: ["lastChangedAt"]
@@ -58907,9 +59144,18 @@ var mediaPlayerCapability = {
58907
59144
  */
58908
59145
  durability: "session",
58909
59146
  /**
58910
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
59147
+ * History (D850): volume (a level an operator or an automation sets; the
59148
+ * default 10 s floor folds a slider drag into its end value) and mute.
59149
+ * `positionMs` is not recorded: it moves continuously while playing.
58911
59150
  */
58912
- history: "none"
59151
+ history: { fields: {
59152
+ volumeLevel: {
59153
+ kind: "gauge",
59154
+ unit: "%",
59155
+ deadband: 1
59156
+ },
59157
+ isMuted: { kind: "boolean" }
59158
+ } }
58913
59159
  };
58914
59160
  /**
58915
59161
  * mesh-network — collection cap for mesh-VPN providers.
@@ -64202,9 +64448,29 @@ var streamParamsCapability = {
64202
64448
  */
64203
64449
  durability: "restored",
64204
64450
  /**
64205
- * History (D850): none — encoder configuration.
64451
+ * History (D850): the configured bitrate and frame rate of the main and sub
64452
+ * profiles. Configuration, so change-only on the default floor: a point is an
64453
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
64454
+ * quality over time must show.
64206
64455
  */
64207
- history: "none",
64456
+ history: { fields: {
64457
+ "main.bitrate": {
64458
+ kind: "gauge",
64459
+ unit: "kbps"
64460
+ },
64461
+ "main.framerate": {
64462
+ kind: "gauge",
64463
+ unit: "fps"
64464
+ },
64465
+ "sub.bitrate": {
64466
+ kind: "gauge",
64467
+ unit: "kbps"
64468
+ },
64469
+ "sub.framerate": {
64470
+ kind: "gauge",
64471
+ unit: "fps"
64472
+ }
64473
+ } },
64208
64474
  /** Clock fields: written, but excluded from the compare that decides
64209
64475
  * whether persisting is worth a SQLite commit. */
64210
64476
  volatileStateFields: ["lastFetchedAt"]
@@ -67382,6 +67648,15 @@ var BaseDevice = class {
67382
67648
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
67383
67649
  * with a typed cast.
67384
67650
  *
67651
+ * Answer what you KNOW. A plain array is read as the complete list only
67652
+ * while this device is `online` and probed; return
67653
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
67654
+ * now (no credentials, parent not connected, a failed or partial read) —
67655
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
67656
+ * to say "connected, and this is the complete list" explicitly. A shrink is
67657
+ * deleted only after a second agreeing complete read on a later probe (D49;
67658
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
67659
+ *
67385
67660
  * Default: no children.
67386
67661
  */
67387
67662
  getAccessoryChildren() {
@@ -71513,7 +71788,19 @@ Object.freeze({
71513
71788
  addonId: null,
71514
71789
  access: "view"
71515
71790
  },
71516
- "logDestination.query": {
71791
+ "logDestination.cancelRead": {
71792
+ capName: "log-destination",
71793
+ capScope: "system",
71794
+ addonId: null,
71795
+ access: "create"
71796
+ },
71797
+ "logDestination.describeRead": {
71798
+ capName: "log-destination",
71799
+ capScope: "system",
71800
+ addonId: null,
71801
+ access: "view"
71802
+ },
71803
+ "logDestination.read": {
71517
71804
  capName: "log-destination",
71518
71805
  capScope: "system",
71519
71806
  addonId: null,
@@ -77520,6 +77807,11 @@ Object.freeze({
77520
77807
  form: "single",
77521
77808
  optional: false
77522
77809
  }],
77810
+ "logDestination.read": [{
77811
+ name: "deviceId",
77812
+ form: "single",
77813
+ optional: true
77814
+ }],
77523
77815
  "mediaPlayer.getStatus": [{
77524
77816
  name: "deviceId",
77525
77817
  form: "single",
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  enumerable: true
25
25
  }) : target, mod));
26
26
  //#endregion
27
- const require_dist = require("../dist-DrmU50mp.js");
27
+ const require_dist = require("../dist-DpZriMEh.js");
28
28
  let node_crypto = require("node:crypto");
29
29
  require("node:zlib");
30
30
  let node_fs = require("node:fs");
@@ -1,4 +1,4 @@
1
- import { $ as oauthIntegrationCapability, Bt as EventCategory, C as buildAddonRouteProvider, Et as nodePin, I as deviceExportCapability, It as string, a as COCO_TO_MACRO, bt as BaseAddon, c as FanDirectionSchema, i as CAMERA_SWITCH_ORDER, l as HvacModeSchema, o as CameraSwitchIdSchema, p as addonRoutesCapability, t as AlarmArmModeSchema, u as MediaPlayerRepeatSchema } from "../dist-CyQP92x0.mjs";
1
+ import { $ as oauthIntegrationCapability, Bt as EventCategory, C as buildAddonRouteProvider, Et as nodePin, I as deviceExportCapability, It as string, a as COCO_TO_MACRO, bt as BaseAddon, c as FanDirectionSchema, i as CAMERA_SWITCH_ORDER, l as HvacModeSchema, o as CameraSwitchIdSchema, p as addonRoutesCapability, t as AlarmArmModeSchema, u as MediaPlayerRepeatSchema } from "../dist-CziryNRD.mjs";
2
2
  import { createHmac, timingSafeEqual } from "node:crypto";
3
3
  import "node:zlib";
4
4
  import "node:fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.2.606",
3
+ "version": "1.2.607",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",