@camstack/addon-provider-hikvision 1.2.157 → 1.2.158

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
@@ -5449,7 +5449,7 @@ var ZodIssueCode = {
5449
5449
  var ZodFirstPartyTypeKind;
5450
5450
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5451
5451
  //#endregion
5452
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5452
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5453
5453
  /**
5454
5454
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5455
5455
  * window to float samples (D455).
@@ -17346,7 +17346,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17346
17346
  kind: literal("node"),
17347
17347
  nodeId: string().min(1)
17348
17348
  })]);
17349
+ /**
17350
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17351
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17352
+ * meaning); a rollup keeps the time spent in each state (`states`).
17353
+ */
17349
17354
  var DeviceHistoryKindSchema = _enum([
17355
+ "gauge",
17356
+ "counter",
17357
+ "boolean",
17358
+ "enum"
17359
+ ]);
17360
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17361
+ var DeviceHistoryProducerKindSchema = _enum([
17350
17362
  "gauge",
17351
17363
  "counter",
17352
17364
  "boolean"
@@ -17383,7 +17395,13 @@ var SeriesInfoSchema = object({
17383
17395
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17384
17396
  unit: string().nullable(),
17385
17397
  displayName: string(),
17386
- source: _enum(["cap", "addon"]),
17398
+ source: _enum([
17399
+ "cap",
17400
+ "addon",
17401
+ "derived"
17402
+ ]),
17403
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17404
+ values: array(string()).readonly().nullable(),
17387
17405
  firstTs: number(),
17388
17406
  lastTs: number()
17389
17407
  });
@@ -17397,17 +17415,31 @@ var QueryPointSchema = object({
17397
17415
  twMean: number().nullable(),
17398
17416
  min: number(),
17399
17417
  max: number(),
17400
- /** `null` is unknown, never zero (D393). */
17401
- last: number().nullable()
17418
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17419
+ last: number().nullable(),
17420
+ /**
17421
+ * The increase over the point: a `counter`'s growth since the previous point
17422
+ * or bucket (a drop is a reset, counted from zero), and for
17423
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17424
+ * every other kind, and when it cannot be known.
17425
+ */
17426
+ delta: number().nullable(),
17427
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17428
+ state: string().nullable(),
17429
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17430
+ states: record(string(), number()).nullable()
17402
17431
  });
17403
17432
  var QuerySeriesSchema = object({
17404
17433
  scope: string(),
17405
17434
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17406
17435
  before: object({
17407
17436
  t: number(),
17408
- value: number().nullable()
17437
+ value: number().nullable(),
17438
+ state: string().nullable()
17409
17439
  }).nullable(),
17410
- points: array(QueryPointSchema).readonly()
17440
+ points: array(QueryPointSchema).readonly(),
17441
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17442
+ derivedFrom: string().nullable()
17411
17443
  });
17412
17444
  /** The window part of a query, shared by the device and node forms. */
17413
17445
  var QueryWindowShape = {
@@ -17423,6 +17455,23 @@ var QueryResultSchema = object({
17423
17455
  series: array(QuerySeriesSchema).readonly(),
17424
17456
  truncated: boolean()
17425
17457
  });
17458
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17459
+ var QueryManyItemSchema = union([object({
17460
+ deviceId: number().int(),
17461
+ key: string(),
17462
+ scope: string().optional()
17463
+ }), object({
17464
+ forNodeId: string().min(1),
17465
+ key: string(),
17466
+ scope: string().optional()
17467
+ })]);
17468
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17469
+ ok: literal(true),
17470
+ result: QueryResultSchema
17471
+ }), object({
17472
+ ok: literal(false),
17473
+ error: string()
17474
+ })]);
17426
17475
  var TierStatusSchema = object({
17427
17476
  tier: DeviceHistoryResolutionSchema,
17428
17477
  /** `null` until the first background count answered. */
@@ -17478,16 +17527,22 @@ var DeviceHistoryStatusSchema = object({
17478
17527
  lastRefreshAt: number().nullable()
17479
17528
  })
17480
17529
  });
17481
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17530
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17482
17531
  deviceId: number().int(),
17483
17532
  ...QueryWindowShape
