@camstack/addon-provider-rademacher 0.2.131 → 0.2.132

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 +332 -40
  2. package/dist/addon.mjs +332 -40
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -6399,7 +6399,7 @@ var ZodIssueCode = {
6399
6399
  var ZodFirstPartyTypeKind;
6400
6400
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6401
6401
  //#endregion
6402
- //#region ../types/dist/sleep-yKL5gfrH.mjs
6402
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
6403
6403
  /**
6404
6404
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6405
6405
  * window to float samples (D455).
@@ -17979,7 +17979,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17979
17979
  kind: literal("node"),
17980
17980
  nodeId: string().min(1)
17981
17981
  })]);
17982
+ /**
17983
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17984
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17985
+ * meaning); a rollup keeps the time spent in each state (`states`).
17986
+ */
17982
17987
  var DeviceHistoryKindSchema = _enum([
17988
+ "gauge",
17989
+ "counter",
17990
+ "boolean",
17991
+ "enum"
17992
+ ]);
17993
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17994
+ var DeviceHistoryProducerKindSchema = _enum([
17983
17995
  "gauge",
17984
17996
  "counter",
17985
17997
  "boolean"
@@ -18016,7 +18028,13 @@ var SeriesInfoSchema = object({
18016
18028
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
18017
18029
  unit: string().nullable(),
18018
18030
  displayName: string(),
18019
- source: _enum(["cap", "addon"]),
18031
+ source: _enum([
18032
+ "cap",
18033
+ "addon",
18034
+ "derived"
18035
+ ]),
18036
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
18037
+ values: array(string()).readonly().nullable(),
18020
18038
  firstTs: number(),
18021
18039
  lastTs: number()
18022
18040
  });
@@ -18030,17 +18048,31 @@ var QueryPointSchema = object({
18030
18048
  twMean: number().nullable(),
18031
18049
  min: number(),
18032
18050
  max: number(),
18033
- /** `null` is unknown, never zero (D393). */
18034
- last: number().nullable()
18051
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
18052
+ last: number().nullable(),
18053
+ /**
18054
+ * The increase over the point: a `counter`'s growth since the previous point
18055
+ * or bucket (a drop is a reset, counted from zero), and for
18056
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
18057
+ * every other kind, and when it cannot be known.
18058
+ */
18059
+ delta: number().nullable(),
18060
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
18061
+ state: string().nullable(),
18062
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
18063
+ states: record(string(), number()).nullable()
18035
18064
  });
18036
18065
  var QuerySeriesSchema = object({
18037
18066
  scope: string(),
18038
18067
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
18039
18068
  before: object({
18040
18069
  t: number(),
18041
- value: number().nullable()
18070
+ value: number().nullable(),
18071
+ state: string().nullable()
18042
18072
  }).nullable(),
18043
- points: array(QueryPointSchema).readonly()
18073
+ points: array(QueryPointSchema).readonly(),
18074
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
18075
+ derivedFrom: string().nullable()
18044
18076
  });
18045
18077
  /** The window part of a query, shared by the device and node forms. */
18046
18078
  var QueryWindowShape = {
@@ -18056,6 +18088,23 @@ var QueryResultSchema = object({
18056
18088
  series: array(QuerySeriesSchema).readonly(),
18057
18089
  truncated: boolean()
18058
18090
  });
18091
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
18092
+ var QueryManyItemSchema = union([object({
18093
+ deviceId: number().int(),
18094
+ key: string(),
18095
+ scope: string().optional()
18096
+ }), object({
18097
+ forNodeId: string().min(1),
18098
+ key: string(),
18099
+ scope: string().optional()
18100
+ })]);
18101
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
18102
+ ok: literal(true),
18103
+ result: QueryResultSchema
18104
+ }), object({
18105
+ ok: literal(false),
18106
+ error: string()
18107
+ })]);
18059
18108
  var TierStatusSchema = object({
18060
18109
  tier: DeviceHistoryResolutionSchema,
18061
18110
  /** `null` until the first background count answered. */
@@ -18111,16 +18160,22 @@ var DeviceHistoryStatusSchema = object({
18111
18160
  lastRefreshAt: number().nullable()
18112
18161
  })
18113
18162
  });
18114
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
18163
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
18115
18164
  deviceId: number().int(),
18116
18165
  ...QueryWindowShape
