@camstack/addon-provider-dreo 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
@@ -5450,7 +5450,7 @@ var ZodIssueCode = {
5450
5450
  var ZodFirstPartyTypeKind;
5451
5451
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5452
5452
  //#endregion
5453
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5453
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5454
5454
  /**
5455
5455
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5456
5456
  * window to float samples (D455).
@@ -17030,7 +17030,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17030
17030
  kind: literal("node"),
17031
17031
  nodeId: string().min(1)
17032
17032
  })]);
17033
+ /**
17034
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17035
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17036
+ * meaning); a rollup keeps the time spent in each state (`states`).
17037
+ */
17033
17038
  var DeviceHistoryKindSchema = _enum([
17039
+ "gauge",
17040
+ "counter",
17041
+ "boolean",
17042
+ "enum"
17043
+ ]);
17044
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17045
+ var DeviceHistoryProducerKindSchema = _enum([
17034
17046
  "gauge",
17035
17047
  "counter",
17036
17048
  "boolean"
@@ -17067,7 +17079,13 @@ var SeriesInfoSchema = object({
17067
17079
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17068
17080
  unit: string().nullable(),
17069
17081
  displayName: string(),
17070
- source: _enum(["cap", "addon"]),
17082
+ source: _enum([
17083
+ "cap",
17084
+ "addon",
17085
+ "derived"
17086
+ ]),
17087
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17088
+ values: array(string()).readonly().nullable(),
17071
17089
  firstTs: number(),
17072
17090
  lastTs: number()
17073
17091
  });
@@ -17081,17 +17099,31 @@ var QueryPointSchema = object({
17081
17099
  twMean: number().nullable(),
17082
17100
  min: number(),
17083
17101
  max: number(),
17084
- /** `null` is unknown, never zero (D393). */
17085
- last: number().nullable()
17102
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17103
+ last: number().nullable(),
17104
+ /**
17105
+ * The increase over the point: a `counter`'s growth since the previous point
17106
+ * or bucket (a drop is a reset, counted from zero), and for
17107
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17108
+ * every other kind, and when it cannot be known.
17109
+ */
17110
+ delta: number().nullable(),
17111
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17112
+ state: string().nullable(),
17113
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17114
+ states: record(string(), number()).nullable()
17086
17115
  });
17087
17116
  var QuerySeriesSchema = object({
17088
17117
  scope: string(),
17089
17118
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17090
17119
  before: object({
17091
17120
  t: number(),
17092
- value: number().nullable()
17121
+ value: number().nullable(),
17122
+ state: string().nullable()
17093
17123
  }).nullable(),
17094
- points: array(QueryPointSchema).readonly()
17124
+ points: array(QueryPointSchema).readonly(),
17125
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17126
+ derivedFrom: string().nullable()
17095
17127
  });
17096
17128
  /** The window part of a query, shared by the device and node forms. */
17097
17129
  var QueryWindowShape = {
@@ -17107,6 +17139,23 @@ var QueryResultSchema = object({
17107
17139
  series: array(QuerySeriesSchema).readonly(),
17108
17140
  truncated: boolean()
17109
17141
  });
17142
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17143
+ var QueryManyItemSchema = union([object({
17144
+ deviceId: number().int(),
17145
+ key: string(),
17146
+ scope: string().optional()
17147
+ }), object({
17148
+ forNodeId: string().min(1),
17149
+ key: string(),
17150
+ scope: string().optional()
17151
+ })]);
17152
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17153
+ ok: literal(true),
17154
+ result: QueryResultSchema
17155
+ }), object({
17156
+ ok: literal(false),
17157
+ error: string()
17158
+ })]);
17110
17159
  var TierStatusSchema = object({
17111
17160
  tier: DeviceHistoryResolutionSchema,
17112
17161
  /** `null` until the first background count answered. */
@@ -17162,16 +17211,22 @@ var DeviceHistoryStatusSchema = object({
17162
17211
  lastRefreshAt: number().nullable()
17163
17212
  })
17164
17213
  });
17165
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17214
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17166
17215
  deviceId: number().int(),
17167
17216
  ...QueryWindowShape