17484
17533
  }), QueryResultSchema), method(object({
17485
- nodeId: string().min(1),
17534
+ forNodeId: string().min(1),
17486
17535
  ...QueryWindowShape
17487
17536
  }), QueryResultSchema, { auth: "admin" }), method(object({
17537
+ items: array(QueryManyItemSchema).min(1).max(24),
17538
+ from: QueryWindowShape.from,
17539
+ to: QueryWindowShape.to,
17540
+ resolution: QueryWindowShape.resolution,
17541
+ maxPoints: QueryWindowShape.maxPoints
17542
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17488
17543
  name: string().regex(/^[a-z0-9-]+$/),
17489
17544
  subjectKind: _enum(["device", "node"]),
17490
- kind: DeviceHistoryKindSchema,
17545
+ kind: DeviceHistoryProducerKindSchema,
17491
17546
  unit: string().optional(),
17492
17547
  displayName: string().min(1),
17493
17548
  ingest: _enum(["points", "buckets"])
@@ -40828,14 +40883,106 @@ var LogEntrySchema = object({
40828
40883
  meta: record(string(), unknown()).optional(),
40829
40884
  tags: record(string(), string()).optional()
40830
40885
  });
40831
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40832
- scope: array(string()).optional(),
40886
+ /**
40887
+ * A history READ against one destination (D898).
40888
+ *
40889
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40890
+ * browser applied after the limit is what made a rare device's lines
40891
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40892
+ * minted (opaque to everyone else): a file position for the rotated files, a
40893
+ * nanosecond timestamp for Loki.
40894
+ *
40895
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40896
+ * store answers `done: false` with the cursor it reached and the bytes it
40897
+ * scanned, and the caller decides whether to go on. That is what makes a long
40898
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40899
+ * flight, and not asking for the next slice ends the scan.
40900
+ */
40901
+ var LogReadQuerySchema = object({
40902
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40903
+ requestId: string().min(1).max(64).optional(),
40904
+ /** The device the line is about (`tags.deviceId`, numeric). */
40905
+ deviceId: number().int().optional(),
40906
+ /**
40907
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40908
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40909
+ */
40910
+ fromAddonId: string().min(1).max(200).optional(),
40911
+ /**
40912
+ * The emitting node: matches the agent that emitted the line, the node
40913
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40914
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40915
+ * name as "which node's provider".
40916
+ */
40917
+ fromNodeId: string().min(1).max(200).optional(),
40918
+ /** Any other tag, exact match (AND). */
40919
+ tags: record(string(), union([string(), number()])).optional(),
40920
+ /** Severity FLOOR: this level and above. */
40833
40921
  level: LogLevelSchema.optional(),
40834
- since: date().optional(),
40835
- until: date().optional(),
40836
- limit: number().optional(),
40837
- tags: record(string(), string()).optional()
40838
- }), array(LogEntrySchema).readonly());
40922
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40923
+ text: string().min(1).max(200).optional(),
40924
+ /** Epoch ms, inclusive. */
40925
+ since: number().optional(),
40926
+ /** Epoch ms, inclusive. */
40927
+ until: number().optional(),
40928
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40929
+ before: string().min(1).max(1024).optional(),
40930
+ /** Newer than this cursor (exclusive). */
40931
+ after: string().min(1).max(1024).optional(),
40932
+ limit: number().int().min(1).max(1e3).optional(),
40933
+ /** Wall-clock bound of this slice. The provider caps it. */
40934
+ budgetMs: number().int().min(50).max(1e4).optional()
40935
+ });
40936
+ var LogReadResultSchema = object({
40937
+ /** Newest first. */
40938
+ entries: array(object({
40939
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40940
+ id: string().optional(),
40941
+ /** Epoch ms. */
40942
+ timestamp: number(),
40943
+ level: LogLevelSchema,
40944
+ scope: string().optional(),
40945
+ message: string(),
40946
+ tags: record(string(), union([string(), number()])).optional(),
40947
+ meta: record(string(), unknown()).optional()
40948
+ })),
40949
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40950
+ nextBefore: string().nullable(),
40951
+ /** Pass as `after` to read what arrived since; null when unknown. */
40952
+ nextAfter: string().nullable(),
40953
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40954
+ scannedBytes: number().int().nonnegative(),
40955
+ /**
40956
+ * True when the scan in this direction reached the end of the store.
40957
+ * False with fewer than `limit` entries means the budget ran out first —
40958
+ * call again with `nextBefore` to go on.
40959
+ */
40960
+ done: boolean(),
40961
+ /** True when `cancelRead` ended this slice early. */
40962
+ cancelled: boolean().optional()
40963
+ });
40964
+ var LogReadCapabilitiesSchema = object({
40965
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40966
+ readable: boolean(),
40967
+ /** Why not, when `readable` is false — rendered next to the source. */
40968
+ reason: string().nullable(),
40969
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40970
+ filters: object({
40971
+ deviceId: boolean(),
40972
+ addonId: boolean(),
40973
+ nodeId: boolean(),
40974
+ tags: boolean(),
40975
+ level: boolean(),
40976
+ text: boolean(),
40977
+ timeRange: boolean()
40978
+ }),
40979
+ /** How far back the store reaches, when the provider knows (days). */
40980
+ retentionDays: number().nullable()
40981
+ });
40982
+ 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() }), {
40983
+ kind: "mutation",
40984
+ auth: "admin"
40985
+ });
40839
40986
  /**
40840
40987
  * `login-method` — collection cap through which auth addons contribute
40841
40988
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42553,9 +42700,11 @@ var alarmPanelCapability = {
42553
42700
  */
42554
42701
  durability: "restored",
42555
42702
  /**
42556
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
42703
+ * History (D850): the panel's lifecycle state as an `enum` series —
42704
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
42705
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42557
42706
  */
42558
- history: "none",
42707
+ history: { fields: { state: { kind: "enum" } } },
42559
42708
  /** Clock fields: written, but excluded from the compare that decides
42560
42709
  * whether persisting is worth a SQLite commit. */
42561
42710
  volatileStateFields: ["lastChangedAt"]
@@ -43433,6 +43582,33 @@ var NcRuleTargetSchema = object({
43433
43582
  params: record(string(), unknown()).optional()
43434
43583
  });
43435
43584
  /**
43585
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43586
+ *
43587
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43588
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43589
+ * to the zone that fired the rule) and renders it once at send time:
43590
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43591
+ * colour and every OTHER track visible at that instant outlined thin, each
43592
+ * labelled with class and confidence ("dog 87%").
43593
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43594
+ * - `clean` — the whole scene with nothing drawn on it.
43595
+ * - `none` — no picture.
43596
+ *
43597
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43598
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43599
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43600
+ * ship a crop on one event and a boxed scene on the next depending on which
43601
+ * stored kind had landed.
43602
+ */
43603
+ var NcMediaImageSchema = _enum([
43604
+ "scene-boxes",
43605
+ "crop",
43606
+ "clean",
43607
+ "none"
43608
+ ]);
43609
+ /**
43610
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43611
+ *
43436
43612
  * Media attachment policy (P1 still-image subset).
43437
43613
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43438
43614
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43446,6 +43622,8 @@ var NcRuleTargetSchema = object({
43446
43622
  * - `none` — no attachment.
43447
43623
  */