18117
18166
  }), QueryResultSchema), method(object({
18118
- nodeId: string().min(1),
18167
+ forNodeId: string().min(1),
18119
18168
  ...QueryWindowShape
18120
18169
  }), QueryResultSchema, { auth: "admin" }), method(object({
18170
+ items: array(QueryManyItemSchema).min(1).max(24),
18171
+ from: QueryWindowShape.from,
18172
+ to: QueryWindowShape.to,
18173
+ resolution: QueryWindowShape.resolution,
18174
+ maxPoints: QueryWindowShape.maxPoints
18175
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
18121
18176
  name: string().regex(/^[a-z0-9-]+$/),
18122
18177
  subjectKind: _enum(["device", "node"]),
18123
- kind: DeviceHistoryKindSchema,
18178
+ kind: DeviceHistoryProducerKindSchema,
18124
18179
  unit: string().optional(),
18125
18180
  displayName: string().min(1),
18126
18181
  ingest: _enum(["points", "buckets"])
@@ -41442,14 +41497,106 @@ var LogEntrySchema = object({
41442
41497
  meta: record(string(), unknown()).optional(),
41443
41498
  tags: record(string(), string()).optional()
41444
41499
  });
41445
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
41446
- scope: array(string()).optional(),
41500
+ /**
41501
+ * A history READ against one destination (D898).
41502
+ *
41503
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
41504
+ * browser applied after the limit is what made a rare device's lines
41505
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
41506
+ * minted (opaque to everyone else): a file position for the rotated files, a
41507
+ * nanosecond timestamp for Loki.
41508
+ *
41509
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
41510
+ * store answers `done: false` with the cursor it reached and the bytes it
41511
+ * scanned, and the caller decides whether to go on. That is what makes a long
41512
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
41513
+ * flight, and not asking for the next slice ends the scan.
41514
+ */
41515
+ var LogReadQuerySchema = object({
41516
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
41517
+ requestId: string().min(1).max(64).optional(),
41518
+ /** The device the line is about (`tags.deviceId`, numeric). */
41519
+ deviceId: number().int().optional(),
41520
+ /**
41521
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
41522
+ * match. Not `addonId`: a cap router reads that name as "which provider".
41523
+ */
41524
+ fromAddonId: string().min(1).max(200).optional(),
41525
+ /**
41526
+ * The emitting node: matches the agent that emitted the line, the node
41527
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
41528
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
41529
+ * name as "which node's provider".
41530
+ */
41531
+ fromNodeId: string().min(1).max(200).optional(),
41532
+ /** Any other tag, exact match (AND). */
41533
+ tags: record(string(), union([string(), number()])).optional(),
41534
+ /** Severity FLOOR: this level and above. */
41447
41535
  level: LogLevelSchema.optional(),
41448
- since: date().optional(),
41449
- until: date().optional(),
41450
- limit: number().optional(),
41451
- tags: record(string(), string()).optional()
41452
- }), array(LogEntrySchema).readonly());
41536
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
41537
+ text: string().min(1).max(200).optional(),
41538
+ /** Epoch ms, inclusive. */
41539
+ since: number().optional(),
41540
+ /** Epoch ms, inclusive. */
41541
+ until: number().optional(),
41542
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
41543
+ before: string().min(1).max(1024).optional(),
41544
+ /** Newer than this cursor (exclusive). */
41545
+ after: string().min(1).max(1024).optional(),
41546
+ limit: number().int().min(1).max(1e3).optional(),
41547
+ /** Wall-clock bound of this slice. The provider caps it. */
41548
+ budgetMs: number().int().min(50).max(1e4).optional()
41549
+ });
41550
+ var LogReadResultSchema = object({
41551
+ /** Newest first. */
41552
+ entries: array(object({
41553
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
41554
+ id: string().optional(),
41555
+ /** Epoch ms. */
41556
+ timestamp: number(),
41557
+ level: LogLevelSchema,
41558
+ scope: string().optional(),
41559
+ message: string(),
41560
+ tags: record(string(), union([string(), number()])).optional(),
41561
+ meta: record(string(), unknown()).optional()
41562
+ })),
41563
+ /** Pass as `before` for the next older page; null when nothing older exists. */
41564
+ nextBefore: string().nullable(),
41565
+ /** Pass as `after` to read what arrived since; null when unknown. */
41566
+ nextAfter: string().nullable(),
41567
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
41568
+ scannedBytes: number().int().nonnegative(),
41569
+ /**
41570
+ * True when the scan in this direction reached the end of the store.
41571
+ * False with fewer than `limit` entries means the budget ran out first —
41572
+ * call again with `nextBefore` to go on.
41573
+ */
41574
+ done: boolean(),
41575
+ /** True when `cancelRead` ended this slice early. */
41576
+ cancelled: boolean().optional()
41577
+ });
41578
+ var LogReadCapabilitiesSchema = object({
41579
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
41580
+ readable: boolean(),
41581
+ /** Why not, when `readable` is false — rendered next to the source. */
41582
+ reason: string().nullable(),
41583
+ /** Filters the provider applies itself. A false one is applied by nobody. */
41584
+ filters: object({
41585
+ deviceId: boolean(),
41586
+ addonId: boolean(),
41587
+ nodeId: boolean(),
41588
+ tags: boolean(),
41589
+ level: boolean(),
41590
+ text: boolean(),
41591
+ timeRange: boolean()
41592
+ }),
41593
+ /** How far back the store reaches, when the provider knows (days). */
41594
+ retentionDays: number().nullable()
41595
+ });
41596
+ 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() }), {
41597
+ kind: "mutation",
41598
+ auth: "admin"
41599
+ });
41453
41600
  /**
41454
41601
  * `login-method` — collection cap through which auth addons contribute
41455
41602
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -43167,9 +43314,11 @@ var alarmPanelCapability = {
43167
43314
  */
43168
43315
  durability: "restored",
43169
43316
  /**
43170
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
43317
+ * History (D850): the panel's lifecycle state as an `enum` series —
43318
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
43319
+ * few seconds keeps every step. Who armed it stays in the events ledger.
43171
43320
  */
43172
- history: "none",
43321
+ history: { fields: { state: { kind: "enum" } } },
43173
43322
  /** Clock fields: written, but excluded from the compare that decides
43174
43323
  * whether persisting is worth a SQLite commit. */
43175
43324
  volatileStateFields: ["lastChangedAt"]
@@ -44047,6 +44196,33 @@ var NcRuleTargetSchema = object({
44047
44196
  params: record(string(), unknown()).optional()
44048
44197
  });