17168
17217
  }), QueryResultSchema), method(object({
17169
- nodeId: string().min(1),
17218
+ forNodeId: string().min(1),
17170
17219
  ...QueryWindowShape
17171
17220
  }), QueryResultSchema, { auth: "admin" }), method(object({
17221
+ items: array(QueryManyItemSchema).min(1).max(24),
17222
+ from: QueryWindowShape.from,
17223
+ to: QueryWindowShape.to,
17224
+ resolution: QueryWindowShape.resolution,
17225
+ maxPoints: QueryWindowShape.maxPoints
17226
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17172
17227
  name: string().regex(/^[a-z0-9-]+$/),
17173
17228
  subjectKind: _enum(["device", "node"]),
17174
- kind: DeviceHistoryKindSchema,
17229
+ kind: DeviceHistoryProducerKindSchema,
17175
17230
  unit: string().optional(),
17176
17231
  displayName: string().min(1),
17177
17232
  ingest: _enum(["points", "buckets"])
@@ -40397,14 +40452,106 @@ var LogEntrySchema = object({
40397
40452
  meta: record(string(), unknown()).optional(),
40398
40453
  tags: record(string(), string()).optional()
40399
40454
  });
40400
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40401
- scope: array(string()).optional(),
40455
+ /**
40456
+ * A history READ against one destination (D898).
40457
+ *
40458
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40459
+ * browser applied after the limit is what made a rare device's lines
40460
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40461
+ * minted (opaque to everyone else): a file position for the rotated files, a
40462
+ * nanosecond timestamp for Loki.
40463
+ *
40464
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40465
+ * store answers `done: false` with the cursor it reached and the bytes it
40466
+ * scanned, and the caller decides whether to go on. That is what makes a long
40467
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40468
+ * flight, and not asking for the next slice ends the scan.
40469
+ */
40470
+ var LogReadQuerySchema = object({
40471
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40472
+ requestId: string().min(1).max(64).optional(),
40473
+ /** The device the line is about (`tags.deviceId`, numeric). */
40474
+ deviceId: number().int().optional(),
40475
+ /**
40476
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40477
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40478
+ */
40479
+ fromAddonId: string().min(1).max(200).optional(),
40480
+ /**
40481
+ * The emitting node: matches the agent that emitted the line, the node
40482
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40483
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40484
+ * name as "which node's provider".
40485
+ */
40486
+ fromNodeId: string().min(1).max(200).optional(),
40487
+ /** Any other tag, exact match (AND). */
40488
+ tags: record(string(), union([string(), number()])).optional(),
40489
+ /** Severity FLOOR: this level and above. */
40402
40490
  level: LogLevelSchema.optional(),
40403
- since: date().optional(),
40404
- until: date().optional(),
40405
- limit: number().optional(),
40406
- tags: record(string(), string()).optional()
40407
- }), array(LogEntrySchema).readonly());
40491
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40492
+ text: string().min(1).max(200).optional(),
40493
+ /** Epoch ms, inclusive. */
40494
+ since: number().optional(),
40495
+ /** Epoch ms, inclusive. */
40496
+ until: number().optional(),
40497
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40498
+ before: string().min(1).max(1024).optional(),
40499
+ /** Newer than this cursor (exclusive). */
40500
+ after: string().min(1).max(1024).optional(),
40501
+ limit: number().int().min(1).max(1e3).optional(),
40502
+ /** Wall-clock bound of this slice. The provider caps it. */
40503
+ budgetMs: number().int().min(50).max(1e4).optional()
40504
+ });
40505
+ var LogReadResultSchema = object({
40506
+ /** Newest first. */
40507
+ entries: array(object({
40508
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40509
+ id: string().optional(),
40510
+ /** Epoch ms. */
40511
+ timestamp: number(),
40512
+ level: LogLevelSchema,
40513
+ scope: string().optional(),
40514
+ message: string(),
40515
+ tags: record(string(), union([string(), number()])).optional(),
40516
+ meta: record(string(), unknown()).optional()
40517
+ })),
40518
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40519
+ nextBefore: string().nullable(),
40520
+ /** Pass as `after` to read what arrived since; null when unknown. */
40521
+ nextAfter: string().nullable(),
40522
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40523
+ scannedBytes: number().int().nonnegative(),
40524
+ /**
40525
+ * True when the scan in this direction reached the end of the store.
40526
+ * False with fewer than `limit` entries means the budget ran out first —
40527
+ * call again with `nextBefore` to go on.
40528
+ */
40529
+ done: boolean(),
40530
+ /** True when `cancelRead` ended this slice early. */
40531
+ cancelled: boolean().optional()
40532
+ });
40533
+ var LogReadCapabilitiesSchema = object({
40534
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40535
+ readable: boolean(),
40536
+ /** Why not, when `readable` is false — rendered next to the source. */
40537
+ reason: string().nullable(),
40538
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40539
+ filters: object({
40540
+ deviceId: boolean(),
40541
+ addonId: boolean(),
40542
+ nodeId: boolean(),
40543
+ tags: boolean(),
40544
+ level: boolean(),
40545
+ text: boolean(),
40546
+ timeRange: boolean()
40547
+ }),
40548
+ /** How far back the store reaches, when the provider knows (days). */
40549
+ retentionDays: number().nullable()
40550
+ });
40551
+ 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() }), {
40552
+ kind: "mutation",
40553
+ auth: "admin"
40554
+ });
40408
40555
  /**
40409
40556
  * `login-method` — collection cap through which auth addons contribute
40410
40557
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42122,9 +42269,11 @@ var alarmPanelCapability = {
42122
42269
  */
42123
42270
  durability: "restored",
42124
42271
  /**
42125
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
42272
+ * History (D850): the panel's lifecycle state as an `enum` series —
42273
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
42274
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42126
42275
  */
42127
- history: "none",
42276
+ history: { fields: { state: { kind: "enum" } } },
42128
42277
  /** Clock fields: written, but excluded from the compare that decides
42129
42278
  * whether persisting is worth a SQLite commit. */
42130
42279
  volatileStateFields: ["lastChangedAt"]
@@ -43002,6 +43151,33 @@ var NcRuleTargetSchema = object({
43002
43151
  params: record(string(), unknown()).optional()
43003
43152
  });
43004
43153
  /**
43154
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43155
+ *
43156
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43157
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43158
+ * to the zone that fired the rule) and renders it once at send time:
43159
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43160
+ * colour and every OTHER track visible at that instant outlined thin, each
43161
+ * labelled with class and confidence ("dog 87%").
43162
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43163
+ * - `clean` — the whole scene with nothing drawn on it.
43164
+ * - `none` — no picture.
43165
+ *
43166
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43167
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43168
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43169
+ * ship a crop on one event and a boxed scene on the next depending on which
43170
+ * stored kind had landed.
43171
+ */
43172
+ var NcMediaImageSchema = _enum([
43173
+ "scene-boxes",
43174
+ "crop",
43175
+ "clean",
43176
+ "none"
43177
+ ]);
43178
+ /**
43179
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43180
+ *
43005
43181
  * Media attachment policy (P1 still-image subset).
43006
43182
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43007
43183
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43015,6 +43191,8 @@ var NcRuleTargetSchema = object({
43015
43191
  * - `none` — no attachment.
43016
43192
  */