43448
43624
  /**
43625
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43626
+ *
43449
43627
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43450
43628
  * conflate it with the selection strategy and betray the request: asking for
43451
43629
  * the clean scene frame on an object-event owner used to start at
@@ -43474,16 +43652,29 @@ var NcMediaFrameSchema = _enum([
43474
43652
  */
43475
43653
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43476
43654
  var NcMediaPolicySchema = object({
43655
+ /**
43656
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43657
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43658
+ * triple below, at load and at every write, and the store keeps only this.
43659
+ */
43660
+ image: NcMediaImageSchema.optional(),
43661
+ /**
43662
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43663
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43664
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43665
+ * Replaces `zoneCrop`.
43666
+ */
43667
+ showTriggerZone: boolean().optional(),
43668
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43477
43669
  attach: _enum([
43478
43670
  "best",
43479
43671
  "best-matching",
43480
43672
  "keyFrame",
43481
43673
  "none"
43482
- ]).default("best"),
43483
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43674
+ ]).optional(),
43675
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43484
43676
  frame: NcMediaFrameSchema.optional(),
43485
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43486
- * "show me the ZONE", not the whole scene or the subject crop. */
43677
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43487
43678
  zoneCrop: boolean().optional(),
43488
43679
  /**
43489
43680
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43655,7 +43846,9 @@ var NcRuleInputSchema = object({
43655
43846
  * targets.
43656
43847
  */
43657
43848
  targetUsers: array(string()).optional(),