44049
44198
  /**
44199
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
44200
+ *
44201
+ * Every mode starts from the same CLEAN source frame of the trigger moment
44202
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
44203
+ * to the zone that fired the rule) and renders it once at send time:
44204
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
44205
+ * colour and every OTHER track visible at that instant outlined thin, each
44206
+ * labelled with class and confidence ("dog 87%").
44207
+ * - `crop` — the subject cut out of that frame around its box at that instant.
44208
+ * - `clean` — the whole scene with nothing drawn on it.
44209
+ * - `none` — no picture.
44210
+ *
44211
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
44212
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
44213
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
44214
+ * ship a crop on one event and a boxed scene on the next depending on which
44215
+ * stored kind had landed.
44216
+ */
44217
+ var NcMediaImageSchema = _enum([
44218
+ "scene-boxes",
44219
+ "crop",
44220
+ "clean",
44221
+ "none"
44222
+ ]);
44223
+ /**
44224
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
44225
+ *
44050
44226
  * Media attachment policy (P1 still-image subset).
44051
44227
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
44052
44228
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -44060,6 +44236,8 @@ var NcRuleTargetSchema = object({
44060
44236
  * - `none` — no attachment.
44061
44237
  */
44062
44238
  /**
44239
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
44240
+ *
44063
44241
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
44064
44242
  * conflate it with the selection strategy and betray the request: asking for
44065
44243
  * the clean scene frame on an object-event owner used to start at
@@ -44088,16 +44266,29 @@ var NcMediaFrameSchema = _enum([
44088
44266
  */
44089
44267
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
44090
44268
  var NcMediaPolicySchema = object({
44269
+ /**
44270
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
44271
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
44272
+ * triple below, at load and at every write, and the store keeps only this.
44273
+ */
44274
+ image: NcMediaImageSchema.optional(),
44275
+ /**
44276
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
44277
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
44278
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
44279
+ * Replaces `zoneCrop`.
44280
+ */
44281
+ showTriggerZone: boolean().optional(),
44282
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
44091
44283
  attach: _enum([
44092
44284
  "best",
44093
44285
  "best-matching",
44094
44286
  "keyFrame",
44095
44287
  "none"
44096
- ]).default("best"),
44097
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
44288
+ ]).optional(),
44289
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
44098
44290
  frame: NcMediaFrameSchema.optional(),
44099
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
44100
- * "show me the ZONE", not the whole scene or the subject crop. */
44291
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
44101
44292
  zoneCrop: boolean().optional(),
44102
44293
  /**
44103
44294
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -44269,7 +44460,9 @@ var NcRuleInputSchema = object({
44269
44460
  * targets.
44270
44461
  */
44271
44462
  targetUsers: array(string()).optional(),