43017
43193
  /**
43194
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43195
+ *
43018
43196
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43019
43197
  * conflate it with the selection strategy and betray the request: asking for
43020
43198
  * the clean scene frame on an object-event owner used to start at
@@ -43043,16 +43221,29 @@ var NcMediaFrameSchema = _enum([
43043
43221
  */
43044
43222
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43045
43223
  var NcMediaPolicySchema = object({
43224
+ /**
43225
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43226
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43227
+ * triple below, at load and at every write, and the store keeps only this.
43228
+ */
43229
+ image: NcMediaImageSchema.optional(),
43230
+ /**
43231
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43232
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43233
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43234
+ * Replaces `zoneCrop`.
43235
+ */
43236
+ showTriggerZone: boolean().optional(),
43237
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43046
43238
  attach: _enum([
43047
43239
  "best",
43048
43240
  "best-matching",
43049
43241
  "keyFrame",
43050
43242
  "none"
43051
- ]).default("best"),
43052
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43243
+ ]).optional(),
43244
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43053
43245
  frame: NcMediaFrameSchema.optional(),
43054
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43055
- * "show me the ZONE", not the whole scene or the subject crop. */
43246
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43056
43247
  zoneCrop: boolean().optional(),
43057
43248
  /**
43058
43249
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43224,7 +43415,9 @@ var NcRuleInputSchema = object({
43224
43415
  * targets.
43225
43416
  */
43226
43417
  targetUsers: array(string()).optional(),