43658
- media: NcMediaPolicySchema.default({ attach: "best" }),
43849
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43850
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43851
+ media: NcMediaPolicySchema.default({}),
43659
43852
  throttle: NcThrottleSchema.default({
43660
43853
  cooldownSec: 60,
43661
43854
  scope: "rule-device"
@@ -44592,13 +44785,37 @@ var NcAlarmModeOpeningsSchema = object({
44592
44785
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44593
44786
  unknown: array(number().int())
44594
44787
  });
44788
+ /**
44789
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44790
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44791
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44792
+ * never looks fully armed (D62: off must never look like broken).
44793
+ */
44794
+ var NcAlarmInputBypassViewSchema = object({
44795
+ ruleId: string(),
44796
+ /** The rule's current name (its frozen name when the rule is gone). */
44797
+ ruleName: string(),
44798
+ /** The input: the sensor of the match, else its camera. */
44799
+ deviceId: number().int(),
44800
+ /** The input's current name. */
44801
+ name: string(),
44802
+ /** When it was bypassed (ms epoch). */
44803
+ since: number(),
44804
+ /** Triggers from this input dropped since. */
44805
+ dropped: number().int().min(0)
44806
+ });
44595
44807
  var NcAlarmLiveSchema = object({
44596
44808
  state: AlarmStateSchema,
44597
44809
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44598
44810
  targetMode: AlarmArmModeSchema.nullable(),
44599
44811
  availableModes: array(AlarmArmModeSchema),
44600
44812
  openings: array(NcAlarmModeOpeningsSchema),
44601
- exclusions: array(NcAlarmExclusionViewSchema)
44813
+ exclusions: array(NcAlarmExclusionViewSchema),
44814
+ /**
44815
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44816
+ * Defaulted so an older hub answer still parses (as "none known").
44817
+ */
44818
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44602
44819
  });
44603
44820
  var NcAlarmConfigSchema = object({
44604
44821
  /**
@@ -55839,9 +56056,11 @@ var connectivityCapability = {
55839
56056
  */
55840
56057
  durability: "restored",
55841
56058
  /**
55842
- * History (D850): none — duplicates device-status.online (one authority for availability).
56059
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
56060
+ * is the upstream entity's own link (a HA connectivity sensor), not the
56061
+ * device's reachability, which stays `device-status.online`.
55843
56062
  */
55844
- history: "none",
56063
+ history: { fields: { connected: { kind: "boolean" } } },
55845
56064
  /** Clock fields: written, but excluded from the compare that decides
55846
56065
  * whether persisting is worth a SQLite commit. */
55847
56066
  volatileStateFields: ["lastChangedAt"]
@@ -56665,11 +56884,22 @@ var dishwasherCapability = {
56665
56884
  },
56666
56885
  runtimeState: DishwasherStatusSchema,
56667
56886
  durability: "session",
56668
- history: { fields: { progressPercent: {
56669
- kind: "gauge",
56670
- unit: "%",
56671
- deadband: 2
56672
- } } }
56887
+ history: { fields: {
56888
+ progressPercent: {
56889
+ kind: "gauge",
56890
+ unit: "%",
56891
+ deadband: 2
56892
+ },
56893
+ state: { kind: "enum" },
56894
+ operationState: { kind: "enum" },
56895
+ remainingSeconds: {
56896
+ kind: "gauge",
56897
+ unit: "s",
56898
+ minIntervalMs: 6e4
56899
+ },
56900
+ doorOpen: { kind: "boolean" },
56901
+ powerOn: { kind: "boolean" }
56902
+ } }
56673
56903
  };
56674
56904
  var DoorbellStatusSchema = object({
56675
56905
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -56786,9 +57016,15 @@ var enumSensorCapability = {
56786
57016
  */
56787
57017
  durability: "restored",
56788
57018
  /**
56789
- * History (D850): none — text/enum state has no history (non-goal).
57019
+ * History (D850): the value as an `enum` series (an appliance's program or
57020
+ * operation state, an HVAC action). The option set is per device, so the
57021
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
57022
+ * `format` carries a timestamp, not a state, and is not recorded.
56790
57023
  */
56791
- history: "none",
57024
+ history: { fields: { value: {
57025
+ kind: "enum",
57026
+ skipWhenSet: "format"
57027
+ } } },
56792
57028
  /** Clock fields: written, but excluded from the compare that decides
56793
57029
  * whether persisting is worth a SQLite commit. */
56794
57030
  volatileStateFields: ["lastFetchedAt"]
@@ -58762,9 +58998,10 @@ var lockControlCapability = {
58762
58998
  */
58763
58999
  durability: "restored",
58764
59000
  /**
58765
- * History (D850): none — enum state; lock events belong in the events ledger.
59001
+ * History (D850): the lock's state as an `enum` series — change-only, no
59002
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
58766
59003
  */
58767
- history: "none",
59004
+ history: { fields: { state: { kind: "enum" } } },
58768
59005
  /** Clock fields: written, but excluded from the compare that decides
58769
59006
  * whether persisting is worth a SQLite commit. */
58770
59007
  volatileStateFields: ["lastChangedAt"]
@@ -58938,9 +59175,18 @@ var mediaPlayerCapability = {
58938
59175
  */
58939
59176
  durability: "session",
58940
59177
  /**
58941
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
59178
+ * History (D850): volume (a level an operator or an automation sets; the
59179
+ * default 10 s floor folds a slider drag into its end value) and mute.
59180
+ * `positionMs` is not recorded: it moves continuously while playing.
58942
59181
  */
58943
- history: "none"
59182
+ history: { fields: {
59183
+ volumeLevel: {
59184
+ kind: "gauge",
59185
+ unit: "%",
59186
+ deadband: 1
59187
+ },
59188
+ isMuted: { kind: "boolean" }
59189
+ } }
58944
59190
  };
58945
59191
  /**
58946
59192
  * mesh-network — collection cap for mesh-VPN providers.
@@ -64596,9 +64842,29 @@ var streamParamsCapability = {
64596
64842
  */
64597
64843
  durability: "restored",
64598
64844
  /**
64599
- * History (D850): none — encoder configuration.
64845
+ * History (D850): the configured bitrate and frame rate of the main and sub
64846
+ * profiles. Configuration, so change-only on the default floor: a point is an
64847
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
64848
+ * quality over time must show.
64600
64849
  */
64601
- history: "none",
64850
+ history: { fields: {
64851
+ "main.bitrate": {
64852
+ kind: "gauge",
64853
+ unit: "kbps"
64854
+ },
64855
+ "main.framerate": {
64856
+ kind: "gauge",
64857
+ unit: "fps"
64858
+ },
64859
+ "sub.bitrate": {
64860
+ kind: "gauge",
64861
+ unit: "kbps"
64862
+ },
64863
+ "sub.framerate": {
64864
+ kind: "gauge",
64865
+ unit: "fps"
64866
+ }
64867
+ } },
64602
64868
  /** Clock fields: written, but excluded from the compare that decides
64603
64869
  * whether persisting is worth a SQLite commit. */
64604
64870
  volatileStateFields: ["lastFetchedAt"]
@@ -67989,6 +68255,15 @@ var BaseDevice = class {
67989
68255
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
67990
68256
  * with a typed cast.
67991
68257
  *
68258
+ * Answer what you KNOW. A plain array is read as the complete list only
68259
+ * while this device is `online` and probed; return
68260
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
68261
+ * now (no credentials, parent not connected, a failed or partial read) —
68262
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
68263
+ * to say "connected, and this is the complete list" explicitly. A shrink is
68264
+ * deleted only after a second agreeing complete read on a later probe (D49;
68265
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
68266
+ *
67992
68267
  * Default: no children.
67993
68268
  */
67994
68269
  getAccessoryChildren() {
@@ -72124,7 +72399,19 @@ Object.freeze({
72124
72399
  addonId: null,
72125
72400
  access: "view"
72126
72401
  },
72127
- "logDestination.query": {
72402
+ "logDestination.cancelRead": {
72403
+ capName: "log-destination",
72404
+ capScope: "system",
72405
+ addonId: null,
72406
+ access: "create"
72407
+ },
72408
+ "logDestination.describeRead": {
72409
+ capName: "log-destination",
72410
+ capScope: "system",
72411
+ addonId: null,
72412
+ access: "view"
72413
+ },
72414
+ "logDestination.read": {
72128
72415
  capName: "log-destination",
72129
72416
  capScope: "system",
72130
72417
  addonId: null,
@@ -78349,6 +78636,11 @@ Object.freeze({
78349
78636
  form: "single",
78350
78637
  optional: false
78351
78638
  }],
78639
+ "logDestination.read": [{
78640
+ name: "deviceId",
78641
+ form: "single",
78642
+ optional: true
78643
+ }],
78352
78644
  "mediaPlayer.getStatus": [{
78353
78645
  name: "deviceId",
78354
78646
  form: "single",
package/dist/addon.mjs CHANGED
@@ -5428,7 +5428,7 @@ var ZodIssueCode = {
5428
5428
  var ZodFirstPartyTypeKind;
5429
5429
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5430
5430
  //#endregion
5431
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5431
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5432
5432
  /**
5433
5433
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5434
5434
  * window to float samples (D455).
@@ -17325,7 +17325,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17325
17325
  kind: literal("node"),
17326
17326
  nodeId: string().min(1)
17327
17327
  })]);
17328
+ /**
17329
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17330
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17331
+ * meaning); a rollup keeps the time spent in each state (`states`).
17332
+ */
17328
17333
  var DeviceHistoryKindSchema = _enum([
17334
+ "gauge",
17335
+ "counter",
17336
+ "boolean",
17337
+ "enum"
17338
+ ]);
17339
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17340
+ var DeviceHistoryProducerKindSchema = _enum([
17329
17341
  "gauge",
17330
17342
  "counter",
17331
17343
  "boolean"
@@ -17362,7 +17374,13 @@ var SeriesInfoSchema = object({
17362
17374
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17363
17375
  unit: string().nullable(),
17364
17376
  displayName: string(),
17365
- source: _enum(["cap", "addon"]),
17377
+ source: _enum([
17378
+ "cap",
17379
+ "addon",
17380
+ "derived"
17381
+ ]),
17382
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17383
+ values: array(string()).readonly().nullable(),
17366
17384
  firstTs: number(),
17367
17385
  lastTs: number()
17368
17386
  });
@@ -17376,17 +17394,31 @@ var QueryPointSchema = object({
17376
17394
  twMean: number().nullable(),
17377
17395
  min: number(),
17378
17396
  max: number(),
17379
- /** `null` is unknown, never zero (D393). */
17380
- last: number().nullable()
17397
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17398
+ last: number().nullable(),
17399
+ /**
17400
+ * The increase over the point: a `counter`'s growth since the previous point
17401
+ * or bucket (a drop is a reset, counted from zero), and for
17402
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17403
+ * every other kind, and when it cannot be known.
17404
+ */
17405
+ delta: number().nullable(),
17406
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17407
+ state: string().nullable(),
17408
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17409
+ states: record(string(), number()).nullable()
17381
17410
  });
17382
17411
  var QuerySeriesSchema = object({
17383
17412
  scope: string(),
17384
17413
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17385
17414
  before: object({
17386
17415
  t: number(),
17387
- value: number().nullable()
17416
+ value: number().nullable(),
17417
+ state: string().nullable()
17388
17418
  }).nullable(),
17389
- points: array(QueryPointSchema).readonly()
17419
+ points: array(QueryPointSchema).readonly(),
17420
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17421
+ derivedFrom: string().nullable()
17390
17422
  });
17391
17423
  /** The window part of a query, shared by the device and node forms. */
17392
17424
  var QueryWindowShape = {
@@ -17402,6 +17434,23 @@ var QueryResultSchema = object({
17402
17434
  series: array(QuerySeriesSchema).readonly(),
17403
17435
  truncated: boolean()
17404
17436
  });
17437
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17438
+ var QueryManyItemSchema = union([object({
17439
+ deviceId: number().int(),
17440
+ key: string(),
17441
+ scope: string().optional()
17442
+ }), object({
17443
+ forNodeId: string().min(1),
17444
+ key: string(),
17445
+ scope: string().optional()
17446
+ })]);
17447
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17448
+ ok: literal(true),
17449
+ result: QueryResultSchema
17450
+ }), object({
17451
+ ok: literal(false),
17452
+ error: string()
17453
+ })]);
17405
17454
  var TierStatusSchema = object({
17406
17455
  tier: DeviceHistoryResolutionSchema,
17407
17456
  /** `null` until the first background count answered. */
@@ -17457,16 +17506,22 @@ var DeviceHistoryStatusSchema = object({
17457
17506
  lastRefreshAt: number().nullable()
17458
17507
  })
17459
17508
  });
17460
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17509
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17461
17510
  deviceId: number().int(),
17462
17511
  ...QueryWindowShape
17463
17512
  }), QueryResultSchema), method(object({
17464
- nodeId: string().min(1),
17513
+ forNodeId: string().min(1),
17465
17514
  ...QueryWindowShape
17466
17515
  }), QueryResultSchema, { auth: "admin" }), method(object({
17516
+ items: array(QueryManyItemSchema).min(1).max(24),
17517
+ from: QueryWindowShape.from,
17518
+ to: QueryWindowShape.to,
17519
+ resolution: QueryWindowShape.resolution,
17520
+ maxPoints: QueryWindowShape.maxPoints
17521
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17467
17522
  name: string().regex(/^[a-z0-9-]+$/),
17468
17523
  subjectKind: _enum(["device", "node"]),
17469
- kind: DeviceHistoryKindSchema,
17524
+ kind: DeviceHistoryProducerKindSchema,
17470
17525
  unit: string().optional(),
17471
17526
  displayName: string().min(1),
17472
17527
  ingest: _enum(["points", "buckets"])
@@ -40807,14 +40862,106 @@ var LogEntrySchema = object({
40807
40862
  meta: record(string(), unknown()).optional(),
40808
40863
  tags: record(string(), string()).optional()
40809
40864
  });
40810
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40811
- scope: array(string()).optional(),
40865
+ /**
40866
+ * A history READ against one destination (D898).
40867
+ *
40868
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40869
+ * browser applied after the limit is what made a rare device's lines
40870
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40871
+ * minted (opaque to everyone else): a file position for the rotated files, a
40872
+ * nanosecond timestamp for Loki.
40873
+ *
40874
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40875
+ * store answers `done: false` with the cursor it reached and the bytes it
40876
+ * scanned, and the caller decides whether to go on. That is what makes a long
40877
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40878
+ * flight, and not asking for the next slice ends the scan.
40879
+ */
40880
+ var LogReadQuerySchema = object({
40881
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40882
+ requestId: string().min(1).max(64).optional(),
40883
+ /** The device the line is about (`tags.deviceId`, numeric). */
40884
+ deviceId: number().int().optional(),
40885
+ /**
40886
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40887
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40888
+ */
40889
+ fromAddonId: string().min(1).max(200).optional(),
40890
+ /**
40891
+ * The emitting node: matches the agent that emitted the line, the node
40892
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40893
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40894
+ * name as "which node's provider".
40895
+ */
40896
+ fromNodeId: string().min(1).max(200).optional(),
40897
+ /** Any other tag, exact match (AND). */
40898
+ tags: record(string(), union([string(), number()])).optional(),
40899
+ /** Severity FLOOR: this level and above. */
40812
40900
  level: LogLevelSchema.optional(),
40813
- since: date().optional(),
40814
- until: date().optional(),
40815
- limit: number().optional(),
40816
- tags: record(string(), string()).optional()
40817
- }), array(LogEntrySchema).readonly());
40901
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40902
+ text: string().min(1).max(200).optional(),
40903
+ /** Epoch ms, inclusive. */
40904
+ since: number().optional(),
40905
+ /** Epoch ms, inclusive. */
40906
+ until: number().optional(),
40907
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40908
+ before: string().min(1).max(1024).optional(),
40909
+ /** Newer than this cursor (exclusive). */
40910
+ after: string().min(1).max(1024).optional(),
40911
+ limit: number().int().min(1).max(1e3).optional(),
40912
+ /** Wall-clock bound of this slice. The provider caps it. */
40913
+ budgetMs: number().int().min(50).max(1e4).optional()
40914
+ });
40915
+ var LogReadResultSchema = object({
40916
+ /** Newest first. */
40917
+ entries: array(object({
40918
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40919
+ id: string().optional(),
40920
+ /** Epoch ms. */
40921
+ timestamp: number(),
40922
+ level: LogLevelSchema,
40923
+ scope: string().optional(),
40924
+ message: string(),
40925
+ tags: record(string(), union([string(), number()])).optional(),
40926
+ meta: record(string(), unknown()).optional()
40927
+ })),
40928
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40929
+ nextBefore: string().nullable(),
40930
+ /** Pass as `after` to read what arrived since; null when unknown. */
40931
+ nextAfter: string().nullable(),
40932
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40933
+ scannedBytes: number().int().nonnegative(),
40934
+ /**
40935
+ * True when the scan in this direction reached the end of the store.
40936
+ * False with fewer than `limit` entries means the budget ran out first —
40937
+ * call again with `nextBefore` to go on.
40938
+ */
40939
+ done: boolean(),
40940
+ /** True when `cancelRead` ended this slice early. */
40941
+ cancelled: boolean().optional()
40942
+ });
40943
+ var LogReadCapabilitiesSchema = object({
40944
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40945
+ readable: boolean(),
40946
+ /** Why not, when `readable` is false — rendered next to the source. */
40947
+ reason: string().nullable(),
40948
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40949
+ filters: object({
40950
+ deviceId: boolean(),
40951
+ addonId: boolean(),
40952
+ nodeId: boolean(),
40953
+ tags: boolean(),
40954
+ level: boolean(),
40955
+ text: boolean(),
40956
+ timeRange: boolean()
40957
+ }),
40958
+ /** How far back the store reaches, when the provider knows (days). */
40959
+ retentionDays: number().nullable()
40960
+ });
40961
+ 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() }), {
40962
+ kind: "mutation",
40963
+ auth: "admin"
40964
+ });
40818
40965
  /**
40819
40966
  * `login-method` — collection cap through which auth addons contribute
40820
40967
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42532,9 +42679,11 @@ var alarmPanelCapability = {
42532
42679
  */
42533
42680
  durability: "restored",
42534
42681
  /**
42535
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
42682
+ * History (D850): the panel's lifecycle state as an `enum` series —
42683
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
42684
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42536
42685
  */
42537
- history: "none",
42686
+ history: { fields: { state: { kind: "enum" } } },
42538
42687
  /** Clock fields: written, but excluded from the compare that decides
42539
42688
  * whether persisting is worth a SQLite commit. */
42540
42689
  volatileStateFields: ["lastChangedAt"]
@@ -43412,6 +43561,33 @@ var NcRuleTargetSchema = object({
43412
43561
  params: record(string(), unknown()).optional()
43413
43562
  });
43414
43563
  /**
43564
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43565
+ *
43566
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43567
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43568
+ * to the zone that fired the rule) and renders it once at send time:
43569
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43570
+ * colour and every OTHER track visible at that instant outlined thin, each
43571
+ * labelled with class and confidence ("dog 87%").
43572
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43573
+ * - `clean` — the whole scene with nothing drawn on it.
43574
+ * - `none` — no picture.
43575
+ *
43576
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43577
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43578
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43579
+ * ship a crop on one event and a boxed scene on the next depending on which
43580
+ * stored kind had landed.
43581
+ */
43582
+ var NcMediaImageSchema = _enum([
43583
+ "scene-boxes",
43584
+ "crop",
43585
+ "clean",
43586
+ "none"
43587
+ ]);
43588
+ /**
43589
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43590
+ *
43415
43591
  * Media attachment policy (P1 still-image subset).
43416
43592
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43417
43593
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43425,6 +43601,8 @@ var NcRuleTargetSchema = object({
43425
43601
  * - `none` — no attachment.
43426
43602
  */
43427
43603
  /**
43604
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43605
+ *
43428
43606
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43429
43607
  * conflate it with the selection strategy and betray the request: asking for
43430
43608
  * the clean scene frame on an object-event owner used to start at
@@ -43453,16 +43631,29 @@ var NcMediaFrameSchema = _enum([
43453
43631
  */
43454
43632
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43455
43633
  var NcMediaPolicySchema = object({
43634
+ /**
43635
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43636
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43637
+ * triple below, at load and at every write, and the store keeps only this.
43638
+ */
43639
+ image: NcMediaImageSchema.optional(),
43640
+ /**
43641
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43642
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43643
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43644
+ * Replaces `zoneCrop`.
43645
+ */
43646
+ showTriggerZone: boolean().optional(),
43647
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43456
43648
  attach: _enum([
43457
43649
  "best",
43458
43650
  "best-matching",
43459
43651
  "keyFrame",
43460
43652
  "none"
43461
- ]).default("best"),
43462
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43653
+ ]).optional(),
43654
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43463
43655
  frame: NcMediaFrameSchema.optional(),
43464
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43465
- * "show me the ZONE", not the whole scene or the subject crop. */
43656
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43466
43657
  zoneCrop: boolean().optional(),
43467
43658
  /**
43468
43659
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43634,7 +43825,9 @@ var NcRuleInputSchema = object({
43634
43825
  * targets.
43635
43826
  */
43636
43827
  targetUsers: array(string()).optional(),
43637
- media: NcMediaPolicySchema.default({ attach: "best" }),
43828
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43829
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43830
+ media: NcMediaPolicySchema.default({}),
43638
43831
  throttle: NcThrottleSchema.default({
43639
43832
  cooldownSec: 60,
43640
43833
  scope: "rule-device"
@@ -44571,13 +44764,37 @@ var NcAlarmModeOpeningsSchema = object({
44571
44764
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44572
44765
  unknown: array(number().int())
44573
44766
  });
44767
+ /**
44768
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44769
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44770
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44771
+ * never looks fully armed (D62: off must never look like broken).
44772
+ */
44773
+ var NcAlarmInputBypassViewSchema = object({
44774
+ ruleId: string(),
44775
+ /** The rule's current name (its frozen name when the rule is gone). */
44776
+ ruleName: string(),
44777
+ /** The input: the sensor of the match, else its camera. */
44778
+ deviceId: number().int(),
44779
+ /** The input's current name. */
44780
+ name: string(),
44781
+ /** When it was bypassed (ms epoch). */
44782
+ since: number(),
44783
+ /** Triggers from this input dropped since. */
44784
+ dropped: number().int().min(0)
44785
+ });
44574
44786
  var NcAlarmLiveSchema = object({
44575
44787
  state: AlarmStateSchema,
44576
44788
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44577
44789
  targetMode: AlarmArmModeSchema.nullable(),
44578
44790
  availableModes: array(AlarmArmModeSchema),
44579
44791
  openings: array(NcAlarmModeOpeningsSchema),
44580
- exclusions: array(NcAlarmExclusionViewSchema)
44792
+ exclusions: array(NcAlarmExclusionViewSchema),
44793
+ /**
44794
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44795
+ * Defaulted so an older hub answer still parses (as "none known").
44796
+ */
44797
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44581
44798
  });
44582
44799
  var NcAlarmConfigSchema = object({
44583
44800
  /**
@@ -55818,9 +56035,11 @@ var connectivityCapability = {
55818
56035
  */
55819
56036
  durability: "restored",
55820
56037
  /**
55821
- * History (D850): none — duplicates device-status.online (one authority for availability).
56038
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
56039
+ * is the upstream entity's own link (a HA connectivity sensor), not the
56040
+ * device's reachability, which stays `device-status.online`.
55822
56041
  */
55823
- history: "none",
56042
+ history: { fields: { connected: { kind: "boolean" } } },
55824
56043
  /** Clock fields: written, but excluded from the compare that decides
55825
56044
  * whether persisting is worth a SQLite commit. */
55826
56045
  volatileStateFields: ["lastChangedAt"]
@@ -56644,11 +56863,22 @@ var dishwasherCapability = {
56644
56863
  },
56645
56864
  runtimeState: DishwasherStatusSchema,
56646
56865
  durability: "session",
56647
- history: { fields: { progressPercent: {
56648
- kind: "gauge",
56649
- unit: "%",
56650
- deadband: 2
56651
- } } }
56866
+ history: { fields: {
56867
+ progressPercent: {
56868
+ kind: "gauge",
56869
+ unit: "%",
56870
+ deadband: 2
56871
+ },
56872
+ state: { kind: "enum" },
56873
+ operationState: { kind: "enum" },
56874
+ remainingSeconds: {
56875
+ kind: "gauge",
56876
+ unit: "s",
56877
+ minIntervalMs: 6e4
56878
+ },
56879
+ doorOpen: { kind: "boolean" },
56880
+ powerOn: { kind: "boolean" }
56881
+ } }
56652
56882
  };
56653
56883
  var DoorbellStatusSchema = object({
56654
56884
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -56765,9 +56995,15 @@ var enumSensorCapability = {
56765
56995
  */
56766
56996
  durability: "restored",
56767
56997
  /**
56768
- * History (D850): none — text/enum state has no history (non-goal).
56998
+ * History (D850): the value as an `enum` series (an appliance's program or
56999
+ * operation state, an HVAC action). The option set is per device, so the
57000
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
57001
+ * `format` carries a timestamp, not a state, and is not recorded.
56769
57002
  */
56770
- history: "none",
57003
+ history: { fields: { value: {
57004
+ kind: "enum",
57005
+ skipWhenSet: "format"
57006
+ } } },
56771
57007
  /** Clock fields: written, but excluded from the compare that decides
56772
57008
  * whether persisting is worth a SQLite commit. */
56773
57009
  volatileStateFields: ["lastFetchedAt"]
@@ -58741,9 +58977,10 @@ var lockControlCapability = {
58741
58977
  */
58742
58978
  durability: "restored",
58743
58979
  /**
58744
- * History (D850): none — enum state; lock events belong in the events ledger.
58980
+ * History (D850): the lock's state as an `enum` series — change-only, no
58981
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
58745
58982
  */
58746
- history: "none",
58983
+ history: { fields: { state: { kind: "enum" } } },
58747
58984
  /** Clock fields: written, but excluded from the compare that decides
58748
58985
  * whether persisting is worth a SQLite commit. */
58749
58986
  volatileStateFields: ["lastChangedAt"]
@@ -58917,9 +59154,18 @@ var mediaPlayerCapability = {
58917
59154
  */
58918
59155
  durability: "session",
58919
59156
  /**
58920
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
59157
+ * History (D850): volume (a level an operator or an automation sets; the
59158
+ * default 10 s floor folds a slider drag into its end value) and mute.
59159
+ * `positionMs` is not recorded: it moves continuously while playing.
58921
59160
  */
58922
- history: "none"
59161
+ history: { fields: {
59162
+ volumeLevel: {
59163
+ kind: "gauge",
59164
+ unit: "%",
59165
+ deadband: 1
59166
+ },
59167
+ isMuted: { kind: "boolean" }
59168
+ } }
58923
59169
  };
58924
59170
  /**
58925
59171
  * mesh-network — collection cap for mesh-VPN providers.
@@ -64575,9 +64821,29 @@ var streamParamsCapability = {
64575
64821
  */
64576
64822
  durability: "restored",
64577
64823
  /**
64578
- * History (D850): none — encoder configuration.
64824
+ * History (D850): the configured bitrate and frame rate of the main and sub
64825
+ * profiles. Configuration, so change-only on the default floor: a point is an
64826
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
64827
+ * quality over time must show.
64579
64828
  */
64580
- history: "none",
64829
+ history: { fields: {
64830
+ "main.bitrate": {
64831
+ kind: "gauge",
64832
+ unit: "kbps"
64833
+ },
64834
+ "main.framerate": {
64835
+ kind: "gauge",
64836
+ unit: "fps"
64837
+ },
64838
+ "sub.bitrate": {
64839
+ kind: "gauge",
64840
+ unit: "kbps"
64841
+ },
64842
+ "sub.framerate": {
64843
+ kind: "gauge",
64844
+ unit: "fps"
64845
+ }
64846
+ } },
64581
64847
  /** Clock fields: written, but excluded from the compare that decides
64582
64848
  * whether persisting is worth a SQLite commit. */
64583
64849
  volatileStateFields: ["lastFetchedAt"]
@@ -67968,6 +68234,15 @@ var BaseDevice = class {
67968
68234
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
67969
68235
  * with a typed cast.
67970
68236
  *
68237
+ * Answer what you KNOW. A plain array is read as the complete list only
68238
+ * while this device is `online` and probed; return
68239
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
68240
+ * now (no credentials, parent not connected, a failed or partial read) —
68241
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
68242
+ * to say "connected, and this is the complete list" explicitly. A shrink is
68243
+ * deleted only after a second agreeing complete read on a later probe (D49;
68244
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
68245
+ *
67971
68246
  * Default: no children.
67972
68247
  */
67973
68248
  getAccessoryChildren() {
@@ -72103,7 +72378,19 @@ Object.freeze({
72103
72378
  addonId: null,
72104
72379
  access: "view"
72105
72380
  },
72106
- "logDestination.query": {
72381
+ "logDestination.cancelRead": {
72382
+ capName: "log-destination",
72383
+ capScope: "system",
72384
+ addonId: null,
72385
+ access: "create"
72386
+ },
72387
+ "logDestination.describeRead": {
72388
+ capName: "log-destination",
72389
+ capScope: "system",
72390
+ addonId: null,
72391
+ access: "view"
72392
+ },
72393
+ "logDestination.read": {
72107
72394
  capName: "log-destination",
72108
72395
  capScope: "system",
72109
72396
  addonId: null,
@@ -78328,6 +78615,11 @@ Object.freeze({
78328
78615
  form: "single",
78329
78616
  optional: false
78330
78617
  }],
78618
+ "logDestination.read": [{
78619
+ name: "deviceId",
78620
+ form: "single",
78621
+ optional: true
78622
+ }],
78331
78623
  "mediaPlayer.getStatus": [{
78332
78624
  name: "deviceId",
78333
78625
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-hikvision",
3
- "version": "1.2.157",
3
+ "version": "1.2.158",
4
4
  "description": "Hikvision camera device provider addon for CamStack — ISAPI over HTTP(S) with digest auth (snapshot, alarm stream, RTSP discovery)",
5
5
  "keywords": [
6
6
  "camstack",