44272
- media: NcMediaPolicySchema.default({ attach: "best" }),
44463
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
44464
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
44465
+ media: NcMediaPolicySchema.default({}),
44273
44466
  throttle: NcThrottleSchema.default({
44274
44467
  cooldownSec: 60,
44275
44468
  scope: "rule-device"
@@ -45206,13 +45399,37 @@ var NcAlarmModeOpeningsSchema = object({
45206
45399
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
45207
45400
  unknown: array(number().int())
45208
45401
  });
45402
+ /**
45403
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
45404
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
45405
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
45406
+ * never looks fully armed (D62: off must never look like broken).
45407
+ */
45408
+ var NcAlarmInputBypassViewSchema = object({
45409
+ ruleId: string(),
45410
+ /** The rule's current name (its frozen name when the rule is gone). */
45411
+ ruleName: string(),
45412
+ /** The input: the sensor of the match, else its camera. */
45413
+ deviceId: number().int(),
45414
+ /** The input's current name. */
45415
+ name: string(),
45416
+ /** When it was bypassed (ms epoch). */
45417
+ since: number(),
45418
+ /** Triggers from this input dropped since. */
45419
+ dropped: number().int().min(0)
45420
+ });
45209
45421
  var NcAlarmLiveSchema = object({
45210
45422
  state: AlarmStateSchema,
45211
45423
  /** The mode being armed into (exit delay) or held; null when disarmed. */
45212
45424
  targetMode: AlarmArmModeSchema.nullable(),
45213
45425
  availableModes: array(AlarmArmModeSchema),
45214
45426
  openings: array(NcAlarmModeOpeningsSchema),
45215
- exclusions: array(NcAlarmExclusionViewSchema)
45427
+ exclusions: array(NcAlarmExclusionViewSchema),
45428
+ /**
45429
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
45430
+ * Defaulted so an older hub answer still parses (as "none known").
45431
+ */
45432
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
45216
45433
  });
45217
45434
  var NcAlarmConfigSchema = object({
45218
45435
  /**
@@ -55931,9 +56148,11 @@ var connectivityCapability = {
55931
56148
  */
55932
56149
  durability: "restored",
55933
56150
  /**
55934
- * History (D850): none — duplicates device-status.online (one authority for availability).
56151
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
56152
+ * is the upstream entity's own link (a HA connectivity sensor), not the
56153
+ * device's reachability, which stays `device-status.online`.
55935
56154
  */
55936
- history: "none",
56155
+ history: { fields: { connected: { kind: "boolean" } } },
55937
56156
  /** Clock fields: written, but excluded from the compare that decides
55938
56157
  * whether persisting is worth a SQLite commit. */
55939
56158
  volatileStateFields: ["lastChangedAt"]
@@ -56757,11 +56976,22 @@ var dishwasherCapability = {
56757
56976
  },
56758
56977
  runtimeState: DishwasherStatusSchema,
56759
56978
  durability: "session",
56760
- history: { fields: { progressPercent: {
56761
- kind: "gauge",
56762
- unit: "%",
56763
- deadband: 2
56764
- } } }
56979
+ history: { fields: {
56980
+ progressPercent: {
56981
+ kind: "gauge",
56982
+ unit: "%",
56983
+ deadband: 2
56984
+ },
56985
+ state: { kind: "enum" },
56986
+ operationState: { kind: "enum" },
56987
+ remainingSeconds: {
56988
+ kind: "gauge",
56989
+ unit: "s",
56990
+ minIntervalMs: 6e4
56991
+ },
56992
+ doorOpen: { kind: "boolean" },
56993
+ powerOn: { kind: "boolean" }
56994
+ } }
56765
56995
  };
56766
56996
  var DoorbellStatusSchema = object({
56767
56997
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -56878,9 +57108,15 @@ var enumSensorCapability = {
56878
57108
  */
56879
57109
  durability: "restored",
56880
57110
  /**
56881
- * History (D850): none — text/enum state has no history (non-goal).
57111
+ * History (D850): the value as an `enum` series (an appliance's program or
57112
+ * operation state, an HVAC action). The option set is per device, so the
57113
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
57114
+ * `format` carries a timestamp, not a state, and is not recorded.
56882
57115
  */
56883
- history: "none",
57116
+ history: { fields: { value: {
57117
+ kind: "enum",
57118
+ skipWhenSet: "format"
57119
+ } } },
56884
57120
  /** Clock fields: written, but excluded from the compare that decides
56885
57121
  * whether persisting is worth a SQLite commit. */
56886
57122
  volatileStateFields: ["lastFetchedAt"]
@@ -58854,9 +59090,10 @@ var lockControlCapability = {
58854
59090
  */
58855
59091
  durability: "restored",
58856
59092
  /**
58857
- * History (D850): none — enum state; lock events belong in the events ledger.
59093
+ * History (D850): the lock's state as an `enum` series — change-only, no
59094
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
58858
59095
  */
58859
- history: "none",
59096
+ history: { fields: { state: { kind: "enum" } } },
58860
59097
  /** Clock fields: written, but excluded from the compare that decides
58861
59098
  * whether persisting is worth a SQLite commit. */
58862
59099
  volatileStateFields: ["lastChangedAt"]
@@ -59030,9 +59267,18 @@ var mediaPlayerCapability = {
59030
59267
  */
59031
59268
  durability: "session",
59032
59269
  /**
59033
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
59270
+ * History (D850): volume (a level an operator or an automation sets; the
59271
+ * default 10 s floor folds a slider drag into its end value) and mute.
59272
+ * `positionMs` is not recorded: it moves continuously while playing.
59034
59273
  */
59035
- history: "none"
59274
+ history: { fields: {
59275
+ volumeLevel: {
59276
+ kind: "gauge",
59277
+ unit: "%",
59278
+ deadband: 1
59279
+ },
59280
+ isMuted: { kind: "boolean" }
59281
+ } }
59036
59282
  };
59037
59283
  /**
59038
59284
  * mesh-network — collection cap for mesh-VPN providers.
@@ -64325,9 +64571,29 @@ var streamParamsCapability = {
64325
64571
  */
64326
64572
  durability: "restored",
64327
64573
  /**
64328
- * History (D850): none — encoder configuration.
64574
+ * History (D850): the configured bitrate and frame rate of the main and sub
64575
+ * profiles. Configuration, so change-only on the default floor: a point is an
64576
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
64577
+ * quality over time must show.
64329
64578
  */
64330
- history: "none",
64579
+ history: { fields: {
64580
+ "main.bitrate": {
64581
+ kind: "gauge",
64582
+ unit: "kbps"
64583
+ },
64584
+ "main.framerate": {
64585
+ kind: "gauge",
64586
+ unit: "fps"
64587
+ },
64588
+ "sub.bitrate": {
64589
+ kind: "gauge",
64590
+ unit: "kbps"
64591
+ },
64592
+ "sub.framerate": {
64593
+ kind: "gauge",
64594
+ unit: "fps"
64595
+ }
64596
+ } },
64331
64597
  /** Clock fields: written, but excluded from the compare that decides
64332
64598
  * whether persisting is worth a SQLite commit. */
64333
64599
  volatileStateFields: ["lastFetchedAt"]
@@ -67505,6 +67771,15 @@ var BaseDevice = class {
67505
67771
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
67506
67772
  * with a typed cast.
67507
67773
  *
67774
+ * Answer what you KNOW. A plain array is read as the complete list only
67775
+ * while this device is `online` and probed; return
67776
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
67777
+ * now (no credentials, parent not connected, a failed or partial read) —
67778
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
67779
+ * to say "connected, and this is the complete list" explicitly. A shrink is
67780
+ * deleted only after a second agreeing complete read on a later probe (D49;
67781
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
67782
+ *
67508
67783
  * Default: no children.
67509
67784
  */
67510
67785
  getAccessoryChildren() {
@@ -71636,7 +71911,19 @@ Object.freeze({
71636
71911
  addonId: null,
71637
71912
  access: "view"
71638
71913
  },
71639
- "logDestination.query": {
71914
+ "logDestination.cancelRead": {
71915
+ capName: "log-destination",
71916
+ capScope: "system",
71917
+ addonId: null,
71918
+ access: "create"
71919
+ },
71920
+ "logDestination.describeRead": {
71921
+ capName: "log-destination",
71922
+ capScope: "system",
71923
+ addonId: null,
71924
+ access: "view"
71925
+ },
71926
+ "logDestination.read": {
71640
71927
  capName: "log-destination",
71641
71928
  capScope: "system",
71642
71929
  addonId: null,
@@ -77643,6 +77930,11 @@ Object.freeze({
77643
77930
  form: "single",
77644
77931
  optional: false
77645
77932
  }],
77933
+ "logDestination.read": [{
77934
+ name: "deviceId",
77935
+ form: "single",
77936
+ optional: true
77937
+ }],
77646
77938
  "mediaPlayer.getStatus": [{
77647
77939
  name: "deviceId",
77648
77940
  form: "single",
package/dist/addon.mjs CHANGED
@@ -6398,7 +6398,7 @@ var ZodIssueCode = {
6398
6398
  var ZodFirstPartyTypeKind;
6399
6399
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6400
6400
  //#endregion
6401
- //#region ../types/dist/sleep-yKL5gfrH.mjs
6401
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
6402
6402
  /**
6403
6403
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6404
6404
  * window to float samples (D455).
@@ -17978,7 +17978,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17978
17978
  kind: literal("node"),
17979
17979
  nodeId: string().min(1)
17980
17980
  })]);
17981
+ /**
17982
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17983
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17984
+ * meaning); a rollup keeps the time spent in each state (`states`).
17985
+ */
17981
17986
  var DeviceHistoryKindSchema = _enum([
17987
+ "gauge",
17988
+ "counter",
17989
+ "boolean",
17990
+ "enum"
17991
+ ]);
17992
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17993
+ var DeviceHistoryProducerKindSchema = _enum([
17982
17994
  "gauge",
17983
17995
  "counter",
17984
17996
  "boolean"
@@ -18015,7 +18027,13 @@ var SeriesInfoSchema = object({
18015
18027
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
18016
18028
  unit: string().nullable(),
18017
18029
  displayName: string(),
18018
- source: _enum(["cap", "addon"]),
18030
+ source: _enum([
18031
+ "cap",
18032
+ "addon",
18033
+ "derived"
18034
+ ]),
18035
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
18036
+ values: array(string()).readonly().nullable(),
18019
18037
  firstTs: number(),
18020
18038
  lastTs: number()
18021
18039
  });
@@ -18029,17 +18047,31 @@ var QueryPointSchema = object({
18029
18047
  twMean: number().nullable(),
18030
18048
  min: number(),
18031
18049
  max: number(),
18032
- /** `null` is unknown, never zero (D393). */
18033
- last: number().nullable()
18050
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
18051
+ last: number().nullable(),
18052
+ /**
18053
+ * The increase over the point: a `counter`'s growth since the previous point
18054
+ * or bucket (a drop is a reset, counted from zero), and for
18055
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
18056
+ * every other kind, and when it cannot be known.
18057
+ */
18058
+ delta: number().nullable(),
18059
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
18060
+ state: string().nullable(),
18061
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
18062
+ states: record(string(), number()).nullable()
18034
18063
  });
18035
18064
  var QuerySeriesSchema = object({
18036
18065
  scope: string(),
18037
18066
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
18038
18067
  before: object({
18039
18068
  t: number(),
18040
- value: number().nullable()
18069
+ value: number().nullable(),
18070
+ state: string().nullable()
18041
18071
  }).nullable(),
18042
- points: array(QueryPointSchema).readonly()
18072
+ points: array(QueryPointSchema).readonly(),
18073
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
18074
+ derivedFrom: string().nullable()
18043
18075
  });
18044
18076
  /** The window part of a query, shared by the device and node forms. */
18045
18077
  var QueryWindowShape = {
@@ -18055,6 +18087,23 @@ var QueryResultSchema = object({
18055
18087
  series: array(QuerySeriesSchema).readonly(),
18056
18088
  truncated: boolean()
18057
18089
  });
18090
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
18091
+ var QueryManyItemSchema = union([object({
18092
+ deviceId: number().int(),
18093
+ key: string(),
18094
+ scope: string().optional()
18095
+ }), object({
18096
+ forNodeId: string().min(1),
18097
+ key: string(),
18098
+ scope: string().optional()
18099
+ })]);
18100
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
18101
+ ok: literal(true),
18102
+ result: QueryResultSchema
18103
+ }), object({
18104
+ ok: literal(false),
18105
+ error: string()
18106
+ })]);
18058
18107
  var TierStatusSchema = object({
18059
18108
  tier: DeviceHistoryResolutionSchema,
18060
18109
  /** `null` until the first background count answered. */
@@ -18110,16 +18159,22 @@ var DeviceHistoryStatusSchema = object({
18110
18159
  lastRefreshAt: number().nullable()
18111
18160
  })
18112
18161
  });
18113
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
18162
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
18114
18163
  deviceId: number().int(),
18115
18164
  ...QueryWindowShape
18116
18165
  }), QueryResultSchema), method(object({
18117
- nodeId: string().min(1),
18166
+ forNodeId: string().min(1),
18118
18167
  ...QueryWindowShape
18119
18168
  }), QueryResultSchema, { auth: "admin" }), method(object({
18169
+ items: array(QueryManyItemSchema).min(1).max(24),
18170
+ from: QueryWindowShape.from,
18171
+ to: QueryWindowShape.to,
18172
+ resolution: QueryWindowShape.resolution,
18173
+ maxPoints: QueryWindowShape.maxPoints
18174
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
18120
18175
  name: string().regex(/^[a-z0-9-]+$/),
18121
18176
  subjectKind: _enum(["device", "node"]),
18122
- kind: DeviceHistoryKindSchema,
18177
+ kind: DeviceHistoryProducerKindSchema,
18123
18178
  unit: string().optional(),
18124
18179
  displayName: string().min(1),
18125
18180
  ingest: _enum(["points", "buckets"])
@@ -41441,14 +41496,106 @@ var LogEntrySchema = object({
41441
41496
  meta: record(string(), unknown()).optional(),
41442
41497
  tags: record(string(), string()).optional()
41443
41498
  });
41444
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
41445
- scope: array(string()).optional(),
41499
+ /**
41500
+ * A history READ against one destination (D898).
41501
+ *
41502
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
41503
+ * browser applied after the limit is what made a rare device's lines
41504
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
41505
+ * minted (opaque to everyone else): a file position for the rotated files, a
41506
+ * nanosecond timestamp for Loki.
41507
+ *
41508
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
41509
+ * store answers `done: false` with the cursor it reached and the bytes it
41510
+ * scanned, and the caller decides whether to go on. That is what makes a long
41511
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
41512
+ * flight, and not asking for the next slice ends the scan.
41513
+ */
41514
+ var LogReadQuerySchema = object({
41515
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
41516
+ requestId: string().min(1).max(64).optional(),
41517
+ /** The device the line is about (`tags.deviceId`, numeric). */
41518
+ deviceId: number().int().optional(),
41519
+ /**
41520
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
41521
+ * match. Not `addonId`: a cap router reads that name as "which provider".
41522
+ */
41523
+ fromAddonId: string().min(1).max(200).optional(),
41524
+ /**
41525
+ * The emitting node: matches the agent that emitted the line, the node
41526
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
41527
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
41528
+ * name as "which node's provider".
41529
+ */
41530
+ fromNodeId: string().min(1).max(200).optional(),
41531
+ /** Any other tag, exact match (AND). */
41532
+ tags: record(string(), union([string(), number()])).optional(),
41533
+ /** Severity FLOOR: this level and above. */
41446
41534
  level: LogLevelSchema.optional(),
41447
- since: date().optional(),
41448
- until: date().optional(),
41449
- limit: number().optional(),
41450
- tags: record(string(), string()).optional()
41451
- }), array(LogEntrySchema).readonly());
41535
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
41536
+ text: string().min(1).max(200).optional(),
41537
+ /** Epoch ms, inclusive. */
41538
+ since: number().optional(),
41539
+ /** Epoch ms, inclusive. */
41540
+ until: number().optional(),
41541
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
41542
+ before: string().min(1).max(1024).optional(),
41543
+ /** Newer than this cursor (exclusive). */
41544
+ after: string().min(1).max(1024).optional(),
41545
+ limit: number().int().min(1).max(1e3).optional(),
41546
+ /** Wall-clock bound of this slice. The provider caps it. */
41547
+ budgetMs: number().int().min(50).max(1e4).optional()
41548
+ });
41549
+ var LogReadResultSchema = object({
41550
+ /** Newest first. */
41551
+ entries: array(object({
41552
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
41553
+ id: string().optional(),
41554
+ /** Epoch ms. */
41555
+ timestamp: number(),
41556
+ level: LogLevelSchema,
41557
+ scope: string().optional(),
41558
+ message: string(),
41559
+ tags: record(string(), union([string(), number()])).optional(),
41560
+ meta: record(string(), unknown()).optional()
41561
+ })),
41562
+ /** Pass as `before` for the next older page; null when nothing older exists. */
41563
+ nextBefore: string().nullable(),
41564
+ /** Pass as `after` to read what arrived since; null when unknown. */
41565
+ nextAfter: string().nullable(),
41566
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
41567
+ scannedBytes: number().int().nonnegative(),
41568
+ /**
41569
+ * True when the scan in this direction reached the end of the store.
41570
+ * False with fewer than `limit` entries means the budget ran out first —
41571
+ * call again with `nextBefore` to go on.
41572
+ */
41573
+ done: boolean(),
41574
+ /** True when `cancelRead` ended this slice early. */
41575
+ cancelled: boolean().optional()
41576
+ });
41577
+ var LogReadCapabilitiesSchema = object({
41578
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
41579
+ readable: boolean(),
41580
+ /** Why not, when `readable` is false — rendered next to the source. */
41581
+ reason: string().nullable(),
41582
+ /** Filters the provider applies itself. A false one is applied by nobody. */
41583
+ filters: object({
41584
+ deviceId: boolean(),
41585
+ addonId: boolean(),
41586
+ nodeId: boolean(),
41587
+ tags: boolean(),
41588
+ level: boolean(),
41589
+ text: boolean(),
41590
+ timeRange: boolean()
41591
+ }),
41592
+ /** How far back the store reaches, when the provider knows (days). */
41593
+ retentionDays: number().nullable()
41594
+ });
41595
+ 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() }), {
41596
+ kind: "mutation",
41597
+ auth: "admin"
41598
+ });
41452
41599
  /**
41453
41600
  * `login-method` — collection cap through which auth addons contribute
41454
41601
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -43166,9 +43313,11 @@ var alarmPanelCapability = {
43166
43313
  */
43167
43314
  durability: "restored",
43168
43315
  /**
43169
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
43316
+ * History (D850): the panel's lifecycle state as an `enum` series —
43317
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
43318
+ * few seconds keeps every step. Who armed it stays in the events ledger.
43170
43319
  */
43171
- history: "none",
43320
+ history: { fields: { state: { kind: "enum" } } },
43172
43321
  /** Clock fields: written, but excluded from the compare that decides
43173
43322
  * whether persisting is worth a SQLite commit. */
43174
43323
  volatileStateFields: ["lastChangedAt"]
@@ -44046,6 +44195,33 @@ var NcRuleTargetSchema = object({
44046
44195
  params: record(string(), unknown()).optional()
44047
44196
  });
44048
44197
  /**
44198
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
44199
+ *
44200
+ * Every mode starts from the same CLEAN source frame of the trigger moment
44201
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
44202
+ * to the zone that fired the rule) and renders it once at send time:
44203
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
44204
+ * colour and every OTHER track visible at that instant outlined thin, each
44205
+ * labelled with class and confidence ("dog 87%").
44206
+ * - `crop` — the subject cut out of that frame around its box at that instant.
44207
+ * - `clean` — the whole scene with nothing drawn on it.
44208
+ * - `none` — no picture.
44209
+ *
44210
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
44211
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
44212
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
44213
+ * ship a crop on one event and a boxed scene on the next depending on which
44214
+ * stored kind had landed.
44215
+ */
44216
+ var NcMediaImageSchema = _enum([
44217
+ "scene-boxes",
44218
+ "crop",
44219
+ "clean",
44220
+ "none"
44221
+ ]);
44222
+ /**
44223
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
44224
+ *
44049
44225
  * Media attachment policy (P1 still-image subset).
44050
44226
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
44051
44227
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -44059,6 +44235,8 @@ var NcRuleTargetSchema = object({
44059
44235
  * - `none` — no attachment.
44060
44236
  */
44061
44237
  /**
44238
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
44239
+ *
44062
44240
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
44063
44241
  * conflate it with the selection strategy and betray the request: asking for
44064
44242
  * the clean scene frame on an object-event owner used to start at
@@ -44087,16 +44265,29 @@ var NcMediaFrameSchema = _enum([
44087
44265
  */
44088
44266
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
44089
44267
  var NcMediaPolicySchema = object({
44268
+ /**
44269
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
44270
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
44271
+ * triple below, at load and at every write, and the store keeps only this.
44272
+ */
44273
+ image: NcMediaImageSchema.optional(),
44274
+ /**
44275
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
44276
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
44277
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
44278
+ * Replaces `zoneCrop`.
44279
+ */
44280
+ showTriggerZone: boolean().optional(),
44281
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
44090
44282
  attach: _enum([
44091
44283
  "best",
44092
44284
  "best-matching",
44093
44285
  "keyFrame",
44094
44286
  "none"
44095
- ]).default("best"),
44096
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
44287
+ ]).optional(),
44288
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
44097
44289
  frame: NcMediaFrameSchema.optional(),
44098
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
44099
- * "show me the ZONE", not the whole scene or the subject crop. */
44290
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
44100
44291
  zoneCrop: boolean().optional(),
44101
44292
  /**
44102
44293
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -44268,7 +44459,9 @@ var NcRuleInputSchema = object({
44268
44459
  * targets.
44269
44460
  */
44270
44461
  targetUsers: array(string()).optional(),
44271
- media: NcMediaPolicySchema.default({ attach: "best" }),
44462
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
44463
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
44464
+ media: NcMediaPolicySchema.default({}),
44272
44465
  throttle: NcThrottleSchema.default({
44273
44466
  cooldownSec: 60,
44274
44467
  scope: "rule-device"
@@ -45205,13 +45398,37 @@ var NcAlarmModeOpeningsSchema = object({
45205
45398
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
45206
45399
  unknown: array(number().int())
45207
45400
  });
45401
+ /**
45402
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
45403
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
45404
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
45405
+ * never looks fully armed (D62: off must never look like broken).
45406
+ */
45407
+ var NcAlarmInputBypassViewSchema = object({
45408
+ ruleId: string(),
45409
+ /** The rule's current name (its frozen name when the rule is gone). */
45410
+ ruleName: string(),
45411
+ /** The input: the sensor of the match, else its camera. */
45412
+ deviceId: number().int(),
45413
+ /** The input's current name. */
45414
+ name: string(),
45415
+ /** When it was bypassed (ms epoch). */
45416
+ since: number(),
45417
+ /** Triggers from this input dropped since. */
45418
+ dropped: number().int().min(0)
45419
+ });
45208
45420
  var NcAlarmLiveSchema = object({
45209
45421
  state: AlarmStateSchema,
45210
45422
  /** The mode being armed into (exit delay) or held; null when disarmed. */
45211
45423
  targetMode: AlarmArmModeSchema.nullable(),
45212
45424
  availableModes: array(AlarmArmModeSchema),
45213
45425
  openings: array(NcAlarmModeOpeningsSchema),
45214
- exclusions: array(NcAlarmExclusionViewSchema)
45426
+ exclusions: array(NcAlarmExclusionViewSchema),
45427
+ /**
45428
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
45429
+ * Defaulted so an older hub answer still parses (as "none known").
45430
+ */
45431
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
45215
45432
  });
45216
45433
  var NcAlarmConfigSchema = object({
45217
45434
  /**
@@ -55930,9 +56147,11 @@ var connectivityCapability = {
55930
56147
  */
55931
56148
  durability: "restored",
55932
56149
  /**
55933
- * History (D850): none — duplicates device-status.online (one authority for availability).
56150
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
56151
+ * is the upstream entity's own link (a HA connectivity sensor), not the
56152
+ * device's reachability, which stays `device-status.online`.
55934
56153
  */
55935
- history: "none",
56154
+ history: { fields: { connected: { kind: "boolean" } } },
55936
56155
  /** Clock fields: written, but excluded from the compare that decides
55937
56156
  * whether persisting is worth a SQLite commit. */
55938
56157
  volatileStateFields: ["lastChangedAt"]
@@ -56756,11 +56975,22 @@ var dishwasherCapability = {
56756
56975
  },
56757
56976
  runtimeState: DishwasherStatusSchema,
56758
56977
  durability: "session",
56759
- history: { fields: { progressPercent: {
56760
- kind: "gauge",
56761
- unit: "%",
56762
- deadband: 2
56763
- } } }
56978
+ history: { fields: {
56979
+ progressPercent: {
56980
+ kind: "gauge",
56981
+ unit: "%",
56982
+ deadband: 2
56983
+ },
56984
+ state: { kind: "enum" },
56985
+ operationState: { kind: "enum" },
56986
+ remainingSeconds: {
56987
+ kind: "gauge",
56988
+ unit: "s",
56989
+ minIntervalMs: 6e4
56990
+ },
56991
+ doorOpen: { kind: "boolean" },
56992
+ powerOn: { kind: "boolean" }
56993
+ } }
56764
56994
  };
56765
56995
  var DoorbellStatusSchema = object({
56766
56996
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -56877,9 +57107,15 @@ var enumSensorCapability = {
56877
57107
  */
56878
57108
  durability: "restored",
56879
57109
  /**
56880
- * History (D850): none — text/enum state has no history (non-goal).
57110
+ * History (D850): the value as an `enum` series (an appliance's program or
57111
+ * operation state, an HVAC action). The option set is per device, so the
57112
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
57113
+ * `format` carries a timestamp, not a state, and is not recorded.
56881
57114
  */
56882
- history: "none",
57115
+ history: { fields: { value: {
57116
+ kind: "enum",
57117
+ skipWhenSet: "format"
57118
+ } } },
56883
57119
  /** Clock fields: written, but excluded from the compare that decides
56884
57120
  * whether persisting is worth a SQLite commit. */
56885
57121
  volatileStateFields: ["lastFetchedAt"]
@@ -58853,9 +59089,10 @@ var lockControlCapability = {
58853
59089
  */
58854
59090
  durability: "restored",
58855
59091
  /**
58856
- * History (D850): none — enum state; lock events belong in the events ledger.
59092
+ * History (D850): the lock's state as an `enum` series — change-only, no
59093
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
58857
59094
  */
58858
- history: "none",
59095
+ history: { fields: { state: { kind: "enum" } } },
58859
59096
  /** Clock fields: written, but excluded from the compare that decides
58860
59097
  * whether persisting is worth a SQLite commit. */
58861
59098
  volatileStateFields: ["lastChangedAt"]
@@ -59029,9 +59266,18 @@ var mediaPlayerCapability = {
59029
59266
  */
59030
59267
  durability: "session",
59031
59268
  /**
59032
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
59269
+ * History (D850): volume (a level an operator or an automation sets; the
59270
+ * default 10 s floor folds a slider drag into its end value) and mute.
59271
+ * `positionMs` is not recorded: it moves continuously while playing.
59033
59272
  */
59034
- history: "none"
59273
+ history: { fields: {
59274
+ volumeLevel: {
59275
+ kind: "gauge",
59276
+ unit: "%",
59277
+ deadband: 1
59278
+ },
59279
+ isMuted: { kind: "boolean" }
59280
+ } }
59035
59281
  };
59036
59282
  /**
59037
59283
  * mesh-network — collection cap for mesh-VPN providers.
@@ -64324,9 +64570,29 @@ var streamParamsCapability = {
64324
64570
  */
64325
64571
  durability: "restored",
64326
64572
  /**
64327
- * History (D850): none — encoder configuration.
64573
+ * History (D850): the configured bitrate and frame rate of the main and sub
64574
+ * profiles. Configuration, so change-only on the default floor: a point is an
64575
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
64576
+ * quality over time must show.
64328
64577
  */
64329
- history: "none",
64578
+ history: { fields: {
64579
+ "main.bitrate": {
64580
+ kind: "gauge",
64581
+ unit: "kbps"
64582
+ },
64583
+ "main.framerate": {
64584
+ kind: "gauge",
64585
+ unit: "fps"
64586
+ },
64587
+ "sub.bitrate": {
64588
+ kind: "gauge",
64589
+ unit: "kbps"
64590
+ },
64591
+ "sub.framerate": {
64592
+ kind: "gauge",
64593
+ unit: "fps"
64594
+ }
64595
+ } },
64330
64596
  /** Clock fields: written, but excluded from the compare that decides
64331
64597
  * whether persisting is worth a SQLite commit. */
64332
64598
  volatileStateFields: ["lastFetchedAt"]
@@ -67504,6 +67770,15 @@ var BaseDevice = class {
67504
67770
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
67505
67771
  * with a typed cast.
67506
67772
  *
67773
+ * Answer what you KNOW. A plain array is read as the complete list only
67774
+ * while this device is `online` and probed; return
67775
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
67776
+ * now (no credentials, parent not connected, a failed or partial read) —
67777
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
67778
+ * to say "connected, and this is the complete list" explicitly. A shrink is
67779
+ * deleted only after a second agreeing complete read on a later probe (D49;
67780
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
67781
+ *
67507
67782
  * Default: no children.
67508
67783
  */
67509
67784
  getAccessoryChildren() {
@@ -71635,7 +71910,19 @@ Object.freeze({
71635
71910
  addonId: null,
71636
71911
  access: "view"
71637
71912
  },
71638
- "logDestination.query": {
71913
+ "logDestination.cancelRead": {
71914
+ capName: "log-destination",
71915
+ capScope: "system",
71916
+ addonId: null,
71917
+ access: "create"
71918
+ },
71919
+ "logDestination.describeRead": {
71920
+ capName: "log-destination",
71921
+ capScope: "system",
71922
+ addonId: null,
71923
+ access: "view"
71924
+ },
71925
+ "logDestination.read": {
71639
71926
  capName: "log-destination",
71640
71927
  capScope: "system",
71641
71928
  addonId: null,
@@ -77642,6 +77929,11 @@ Object.freeze({
77642
77929
  form: "single",
77643
77930
  optional: false
77644
77931
  }],
77932
+ "logDestination.read": [{
77933
+ name: "deviceId",
77934
+ form: "single",
77935
+ optional: true
77936
+ }],
77645
77937
  "mediaPlayer.getStatus": [{
77646
77938
  name: "deviceId",
77647
77939
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rademacher",
3
- "version": "0.2.131",
3
+ "version": "0.2.132",
4
4
  "description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
5
5
  "keywords": [
6
6
  "camstack",