43227
- media: NcMediaPolicySchema.default({ attach: "best" }),
43418
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43419
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43420
+ media: NcMediaPolicySchema.default({}),
43228
43421
  throttle: NcThrottleSchema.default({
43229
43422
  cooldownSec: 60,
43230
43423
  scope: "rule-device"
@@ -44161,13 +44354,37 @@ var NcAlarmModeOpeningsSchema = object({
44161
44354
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44162
44355
  unknown: array(number().int())
44163
44356
  });
44357
+ /**
44358
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44359
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44360
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44361
+ * never looks fully armed (D62: off must never look like broken).
44362
+ */
44363
+ var NcAlarmInputBypassViewSchema = object({
44364
+ ruleId: string(),
44365
+ /** The rule's current name (its frozen name when the rule is gone). */
44366
+ ruleName: string(),
44367
+ /** The input: the sensor of the match, else its camera. */
44368
+ deviceId: number().int(),
44369
+ /** The input's current name. */
44370
+ name: string(),
44371
+ /** When it was bypassed (ms epoch). */
44372
+ since: number(),
44373
+ /** Triggers from this input dropped since. */
44374
+ dropped: number().int().min(0)
44375
+ });
44164
44376
  var NcAlarmLiveSchema = object({
44165
44377
  state: AlarmStateSchema,
44166
44378
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44167
44379
  targetMode: AlarmArmModeSchema.nullable(),
44168
44380
  availableModes: array(AlarmArmModeSchema),
44169
44381
  openings: array(NcAlarmModeOpeningsSchema),
44170
- exclusions: array(NcAlarmExclusionViewSchema)
44382
+ exclusions: array(NcAlarmExclusionViewSchema),
44383
+ /**
44384
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44385
+ * Defaulted so an older hub answer still parses (as "none known").
44386
+ */
44387
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44171
44388
  });
44172
44389
  var NcAlarmConfigSchema = object({
44173
44390
  /**
@@ -54894,9 +55111,11 @@ var connectivityCapability = {
54894
55111
  */
54895
55112
  durability: "restored",
54896
55113
  /**
54897
- * History (D850): none — duplicates device-status.online (one authority for availability).
55114
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
55115
+ * is the upstream entity's own link (a HA connectivity sensor), not the
55116
+ * device's reachability, which stays `device-status.online`.
54898
55117
  */
54899
- history: "none",
55118
+ history: { fields: { connected: { kind: "boolean" } } },
54900
55119
  /** Clock fields: written, but excluded from the compare that decides
54901
55120
  * whether persisting is worth a SQLite commit. */
54902
55121
  volatileStateFields: ["lastChangedAt"]
@@ -55720,11 +55939,22 @@ var dishwasherCapability = {
55720
55939
  },
55721
55940
  runtimeState: DishwasherStatusSchema,
55722
55941
  durability: "session",
55723
- history: { fields: { progressPercent: {
55724
- kind: "gauge",
55725
- unit: "%",
55726
- deadband: 2
55727
- } } }
55942
+ history: { fields: {
55943
+ progressPercent: {
55944
+ kind: "gauge",
55945
+ unit: "%",
55946
+ deadband: 2
55947
+ },
55948
+ state: { kind: "enum" },
55949
+ operationState: { kind: "enum" },
55950
+ remainingSeconds: {
55951
+ kind: "gauge",
55952
+ unit: "s",
55953
+ minIntervalMs: 6e4
55954
+ },
55955
+ doorOpen: { kind: "boolean" },
55956
+ powerOn: { kind: "boolean" }
55957
+ } }
55728
55958
  };
55729
55959
  var DoorbellStatusSchema = object({
55730
55960
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -55841,9 +56071,15 @@ var enumSensorCapability = {
55841
56071
  */
55842
56072
  durability: "restored",
55843
56073
  /**
55844
- * History (D850): none — text/enum state has no history (non-goal).
56074
+ * History (D850): the value as an `enum` series (an appliance's program or
56075
+ * operation state, an HVAC action). The option set is per device, so the
56076
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
56077
+ * `format` carries a timestamp, not a state, and is not recorded.
55845
56078
  */
55846
- history: "none",
56079
+ history: { fields: { value: {
56080
+ kind: "enum",
56081
+ skipWhenSet: "format"
56082
+ } } },
55847
56083
  /** Clock fields: written, but excluded from the compare that decides
55848
56084
  * whether persisting is worth a SQLite commit. */
55849
56085
  volatileStateFields: ["lastFetchedAt"]
@@ -57817,9 +58053,10 @@ var lockControlCapability = {
57817
58053
  */
57818
58054
  durability: "restored",
57819
58055
  /**
57820
- * History (D850): none — enum state; lock events belong in the events ledger.
58056
+ * History (D850): the lock's state as an `enum` series — change-only, no
58057
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
57821
58058
  */
57822
- history: "none",
58059
+ history: { fields: { state: { kind: "enum" } } },
57823
58060
  /** Clock fields: written, but excluded from the compare that decides
57824
58061
  * whether persisting is worth a SQLite commit. */
57825
58062
  volatileStateFields: ["lastChangedAt"]
@@ -57993,9 +58230,18 @@ var mediaPlayerCapability = {
57993
58230
  */
57994
58231
  durability: "session",
57995
58232
  /**
57996
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
58233
+ * History (D850): volume (a level an operator or an automation sets; the
58234
+ * default 10 s floor folds a slider drag into its end value) and mute.
58235
+ * `positionMs` is not recorded: it moves continuously while playing.
57997
58236
  */
57998
- history: "none"
58237
+ history: { fields: {
58238
+ volumeLevel: {
58239
+ kind: "gauge",
58240
+ unit: "%",
58241
+ deadband: 1
58242
+ },
58243
+ isMuted: { kind: "boolean" }
58244
+ } }
57999
58245
  };
58000
58246
  /**
58001
58247
  * mesh-network — collection cap for mesh-VPN providers.
@@ -63288,9 +63534,29 @@ var streamParamsCapability = {
63288
63534
  */
63289
63535
  durability: "restored",
63290
63536
  /**
63291
- * History (D850): none — encoder configuration.
63537
+ * History (D850): the configured bitrate and frame rate of the main and sub
63538
+ * profiles. Configuration, so change-only on the default floor: a point is an
63539
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
63540
+ * quality over time must show.
63292
63541
  */
63293
- history: "none",
63542
+ history: { fields: {
63543
+ "main.bitrate": {
63544
+ kind: "gauge",
63545
+ unit: "kbps"
63546
+ },
63547
+ "main.framerate": {
63548
+ kind: "gauge",
63549
+ unit: "fps"
63550
+ },
63551
+ "sub.bitrate": {
63552
+ kind: "gauge",
63553
+ unit: "kbps"
63554
+ },
63555
+ "sub.framerate": {
63556
+ kind: "gauge",
63557
+ unit: "fps"
63558
+ }
63559
+ } },
63294
63560
  /** Clock fields: written, but excluded from the compare that decides
63295
63561
  * whether persisting is worth a SQLite commit. */
63296
63562
  volatileStateFields: ["lastFetchedAt"]
@@ -66468,6 +66734,15 @@ var BaseDevice$1 = class {
66468
66734
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
66469
66735
  * with a typed cast.
66470
66736
  *
66737
+ * Answer what you KNOW. A plain array is read as the complete list only
66738
+ * while this device is `online` and probed; return
66739
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
66740
+ * now (no credentials, parent not connected, a failed or partial read) —
66741
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
66742
+ * to say "connected, and this is the complete list" explicitly. A shrink is
66743
+ * deleted only after a second agreeing complete read on a later probe (D49;
66744
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
66745
+ *
66471
66746
  * Default: no children.
66472
66747
  */
66473
66748
  getAccessoryChildren() {
@@ -70599,7 +70874,19 @@ Object.freeze({
70599
70874
  addonId: null,
70600
70875
  access: "view"
70601
70876
  },
70602
- "logDestination.query": {
70877
+ "logDestination.cancelRead": {
70878
+ capName: "log-destination",
70879
+ capScope: "system",
70880
+ addonId: null,
70881
+ access: "create"
70882
+ },
70883
+ "logDestination.describeRead": {
70884
+ capName: "log-destination",
70885
+ capScope: "system",
70886
+ addonId: null,
70887
+ access: "view"
70888
+ },
70889
+ "logDestination.read": {
70603
70890
  capName: "log-destination",
70604
70891
  capScope: "system",
70605
70892
  addonId: null,
@@ -76606,6 +76893,11 @@ Object.freeze({
76606
76893
  form: "single",
76607
76894
  optional: false
76608
76895
  }],
76896
+ "logDestination.read": [{
76897
+ name: "deviceId",
76898
+ form: "single",
76899
+ optional: true
76900
+ }],
76609
76901
  "mediaPlayer.getStatus": [{
76610
76902
  name: "deviceId",
76611
76903
  form: "single",
package/dist/addon.mjs CHANGED
@@ -5451,7 +5451,7 @@ var ZodIssueCode = {
5451
5451
  var ZodFirstPartyTypeKind;
5452
5452
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5453
5453
  //#endregion
5454
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5454
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5455
5455
  /**
5456
5456
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5457
5457
  * window to float samples (D455).
@@ -17031,7 +17031,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17031
17031
  kind: literal("node"),
17032
17032
  nodeId: string().min(1)
17033
17033
  })]);
17034
+ /**
17035
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17036
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17037
+ * meaning); a rollup keeps the time spent in each state (`states`).
17038
+ */
17034
17039
  var DeviceHistoryKindSchema = _enum([
17040
+ "gauge",
17041
+ "counter",
17042
+ "boolean",
17043
+ "enum"
17044
+ ]);
17045
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17046
+ var DeviceHistoryProducerKindSchema = _enum([
17035
17047
  "gauge",
17036
17048
  "counter",
17037
17049
  "boolean"
@@ -17068,7 +17080,13 @@ var SeriesInfoSchema = object({
17068
17080
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17069
17081
  unit: string().nullable(),
17070
17082
  displayName: string(),
17071
- source: _enum(["cap", "addon"]),
17083
+ source: _enum([
17084
+ "cap",
17085
+ "addon",
17086
+ "derived"
17087
+ ]),
17088
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17089
+ values: array(string()).readonly().nullable(),
17072
17090
  firstTs: number(),
17073
17091
  lastTs: number()
17074
17092
  });
@@ -17082,17 +17100,31 @@ var QueryPointSchema = object({
17082
17100
  twMean: number().nullable(),
17083
17101
  min: number(),
17084
17102
  max: number(),
17085
- /** `null` is unknown, never zero (D393). */
17086
- last: number().nullable()
17103
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17104
+ last: number().nullable(),
17105
+ /**
17106
+ * The increase over the point: a `counter`'s growth since the previous point
17107
+ * or bucket (a drop is a reset, counted from zero), and for
17108
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17109
+ * every other kind, and when it cannot be known.
17110
+ */
17111
+ delta: number().nullable(),
17112
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17113
+ state: string().nullable(),
17114
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17115
+ states: record(string(), number()).nullable()
17087
17116
  });
17088
17117
  var QuerySeriesSchema = object({
17089
17118
  scope: string(),
17090
17119
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17091
17120
  before: object({
17092
17121
  t: number(),
17093
- value: number().nullable()
17122
+ value: number().nullable(),
17123
+ state: string().nullable()
17094
17124
  }).nullable(),
17095
- points: array(QueryPointSchema).readonly()
17125
+ points: array(QueryPointSchema).readonly(),
17126
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17127
+ derivedFrom: string().nullable()
17096
17128
  });
17097
17129
  /** The window part of a query, shared by the device and node forms. */
17098
17130
  var QueryWindowShape = {
@@ -17108,6 +17140,23 @@ var QueryResultSchema = object({
17108
17140
  series: array(QuerySeriesSchema).readonly(),
17109
17141
  truncated: boolean()
17110
17142
  });
17143
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17144
+ var QueryManyItemSchema = union([object({
17145
+ deviceId: number().int(),
17146
+ key: string(),
17147
+ scope: string().optional()
17148
+ }), object({
17149
+ forNodeId: string().min(1),
17150
+ key: string(),
17151
+ scope: string().optional()
17152
+ })]);
17153
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17154
+ ok: literal(true),
17155
+ result: QueryResultSchema
17156
+ }), object({
17157
+ ok: literal(false),
17158
+ error: string()
17159
+ })]);
17111
17160
  var TierStatusSchema = object({
17112
17161
  tier: DeviceHistoryResolutionSchema,
17113
17162
  /** `null` until the first background count answered. */
@@ -17163,16 +17212,22 @@ var DeviceHistoryStatusSchema = object({
17163
17212
  lastRefreshAt: number().nullable()
17164
17213
  })
17165
17214
  });
17166
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17215
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17167
17216
  deviceId: number().int(),
17168
17217
  ...QueryWindowShape
17169
17218
  }), QueryResultSchema), method(object({
17170
- nodeId: string().min(1),
17219
+ forNodeId: string().min(1),
17171
17220
  ...QueryWindowShape
17172
17221
  }), QueryResultSchema, { auth: "admin" }), method(object({
17222
+ items: array(QueryManyItemSchema).min(1).max(24),
17223
+ from: QueryWindowShape.from,
17224
+ to: QueryWindowShape.to,
17225
+ resolution: QueryWindowShape.resolution,
17226
+ maxPoints: QueryWindowShape.maxPoints
17227
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17173
17228
  name: string().regex(/^[a-z0-9-]+$/),
17174
17229
  subjectKind: _enum(["device", "node"]),
17175
- kind: DeviceHistoryKindSchema,
17230
+ kind: DeviceHistoryProducerKindSchema,
17176
17231
  unit: string().optional(),
17177
17232
  displayName: string().min(1),
17178
17233
  ingest: _enum(["points", "buckets"])
@@ -40398,14 +40453,106 @@ var LogEntrySchema = object({
40398
40453
  meta: record(string(), unknown()).optional(),
40399
40454
  tags: record(string(), string()).optional()
40400
40455
  });
40401
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40402
- scope: array(string()).optional(),
40456
+ /**
40457
+ * A history READ against one destination (D898).
40458
+ *
40459
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40460
+ * browser applied after the limit is what made a rare device's lines
40461
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40462
+ * minted (opaque to everyone else): a file position for the rotated files, a
40463
+ * nanosecond timestamp for Loki.
40464
+ *
40465
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40466
+ * store answers `done: false` with the cursor it reached and the bytes it
40467
+ * scanned, and the caller decides whether to go on. That is what makes a long
40468
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40469
+ * flight, and not asking for the next slice ends the scan.
40470
+ */
40471
+ var LogReadQuerySchema = object({
40472
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40473
+ requestId: string().min(1).max(64).optional(),
40474
+ /** The device the line is about (`tags.deviceId`, numeric). */
40475
+ deviceId: number().int().optional(),
40476
+ /**
40477
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40478
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40479
+ */
40480
+ fromAddonId: string().min(1).max(200).optional(),
40481
+ /**
40482
+ * The emitting node: matches the agent that emitted the line, the node
40483
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40484
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40485
+ * name as "which node's provider".
40486
+ */
40487
+ fromNodeId: string().min(1).max(200).optional(),
40488
+ /** Any other tag, exact match (AND). */
40489
+ tags: record(string(), union([string(), number()])).optional(),
40490
+ /** Severity FLOOR: this level and above. */
40403
40491
  level: LogLevelSchema.optional(),
40404
- since: date().optional(),
40405
- until: date().optional(),
40406
- limit: number().optional(),
40407
- tags: record(string(), string()).optional()
40408
- }), array(LogEntrySchema).readonly());
40492
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40493
+ text: string().min(1).max(200).optional(),
40494
+ /** Epoch ms, inclusive. */
40495
+ since: number().optional(),
40496
+ /** Epoch ms, inclusive. */
40497
+ until: number().optional(),
40498
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40499
+ before: string().min(1).max(1024).optional(),
40500
+ /** Newer than this cursor (exclusive). */
40501
+ after: string().min(1).max(1024).optional(),
40502
+ limit: number().int().min(1).max(1e3).optional(),
40503
+ /** Wall-clock bound of this slice. The provider caps it. */
40504
+ budgetMs: number().int().min(50).max(1e4).optional()
40505
+ });
40506
+ var LogReadResultSchema = object({
40507
+ /** Newest first. */
40508
+ entries: array(object({
40509
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40510
+ id: string().optional(),
40511
+ /** Epoch ms. */
40512
+ timestamp: number(),
40513
+ level: LogLevelSchema,
40514
+ scope: string().optional(),
40515
+ message: string(),
40516
+ tags: record(string(), union([string(), number()])).optional(),
40517
+ meta: record(string(), unknown()).optional()
40518
+ })),
40519
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40520
+ nextBefore: string().nullable(),
40521
+ /** Pass as `after` to read what arrived since; null when unknown. */
40522
+ nextAfter: string().nullable(),
40523
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40524
+ scannedBytes: number().int().nonnegative(),
40525
+ /**
40526
+ * True when the scan in this direction reached the end of the store.
40527
+ * False with fewer than `limit` entries means the budget ran out first —
40528
+ * call again with `nextBefore` to go on.
40529
+ */
40530
+ done: boolean(),
40531
+ /** True when `cancelRead` ended this slice early. */
40532
+ cancelled: boolean().optional()
40533
+ });
40534
+ var LogReadCapabilitiesSchema = object({
40535
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40536
+ readable: boolean(),
40537
+ /** Why not, when `readable` is false — rendered next to the source. */
40538
+ reason: string().nullable(),
40539
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40540
+ filters: object({
40541
+ deviceId: boolean(),
40542
+ addonId: boolean(),
40543
+ nodeId: boolean(),
40544
+ tags: boolean(),
40545
+ level: boolean(),
40546
+ text: boolean(),
40547
+ timeRange: boolean()
40548
+ }),
40549
+ /** How far back the store reaches, when the provider knows (days). */
40550
+ retentionDays: number().nullable()
40551
+ });
40552
+ 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() }), {
40553
+ kind: "mutation",
40554
+ auth: "admin"
40555
+ });
40409
40556
  /**
40410
40557
  * `login-method` — collection cap through which auth addons contribute
40411
40558
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42123,9 +42270,11 @@ var alarmPanelCapability = {
42123
42270
  */
42124
42271
  durability: "restored",
42125
42272
  /**
42126
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
42273
+ * History (D850): the panel's lifecycle state as an `enum` series —
42274
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
42275
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42127
42276
  */
42128
- history: "none",
42277
+ history: { fields: { state: { kind: "enum" } } },
42129
42278
  /** Clock fields: written, but excluded from the compare that decides
42130
42279
  * whether persisting is worth a SQLite commit. */
42131
42280
  volatileStateFields: ["lastChangedAt"]
@@ -43003,6 +43152,33 @@ var NcRuleTargetSchema = object({
43003
43152
  params: record(string(), unknown()).optional()
43004
43153
  });
43005
43154
  /**
43155
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43156
+ *
43157
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43158
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43159
+ * to the zone that fired the rule) and renders it once at send time:
43160
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43161
+ * colour and every OTHER track visible at that instant outlined thin, each
43162
+ * labelled with class and confidence ("dog 87%").
43163
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43164
+ * - `clean` — the whole scene with nothing drawn on it.
43165
+ * - `none` — no picture.
43166
+ *
43167
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43168
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43169
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43170
+ * ship a crop on one event and a boxed scene on the next depending on which
43171
+ * stored kind had landed.
43172
+ */
43173
+ var NcMediaImageSchema = _enum([
43174
+ "scene-boxes",
43175
+ "crop",
43176
+ "clean",
43177
+ "none"
43178
+ ]);
43179
+ /**
43180
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43181
+ *
43006
43182
  * Media attachment policy (P1 still-image subset).
43007
43183
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43008
43184
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43016,6 +43192,8 @@ var NcRuleTargetSchema = object({
43016
43192
  * - `none` — no attachment.
43017
43193
  */
43018
43194
  /**
43195
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43196
+ *
43019
43197
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43020
43198
  * conflate it with the selection strategy and betray the request: asking for
43021
43199
  * the clean scene frame on an object-event owner used to start at
@@ -43044,16 +43222,29 @@ var NcMediaFrameSchema = _enum([
43044
43222
  */
43045
43223
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43046
43224
  var NcMediaPolicySchema = object({
43225
+ /**
43226
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43227
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43228
+ * triple below, at load and at every write, and the store keeps only this.
43229
+ */
43230
+ image: NcMediaImageSchema.optional(),
43231
+ /**
43232
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43233
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43234
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43235
+ * Replaces `zoneCrop`.
43236
+ */
43237
+ showTriggerZone: boolean().optional(),
43238
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43047
43239
  attach: _enum([
43048
43240
  "best",
43049
43241
  "best-matching",
43050
43242
  "keyFrame",
43051
43243
  "none"
43052
- ]).default("best"),
43053
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43244
+ ]).optional(),
43245
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43054
43246
  frame: NcMediaFrameSchema.optional(),
43055
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43056
- * "show me the ZONE", not the whole scene or the subject crop. */
43247
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43057
43248
  zoneCrop: boolean().optional(),
43058
43249
  /**
43059
43250
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43225,7 +43416,9 @@ var NcRuleInputSchema = object({
43225
43416
  * targets.
43226
43417
  */
43227
43418
  targetUsers: array(string()).optional(),
43228
- media: NcMediaPolicySchema.default({ attach: "best" }),
43419
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43420
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43421
+ media: NcMediaPolicySchema.default({}),
43229
43422
  throttle: NcThrottleSchema.default({
43230
43423
  cooldownSec: 60,
43231
43424
  scope: "rule-device"
@@ -44162,13 +44355,37 @@ var NcAlarmModeOpeningsSchema = object({
44162
44355
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44163
44356
  unknown: array(number().int())
44164
44357
  });
44358
+ /**
44359
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44360
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44361
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44362
+ * never looks fully armed (D62: off must never look like broken).
44363
+ */
44364
+ var NcAlarmInputBypassViewSchema = object({
44365
+ ruleId: string(),
44366
+ /** The rule's current name (its frozen name when the rule is gone). */
44367
+ ruleName: string(),
44368
+ /** The input: the sensor of the match, else its camera. */
44369
+ deviceId: number().int(),
44370
+ /** The input's current name. */
44371
+ name: string(),
44372
+ /** When it was bypassed (ms epoch). */
44373
+ since: number(),
44374
+ /** Triggers from this input dropped since. */
44375
+ dropped: number().int().min(0)
44376
+ });
44165
44377
  var NcAlarmLiveSchema = object({
44166
44378
  state: AlarmStateSchema,
44167
44379
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44168
44380
  targetMode: AlarmArmModeSchema.nullable(),
44169
44381
  availableModes: array(AlarmArmModeSchema),
44170
44382
  openings: array(NcAlarmModeOpeningsSchema),
44171
- exclusions: array(NcAlarmExclusionViewSchema)
44383
+ exclusions: array(NcAlarmExclusionViewSchema),
44384
+ /**
44385
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44386
+ * Defaulted so an older hub answer still parses (as "none known").
44387
+ */
44388
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44172
44389
  });
44173
44390
  var NcAlarmConfigSchema = object({
44174
44391
  /**
@@ -54895,9 +55112,11 @@ var connectivityCapability = {
54895
55112
  */
54896
55113
  durability: "restored",
54897
55114
  /**
54898
- * History (D850): none — duplicates device-status.online (one authority for availability).
55115
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
55116
+ * is the upstream entity's own link (a HA connectivity sensor), not the
55117
+ * device's reachability, which stays `device-status.online`.
54899
55118
  */
54900
- history: "none",
55119
+ history: { fields: { connected: { kind: "boolean" } } },
54901
55120
  /** Clock fields: written, but excluded from the compare that decides
54902
55121
  * whether persisting is worth a SQLite commit. */
54903
55122
  volatileStateFields: ["lastChangedAt"]
@@ -55721,11 +55940,22 @@ var dishwasherCapability = {
55721
55940
  },
55722
55941
  runtimeState: DishwasherStatusSchema,
55723
55942
  durability: "session",
55724
- history: { fields: { progressPercent: {
55725
- kind: "gauge",
55726
- unit: "%",
55727
- deadband: 2
55728
- } } }
55943
+ history: { fields: {
55944
+ progressPercent: {
55945
+ kind: "gauge",
55946
+ unit: "%",
55947
+ deadband: 2
55948
+ },
55949
+ state: { kind: "enum" },
55950
+ operationState: { kind: "enum" },
55951
+ remainingSeconds: {
55952
+ kind: "gauge",
55953
+ unit: "s",
55954
+ minIntervalMs: 6e4
55955
+ },
55956
+ doorOpen: { kind: "boolean" },
55957
+ powerOn: { kind: "boolean" }
55958
+ } }
55729
55959
  };
55730
55960
  var DoorbellStatusSchema = object({
55731
55961
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -55842,9 +56072,15 @@ var enumSensorCapability = {
55842
56072
  */
55843
56073
  durability: "restored",
55844
56074
  /**
55845
- * History (D850): none — text/enum state has no history (non-goal).
56075
+ * History (D850): the value as an `enum` series (an appliance's program or
56076
+ * operation state, an HVAC action). The option set is per device, so the
56077
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
56078
+ * `format` carries a timestamp, not a state, and is not recorded.
55846
56079
  */
55847
- history: "none",
56080
+ history: { fields: { value: {
56081
+ kind: "enum",
56082
+ skipWhenSet: "format"
56083
+ } } },
55848
56084
  /** Clock fields: written, but excluded from the compare that decides
55849
56085
  * whether persisting is worth a SQLite commit. */
55850
56086
  volatileStateFields: ["lastFetchedAt"]
@@ -57818,9 +58054,10 @@ var lockControlCapability = {
57818
58054
  */
57819
58055
  durability: "restored",
57820
58056
  /**
57821
- * History (D850): none — enum state; lock events belong in the events ledger.
58057
+ * History (D850): the lock's state as an `enum` series — change-only, no
58058
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
57822
58059
  */
57823
- history: "none",
58060
+ history: { fields: { state: { kind: "enum" } } },
57824
58061
  /** Clock fields: written, but excluded from the compare that decides
57825
58062
  * whether persisting is worth a SQLite commit. */
57826
58063
  volatileStateFields: ["lastChangedAt"]
@@ -57994,9 +58231,18 @@ var mediaPlayerCapability = {
57994
58231
  */
57995
58232
  durability: "session",
57996
58233
  /**
57997
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
58234
+ * History (D850): volume (a level an operator or an automation sets; the
58235
+ * default 10 s floor folds a slider drag into its end value) and mute.
58236
+ * `positionMs` is not recorded: it moves continuously while playing.
57998
58237
  */
57999
- history: "none"
58238
+ history: { fields: {
58239
+ volumeLevel: {
58240
+ kind: "gauge",
58241
+ unit: "%",
58242
+ deadband: 1
58243
+ },
58244
+ isMuted: { kind: "boolean" }
58245
+ } }
58000
58246
  };
58001
58247
  /**
58002
58248
  * mesh-network — collection cap for mesh-VPN providers.
@@ -63289,9 +63535,29 @@ var streamParamsCapability = {
63289
63535
  */
63290
63536
  durability: "restored",
63291
63537
  /**
63292
- * History (D850): none — encoder configuration.
63538
+ * History (D850): the configured bitrate and frame rate of the main and sub
63539
+ * profiles. Configuration, so change-only on the default floor: a point is an
63540
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
63541
+ * quality over time must show.
63293
63542
  */
63294
- history: "none",
63543
+ history: { fields: {
63544
+ "main.bitrate": {
63545
+ kind: "gauge",
63546
+ unit: "kbps"
63547
+ },
63548
+ "main.framerate": {
63549
+ kind: "gauge",
63550
+ unit: "fps"
63551
+ },
63552
+ "sub.bitrate": {
63553
+ kind: "gauge",
63554
+ unit: "kbps"
63555
+ },
63556
+ "sub.framerate": {
63557
+ kind: "gauge",
63558
+ unit: "fps"
63559
+ }
63560
+ } },
63295
63561
  /** Clock fields: written, but excluded from the compare that decides
63296
63562
  * whether persisting is worth a SQLite commit. */
63297
63563
  volatileStateFields: ["lastFetchedAt"]
@@ -66469,6 +66735,15 @@ var BaseDevice$1 = class {
66469
66735
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
66470
66736
  * with a typed cast.
66471
66737
  *
66738
+ * Answer what you KNOW. A plain array is read as the complete list only
66739
+ * while this device is `online` and probed; return
66740
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
66741
+ * now (no credentials, parent not connected, a failed or partial read) —
66742
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
66743
+ * to say "connected, and this is the complete list" explicitly. A shrink is
66744
+ * deleted only after a second agreeing complete read on a later probe (D49;
66745
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
66746
+ *
66472
66747
  * Default: no children.
66473
66748
  */
66474
66749
  getAccessoryChildren() {
@@ -70600,7 +70875,19 @@ Object.freeze({
70600
70875
  addonId: null,
70601
70876
  access: "view"
70602
70877
  },
70603
- "logDestination.query": {
70878
+ "logDestination.cancelRead": {
70879
+ capName: "log-destination",
70880
+ capScope: "system",
70881
+ addonId: null,
70882
+ access: "create"
70883
+ },
70884
+ "logDestination.describeRead": {
70885
+ capName: "log-destination",
70886
+ capScope: "system",
70887
+ addonId: null,
70888
+ access: "view"
70889
+ },
70890
+ "logDestination.read": {
70604
70891
  capName: "log-destination",
70605
70892
  capScope: "system",
70606
70893
  addonId: null,
@@ -76607,6 +76894,11 @@ Object.freeze({
76607
76894
  form: "single",
76608
76895
  optional: false
76609
76896
  }],
76897
+ "logDestination.read": [{
76898
+ name: "deviceId",
76899
+ form: "single",
76900
+ optional: true
76901
+ }],
76610
76902
  "mediaPlayer.getStatus": [{
76611
76903
  name: "deviceId",
76612
76904
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-dreo",
3
- "version": "0.2.131",
3
+ "version": "0.2.132",
4
4
  "description": "Dreo smart-device (fan / air-circulator / purifier / heater / humidifier) device-provider addon for CamStack — wraps the @apocaliss92/nodedreo Dreo cloud client (REST + WebSocket)",
5
5
  "keywords": [
6
6
  "camstack",