@camstack/addon-matter-broker 0.2.132 → 0.2.133

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
@@ -5561,7 +5561,7 @@ var ZodIssueCode = {
5561
5561
  var ZodFirstPartyTypeKind;
5562
5562
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5563
5563
  //#endregion
5564
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5564
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5565
5565
  /**
5566
5566
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5567
5567
  * window to float samples (D455).
@@ -17390,7 +17390,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17390
17390
  kind: literal("node"),
17391
17391
  nodeId: string$2().min(1)
17392
17392
  })]);
17393
+ /**
17394
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17395
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17396
+ * meaning); a rollup keeps the time spent in each state (`states`).
17397
+ */
17393
17398
  var DeviceHistoryKindSchema = _enum([
17399
+ "gauge",
17400
+ "counter",
17401
+ "boolean",
17402
+ "enum"
17403
+ ]);
17404
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17405
+ var DeviceHistoryProducerKindSchema = _enum([
17394
17406
  "gauge",
17395
17407
  "counter",
17396
17408
  "boolean"
@@ -17427,7 +17439,13 @@ var SeriesInfoSchema = object({
17427
17439
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17428
17440
  unit: string$2().nullable(),
17429
17441
  displayName: string$2(),
17430
- source: _enum(["cap", "addon"]),
17442
+ source: _enum([
17443
+ "cap",
17444
+ "addon",
17445
+ "derived"
17446
+ ]),
17447
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17448
+ values: array(string$2()).readonly().nullable(),
17431
17449
  firstTs: number(),
17432
17450
  lastTs: number()
17433
17451
  });
@@ -17441,17 +17459,31 @@ var QueryPointSchema = object({
17441
17459
  twMean: number().nullable(),
17442
17460
  min: number(),
17443
17461
  max: number(),
17444
- /** `null` is unknown, never zero (D393). */
17445
- last: number().nullable()
17462
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17463
+ last: number().nullable(),
17464
+ /**
17465
+ * The increase over the point: a `counter`'s growth since the previous point
17466
+ * or bucket (a drop is a reset, counted from zero), and for
17467
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17468
+ * every other kind, and when it cannot be known.
17469
+ */
17470
+ delta: number().nullable(),
17471
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17472
+ state: string$2().nullable(),
17473
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17474
+ states: record(string$2(), number()).nullable()
17446
17475
  });
17447
17476
  var QuerySeriesSchema = object({
17448
17477
  scope: string$2(),
17449
17478
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17450
17479
  before: object({
17451
17480
  t: number(),
17452
- value: number().nullable()
17481
+ value: number().nullable(),
17482
+ state: string$2().nullable()
17453
17483
  }).nullable(),
17454
- points: array(QueryPointSchema).readonly()
17484
+ points: array(QueryPointSchema).readonly(),
17485
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17486
+ derivedFrom: string$2().nullable()
17455
17487
  });
17456
17488
  /** The window part of a query, shared by the device and node forms. */
17457
17489
  var QueryWindowShape = {
@@ -17467,6 +17499,23 @@ var QueryResultSchema = object({
17467
17499
  series: array(QuerySeriesSchema).readonly(),
17468
17500
  truncated: boolean()
17469
17501
  });
17502
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17503
+ var QueryManyItemSchema = union([object({
17504
+ deviceId: number().int(),
17505
+ key: string$2(),
17506
+ scope: string$2().optional()
17507
+ }), object({
17508
+ forNodeId: string$2().min(1),
17509
+ key: string$2(),
17510
+ scope: string$2().optional()
17511
+ })]);
17512
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17513
+ ok: literal(true),
17514
+ result: QueryResultSchema
17515
+ }), object({
17516
+ ok: literal(false),
17517
+ error: string$2()
17518
+ })]);
17470
17519
  var TierStatusSchema = object({
17471
17520
  tier: DeviceHistoryResolutionSchema,
17472
17521
  /** `null` until the first background count answered. */
@@ -17522,16 +17571,22 @@ var DeviceHistoryStatusSchema = object({
17522
17571
  lastRefreshAt: number().nullable()
17523
17572
  })
17524
17573
  });
17525
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string$2().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17574
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string$2().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17526
17575
  deviceId: number().int(),
17527
17576
  ...QueryWindowShape
17528
17577
  }), QueryResultSchema), method(object({
17529
- nodeId: string$2().min(1),
17578
+ forNodeId: string$2().min(1),
17530
17579
  ...QueryWindowShape
17531
17580
  }), QueryResultSchema, { auth: "admin" }), method(object({
17581
+ items: array(QueryManyItemSchema).min(1).max(24),
17582
+ from: QueryWindowShape.from,
17583
+ to: QueryWindowShape.to,
17584
+ resolution: QueryWindowShape.resolution,
17585
+ maxPoints: QueryWindowShape.maxPoints
17586
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17532
17587
  name: string$2().regex(/^[a-z0-9-]+$/),
17533
17588
  subjectKind: _enum(["device", "node"]),
17534
- kind: DeviceHistoryKindSchema,
17589
+ kind: DeviceHistoryProducerKindSchema,
17535
17590
  unit: string$2().optional(),
17536
17591
  displayName: string$2().min(1),
17537
17592
  ingest: _enum(["points", "buckets"])
@@ -40757,14 +40812,106 @@ var LogEntrySchema = object({
40757
40812
  meta: record(string$2(), unknown()).optional(),
40758
40813
  tags: record(string$2(), string$2()).optional()
40759
40814
  });
40760
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40761
- scope: array(string$2()).optional(),
40815
+ /**
40816
+ * A history READ against one destination (D898).
40817
+ *
40818
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40819
+ * browser applied after the limit is what made a rare device's lines
40820
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40821
+ * minted (opaque to everyone else): a file position for the rotated files, a
40822
+ * nanosecond timestamp for Loki.
40823
+ *
40824
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40825
+ * store answers `done: false` with the cursor it reached and the bytes it
40826
+ * scanned, and the caller decides whether to go on. That is what makes a long
40827
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40828
+ * flight, and not asking for the next slice ends the scan.
40829
+ */
40830
+ var LogReadQuerySchema = object({
40831
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40832
+ requestId: string$2().min(1).max(64).optional(),
40833
+ /** The device the line is about (`tags.deviceId`, numeric). */
40834
+ deviceId: number().int().optional(),
40835
+ /**
40836
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40837
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40838
+ */
40839
+ fromAddonId: string$2().min(1).max(200).optional(),
40840
+ /**
40841
+ * The emitting node: matches the agent that emitted the line, the node
40842
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40843
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40844
+ * name as "which node's provider".
40845
+ */
40846
+ fromNodeId: string$2().min(1).max(200).optional(),
40847
+ /** Any other tag, exact match (AND). */
40848
+ tags: record(string$2(), union([string$2(), number()])).optional(),
40849
+ /** Severity FLOOR: this level and above. */
40762
40850
  level: LogLevelSchema.optional(),
40763
- since: date().optional(),
40764
- until: date().optional(),
40765
- limit: number().optional(),
40766
- tags: record(string$2(), string$2()).optional()
40767
- }), array(LogEntrySchema).readonly());
40851
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40852
+ text: string$2().min(1).max(200).optional(),
40853
+ /** Epoch ms, inclusive. */
40854
+ since: number().optional(),
40855
+ /** Epoch ms, inclusive. */
40856
+ until: number().optional(),
40857
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40858
+ before: string$2().min(1).max(1024).optional(),
40859
+ /** Newer than this cursor (exclusive). */
40860
+ after: string$2().min(1).max(1024).optional(),
40861
+ limit: number().int().min(1).max(1e3).optional(),
40862
+ /** Wall-clock bound of this slice. The provider caps it. */
40863
+ budgetMs: number().int().min(50).max(1e4).optional()
40864
+ });
40865
+ var LogReadResultSchema = object({
40866
+ /** Newest first. */
40867
+ entries: array(object({
40868
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40869
+ id: string$2().optional(),
40870
+ /** Epoch ms. */
40871
+ timestamp: number(),
40872
+ level: LogLevelSchema,
40873
+ scope: string$2().optional(),
40874
+ message: string$2(),
40875
+ tags: record(string$2(), union([string$2(), number()])).optional(),
40876
+ meta: record(string$2(), unknown()).optional()
40877
+ })),
40878
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40879
+ nextBefore: string$2().nullable(),
40880
+ /** Pass as `after` to read what arrived since; null when unknown. */
40881
+ nextAfter: string$2().nullable(),
40882
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40883
+ scannedBytes: number().int().nonnegative(),
40884
+ /**
40885
+ * True when the scan in this direction reached the end of the store.
40886
+ * False with fewer than `limit` entries means the budget ran out first —
40887
+ * call again with `nextBefore` to go on.
40888
+ */
40889
+ done: boolean(),
40890
+ /** True when `cancelRead` ended this slice early. */
40891
+ cancelled: boolean().optional()
40892
+ });
40893
+ var LogReadCapabilitiesSchema = object({
40894
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40895
+ readable: boolean(),
40896
+ /** Why not, when `readable` is false — rendered next to the source. */
40897
+ reason: string$2().nullable(),
40898
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40899
+ filters: object({
40900
+ deviceId: boolean(),
40901
+ addonId: boolean(),
40902
+ nodeId: boolean(),
40903
+ tags: boolean(),
40904
+ level: boolean(),
40905
+ text: boolean(),
40906
+ timeRange: boolean()
40907
+ }),
40908
+ /** How far back the store reaches, when the provider knows (days). */
40909
+ retentionDays: number().nullable()
40910
+ });
40911
+ method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(_void(), LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string$2().min(1).max(64) }), object({ cancelled: boolean() }), {
40912
+ kind: "mutation",
40913
+ auth: "admin"
40914
+ });
40768
40915
  /**
40769
40916
  * `login-method` — collection cap through which auth addons contribute
40770
40917
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42482,9 +42629,11 @@ var alarmPanelCapability = {
42482
42629
  */
42483
42630
  durability: "restored",
42484
42631
  /**
42485
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
42632
+ * History (D850): the panel's lifecycle state as an `enum` series —
42633
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
42634
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42486
42635
  */
42487
- history: "none",
42636
+ history: { fields: { state: { kind: "enum" } } },
42488
42637
  /** Clock fields: written, but excluded from the compare that decides
42489
42638
  * whether persisting is worth a SQLite commit. */
42490
42639
  volatileStateFields: ["lastChangedAt"]
@@ -43362,6 +43511,33 @@ var NcRuleTargetSchema = object({
43362
43511
  params: record(string$2(), unknown()).optional()
43363
43512
  });
43364
43513
  /**
43514
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43515
+ *
43516
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43517
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43518
+ * to the zone that fired the rule) and renders it once at send time:
43519
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43520
+ * colour and every OTHER track visible at that instant outlined thin, each
43521
+ * labelled with class and confidence ("dog 87%").
43522
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43523
+ * - `clean` — the whole scene with nothing drawn on it.
43524
+ * - `none` — no picture.
43525
+ *
43526
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43527
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43528
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43529
+ * ship a crop on one event and a boxed scene on the next depending on which
43530
+ * stored kind had landed.
43531
+ */
43532
+ var NcMediaImageSchema = _enum([
43533
+ "scene-boxes",
43534
+ "crop",
43535
+ "clean",
43536
+ "none"
43537
+ ]);
43538
+ /**
43539
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43540
+ *
43365
43541
  * Media attachment policy (P1 still-image subset).
43366
43542
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43367
43543
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43375,6 +43551,8 @@ var NcRuleTargetSchema = object({
43375
43551
  * - `none` — no attachment.
43376
43552
  */
43377
43553
  /**
43554
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43555
+ *
43378
43556
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43379
43557
  * conflate it with the selection strategy and betray the request: asking for
43380
43558
  * the clean scene frame on an object-event owner used to start at
@@ -43403,16 +43581,29 @@ var NcMediaFrameSchema = _enum([
43403
43581
  */
43404
43582
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43405
43583
  var NcMediaPolicySchema = object({
43584
+ /**
43585
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43586
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43587
+ * triple below, at load and at every write, and the store keeps only this.
43588
+ */
43589
+ image: NcMediaImageSchema.optional(),
43590
+ /**
43591
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43592
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43593
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43594
+ * Replaces `zoneCrop`.
43595
+ */
43596
+ showTriggerZone: boolean().optional(),
43597
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43406
43598
  attach: _enum([
43407
43599
  "best",
43408
43600
  "best-matching",
43409
43601
  "keyFrame",
43410
43602
  "none"
43411
- ]).default("best"),
43412
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43603
+ ]).optional(),
43604
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43413
43605
  frame: NcMediaFrameSchema.optional(),
43414
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43415
- * "show me the ZONE", not the whole scene or the subject crop. */
43606
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43416
43607
  zoneCrop: boolean().optional(),
43417
43608
  /**
43418
43609
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43584,7 +43775,9 @@ var NcRuleInputSchema = object({
43584
43775
  * targets.
43585
43776
  */
43586
43777
  targetUsers: array(string$2()).optional(),
43587
- media: NcMediaPolicySchema.default({ attach: "best" }),
43778
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43779
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43780
+ media: NcMediaPolicySchema.default({}),
43588
43781
  throttle: NcThrottleSchema.default({
43589
43782
  cooldownSec: 60,
43590
43783
  scope: "rule-device"
@@ -44521,13 +44714,37 @@ var NcAlarmModeOpeningsSchema = object({
44521
44714
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44522
44715
  unknown: array(number().int())
44523
44716
  });
44717
+ /**
44718
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44719
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44720
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44721
+ * never looks fully armed (D62: off must never look like broken).
44722
+ */
44723
+ var NcAlarmInputBypassViewSchema = object({
44724
+ ruleId: string$2(),
44725
+ /** The rule's current name (its frozen name when the rule is gone). */
44726
+ ruleName: string$2(),
44727
+ /** The input: the sensor of the match, else its camera. */
44728
+ deviceId: number().int(),
44729
+ /** The input's current name. */
44730
+ name: string$2(),
44731
+ /** When it was bypassed (ms epoch). */
44732
+ since: number(),
44733
+ /** Triggers from this input dropped since. */
44734
+ dropped: number().int().min(0)
44735
+ });
44524
44736
  var NcAlarmLiveSchema = object({
44525
44737
  state: AlarmStateSchema,
44526
44738
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44527
44739
  targetMode: AlarmArmModeSchema.nullable(),
44528
44740
  availableModes: array(AlarmArmModeSchema),
44529
44741
  openings: array(NcAlarmModeOpeningsSchema),
44530
- exclusions: array(NcAlarmExclusionViewSchema)
44742
+ exclusions: array(NcAlarmExclusionViewSchema),
44743
+ /**
44744
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44745
+ * Defaulted so an older hub answer still parses (as "none known").
44746
+ */
44747
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44531
44748
  });
44532
44749
  var NcAlarmConfigSchema = object({
44533
44750
  /**
@@ -55263,9 +55480,11 @@ var connectivityCapability = {
55263
55480
  */
55264
55481
  durability: "restored",
55265
55482
  /**
55266
- * History (D850): none — duplicates device-status.online (one authority for availability).
55483
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
55484
+ * is the upstream entity's own link (a HA connectivity sensor), not the
55485
+ * device's reachability, which stays `device-status.online`.
55267
55486
  */
55268
- history: "none",
55487
+ history: { fields: { connected: { kind: "boolean" } } },
55269
55488
  /** Clock fields: written, but excluded from the compare that decides
55270
55489
  * whether persisting is worth a SQLite commit. */
55271
55490
  volatileStateFields: ["lastChangedAt"]
@@ -56089,11 +56308,22 @@ var dishwasherCapability = {
56089
56308
  },
56090
56309
  runtimeState: DishwasherStatusSchema,
56091
56310
  durability: "session",
56092
- history: { fields: { progressPercent: {
56093
- kind: "gauge",
56094
- unit: "%",
56095
- deadband: 2
56096
- } } }
56311
+ history: { fields: {
56312
+ progressPercent: {
56313
+ kind: "gauge",
56314
+ unit: "%",
56315
+ deadband: 2
56316
+ },
56317
+ state: { kind: "enum" },
56318
+ operationState: { kind: "enum" },
56319
+ remainingSeconds: {
56320
+ kind: "gauge",
56321
+ unit: "s",
56322
+ minIntervalMs: 6e4
56323
+ },
56324
+ doorOpen: { kind: "boolean" },
56325
+ powerOn: { kind: "boolean" }
56326
+ } }
56097
56327
  };
56098
56328
  var DoorbellStatusSchema = object({
56099
56329
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -56210,9 +56440,15 @@ var enumSensorCapability = {
56210
56440
  */
56211
56441
  durability: "restored",
56212
56442
  /**
56213
- * History (D850): none — text/enum state has no history (non-goal).
56443
+ * History (D850): the value as an `enum` series (an appliance's program or
56444
+ * operation state, an HVAC action). The option set is per device, so the
56445
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
56446
+ * `format` carries a timestamp, not a state, and is not recorded.
56214
56447
  */
56215
- history: "none",
56448
+ history: { fields: { value: {
56449
+ kind: "enum",
56450
+ skipWhenSet: "format"
56451
+ } } },
56216
56452
  /** Clock fields: written, but excluded from the compare that decides
56217
56453
  * whether persisting is worth a SQLite commit. */
56218
56454
  volatileStateFields: ["lastFetchedAt"]
@@ -58186,9 +58422,10 @@ var lockControlCapability = {
58186
58422
  */
58187
58423
  durability: "restored",
58188
58424
  /**
58189
- * History (D850): none — enum state; lock events belong in the events ledger.
58425
+ * History (D850): the lock's state as an `enum` series — change-only, no
58426
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
58190
58427
  */
58191
- history: "none",
58428
+ history: { fields: { state: { kind: "enum" } } },
58192
58429
  /** Clock fields: written, but excluded from the compare that decides
58193
58430
  * whether persisting is worth a SQLite commit. */
58194
58431
  volatileStateFields: ["lastChangedAt"]
@@ -58362,9 +58599,18 @@ var mediaPlayerCapability = {
58362
58599
  */
58363
58600
  durability: "session",
58364
58601
  /**
58365
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
58602
+ * History (D850): volume (a level an operator or an automation sets; the
58603
+ * default 10 s floor folds a slider drag into its end value) and mute.
58604
+ * `positionMs` is not recorded: it moves continuously while playing.
58366
58605
  */
58367
- history: "none"
58606
+ history: { fields: {
58607
+ volumeLevel: {
58608
+ kind: "gauge",
58609
+ unit: "%",
58610
+ deadband: 1
58611
+ },
58612
+ isMuted: { kind: "boolean" }
58613
+ } }
58368
58614
  };
58369
58615
  /**
58370
58616
  * mesh-network — collection cap for mesh-VPN providers.
@@ -63657,9 +63903,29 @@ var streamParamsCapability = {
63657
63903
  */
63658
63904
  durability: "restored",
63659
63905
  /**
63660
- * History (D850): none — encoder configuration.
63906
+ * History (D850): the configured bitrate and frame rate of the main and sub
63907
+ * profiles. Configuration, so change-only on the default floor: a point is an
63908
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
63909
+ * quality over time must show.
63661
63910
  */
63662
- history: "none",
63911
+ history: { fields: {
63912
+ "main.bitrate": {
63913
+ kind: "gauge",
63914
+ unit: "kbps"
63915
+ },
63916
+ "main.framerate": {
63917
+ kind: "gauge",
63918
+ unit: "fps"
63919
+ },
63920
+ "sub.bitrate": {
63921
+ kind: "gauge",
63922
+ unit: "kbps"
63923
+ },
63924
+ "sub.framerate": {
63925
+ kind: "gauge",
63926
+ unit: "fps"
63927
+ }
63928
+ } },
63663
63929
  /** Clock fields: written, but excluded from the compare that decides
63664
63930
  * whether persisting is worth a SQLite commit. */
63665
63931
  volatileStateFields: ["lastFetchedAt"]
@@ -66837,6 +67103,15 @@ var BaseDevice = class {
66837
67103
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
66838
67104
  * with a typed cast.
66839
67105
  *
67106
+ * Answer what you KNOW. A plain array is read as the complete list only
67107
+ * while this device is `online` and probed; return
67108
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
67109
+ * now (no credentials, parent not connected, a failed or partial read) —
67110
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
67111
+ * to say "connected, and this is the complete list" explicitly. A shrink is
67112
+ * deleted only after a second agreeing complete read on a later probe (D49;
67113
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
67114
+ *
66840
67115
  * Default: no children.
66841
67116
  */
66842
67117
  getAccessoryChildren() {
@@ -70968,7 +71243,19 @@ Object.freeze({
70968
71243
  addonId: null,
70969
71244
  access: "view"
70970
71245
  },
70971
- "logDestination.query": {
71246
+ "logDestination.cancelRead": {
71247
+ capName: "log-destination",
71248
+ capScope: "system",
71249
+ addonId: null,
71250
+ access: "create"
71251
+ },
71252
+ "logDestination.describeRead": {
71253
+ capName: "log-destination",
71254
+ capScope: "system",
71255
+ addonId: null,
71256
+ access: "view"
71257
+ },
71258
+ "logDestination.read": {
70972
71259
  capName: "log-destination",
70973
71260
  capScope: "system",
70974
71261
  addonId: null,
@@ -76975,6 +77262,11 @@ Object.freeze({
76975
77262
  form: "single",
76976
77263
  optional: false
76977
77264
  }],
77265
+ "logDestination.read": [{
77266
+ name: "deviceId",
77267
+ form: "single",
77268
+ optional: true
77269
+ }],
76978
77270
  "mediaPlayer.getStatus": [{
76979
77271
  name: "deviceId",
76980
77272
  form: "single",
package/dist/addon.mjs CHANGED
@@ -5559,7 +5559,7 @@ var ZodIssueCode = {
5559
5559
  var ZodFirstPartyTypeKind;
5560
5560
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5561
5561
  //#endregion
5562
- //#region ../types/dist/sleep-yKL5gfrH.mjs
5562
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5563
5563
  /**
5564
5564
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5565
5565
  * window to float samples (D455).
@@ -17388,7 +17388,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17388
17388
  kind: literal("node"),
17389
17389
  nodeId: string$2().min(1)
17390
17390
  })]);
17391
+ /**
17392
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17393
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17394
+ * meaning); a rollup keeps the time spent in each state (`states`).
17395
+ */
17391
17396
  var DeviceHistoryKindSchema = _enum([
17397
+ "gauge",
17398
+ "counter",
17399
+ "boolean",
17400
+ "enum"
17401
+ ]);
17402
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17403
+ var DeviceHistoryProducerKindSchema = _enum([
17392
17404
  "gauge",
17393
17405
  "counter",
17394
17406
  "boolean"
@@ -17425,7 +17437,13 @@ var SeriesInfoSchema = object({
17425
17437
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17426
17438
  unit: string$2().nullable(),
17427
17439
  displayName: string$2(),
17428
- source: _enum(["cap", "addon"]),
17440
+ source: _enum([
17441
+ "cap",
17442
+ "addon",
17443
+ "derived"
17444
+ ]),
17445
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17446
+ values: array(string$2()).readonly().nullable(),
17429
17447
  firstTs: number(),
17430
17448
  lastTs: number()
17431
17449
  });
@@ -17439,17 +17457,31 @@ var QueryPointSchema = object({
17439
17457
  twMean: number().nullable(),
17440
17458
  min: number(),
17441
17459
  max: number(),
17442
- /** `null` is unknown, never zero (D393). */
17443
- last: number().nullable()
17460
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17461
+ last: number().nullable(),
17462
+ /**
17463
+ * The increase over the point: a `counter`'s growth since the previous point
17464
+ * or bucket (a drop is a reset, counted from zero), and for
17465
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17466
+ * every other kind, and when it cannot be known.
17467
+ */
17468
+ delta: number().nullable(),
17469
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17470
+ state: string$2().nullable(),
17471
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17472
+ states: record(string$2(), number()).nullable()
17444
17473
  });
17445
17474
  var QuerySeriesSchema = object({
17446
17475
  scope: string$2(),
17447
17476
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17448
17477
  before: object({
17449
17478
  t: number(),
17450
- value: number().nullable()
17479
+ value: number().nullable(),
17480
+ state: string$2().nullable()
17451
17481
  }).nullable(),
17452
- points: array(QueryPointSchema).readonly()
17482
+ points: array(QueryPointSchema).readonly(),
17483
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17484
+ derivedFrom: string$2().nullable()
17453
17485
  });
17454
17486
  /** The window part of a query, shared by the device and node forms. */
17455
17487
  var QueryWindowShape = {
@@ -17465,6 +17497,23 @@ var QueryResultSchema = object({
17465
17497
  series: array(QuerySeriesSchema).readonly(),
17466
17498
  truncated: boolean()
17467
17499
  });
17500
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17501
+ var QueryManyItemSchema = union([object({
17502
+ deviceId: number().int(),
17503
+ key: string$2(),
17504
+ scope: string$2().optional()
17505
+ }), object({
17506
+ forNodeId: string$2().min(1),
17507
+ key: string$2(),
17508
+ scope: string$2().optional()
17509
+ })]);
17510
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17511
+ ok: literal(true),
17512
+ result: QueryResultSchema
17513
+ }), object({
17514
+ ok: literal(false),
17515
+ error: string$2()
17516
+ })]);
17468
17517
  var TierStatusSchema = object({
17469
17518
  tier: DeviceHistoryResolutionSchema,
17470
17519
  /** `null` until the first background count answered. */
@@ -17520,16 +17569,22 @@ var DeviceHistoryStatusSchema = object({
17520
17569
  lastRefreshAt: number().nullable()
17521
17570
  })
17522
17571
  });
17523
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string$2().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17572
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string$2().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17524
17573
  deviceId: number().int(),
17525
17574
  ...QueryWindowShape
17526
17575
  }), QueryResultSchema), method(object({
17527
- nodeId: string$2().min(1),
17576
+ forNodeId: string$2().min(1),
17528
17577
  ...QueryWindowShape
17529
17578
  }), QueryResultSchema, { auth: "admin" }), method(object({
17579
+ items: array(QueryManyItemSchema).min(1).max(24),
17580
+ from: QueryWindowShape.from,
17581
+ to: QueryWindowShape.to,
17582
+ resolution: QueryWindowShape.resolution,
17583
+ maxPoints: QueryWindowShape.maxPoints
17584
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17530
17585
  name: string$2().regex(/^[a-z0-9-]+$/),
17531
17586
  subjectKind: _enum(["device", "node"]),
17532
- kind: DeviceHistoryKindSchema,
17587
+ kind: DeviceHistoryProducerKindSchema,
17533
17588
  unit: string$2().optional(),
17534
17589
  displayName: string$2().min(1),
17535
17590
  ingest: _enum(["points", "buckets"])
@@ -40755,14 +40810,106 @@ var LogEntrySchema = object({
40755
40810
  meta: record(string$2(), unknown()).optional(),
40756
40811
  tags: record(string$2(), string$2()).optional()
40757
40812
  });
40758
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40759
- scope: array(string$2()).optional(),
40813
+ /**
40814
+ * A history READ against one destination (D898).
40815
+ *
40816
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40817
+ * browser applied after the limit is what made a rare device's lines
40818
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40819
+ * minted (opaque to everyone else): a file position for the rotated files, a
40820
+ * nanosecond timestamp for Loki.
40821
+ *
40822
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40823
+ * store answers `done: false` with the cursor it reached and the bytes it
40824
+ * scanned, and the caller decides whether to go on. That is what makes a long
40825
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40826
+ * flight, and not asking for the next slice ends the scan.
40827
+ */
40828
+ var LogReadQuerySchema = object({
40829
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40830
+ requestId: string$2().min(1).max(64).optional(),
40831
+ /** The device the line is about (`tags.deviceId`, numeric). */
40832
+ deviceId: number().int().optional(),
40833
+ /**
40834
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40835
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40836
+ */
40837
+ fromAddonId: string$2().min(1).max(200).optional(),
40838
+ /**
40839
+ * The emitting node: matches the agent that emitted the line, the node
40840
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40841
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40842
+ * name as "which node's provider".
40843
+ */
40844
+ fromNodeId: string$2().min(1).max(200).optional(),
40845
+ /** Any other tag, exact match (AND). */
40846
+ tags: record(string$2(), union([string$2(), number()])).optional(),
40847
+ /** Severity FLOOR: this level and above. */
40760
40848
  level: LogLevelSchema.optional(),
40761
- since: date().optional(),
40762
- until: date().optional(),
40763
- limit: number().optional(),
40764
- tags: record(string$2(), string$2()).optional()
40765
- }), array(LogEntrySchema).readonly());
40849
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40850
+ text: string$2().min(1).max(200).optional(),
40851
+ /** Epoch ms, inclusive. */
40852
+ since: number().optional(),
40853
+ /** Epoch ms, inclusive. */
40854
+ until: number().optional(),
40855
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40856
+ before: string$2().min(1).max(1024).optional(),
40857
+ /** Newer than this cursor (exclusive). */
40858
+ after: string$2().min(1).max(1024).optional(),
40859
+ limit: number().int().min(1).max(1e3).optional(),
40860
+ /** Wall-clock bound of this slice. The provider caps it. */
40861
+ budgetMs: number().int().min(50).max(1e4).optional()
40862
+ });
40863
+ var LogReadResultSchema = object({
40864
+ /** Newest first. */
40865
+ entries: array(object({
40866
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40867
+ id: string$2().optional(),
40868
+ /** Epoch ms. */
40869
+ timestamp: number(),
40870
+ level: LogLevelSchema,
40871
+ scope: string$2().optional(),
40872
+ message: string$2(),
40873
+ tags: record(string$2(), union([string$2(), number()])).optional(),
40874
+ meta: record(string$2(), unknown()).optional()
40875
+ })),
40876
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40877
+ nextBefore: string$2().nullable(),
40878
+ /** Pass as `after` to read what arrived since; null when unknown. */
40879
+ nextAfter: string$2().nullable(),
40880
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40881
+ scannedBytes: number().int().nonnegative(),
40882
+ /**
40883
+ * True when the scan in this direction reached the end of the store.
40884
+ * False with fewer than `limit` entries means the budget ran out first —
40885
+ * call again with `nextBefore` to go on.
40886
+ */
40887
+ done: boolean(),
40888
+ /** True when `cancelRead` ended this slice early. */
40889
+ cancelled: boolean().optional()
40890
+ });
40891
+ var LogReadCapabilitiesSchema = object({
40892
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40893
+ readable: boolean(),
40894
+ /** Why not, when `readable` is false — rendered next to the source. */
40895
+ reason: string$2().nullable(),
40896
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40897
+ filters: object({
40898
+ deviceId: boolean(),
40899
+ addonId: boolean(),
40900
+ nodeId: boolean(),
40901
+ tags: boolean(),
40902
+ level: boolean(),
40903
+ text: boolean(),
40904
+ timeRange: boolean()
40905
+ }),
40906
+ /** How far back the store reaches, when the provider knows (days). */
40907
+ retentionDays: number().nullable()
40908
+ });
40909
+ method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(_void(), LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string$2().min(1).max(64) }), object({ cancelled: boolean() }), {
40910
+ kind: "mutation",
40911
+ auth: "admin"
40912
+ });
40766
40913
  /**
40767
40914
  * `login-method` — collection cap through which auth addons contribute
40768
40915
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42480,9 +42627,11 @@ var alarmPanelCapability = {
42480
42627
  */
42481
42628
  durability: "restored",
42482
42629
  /**
42483
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
42630
+ * History (D850): the panel's lifecycle state as an `enum` series —
42631
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
42632
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42484
42633
  */
42485
- history: "none",
42634
+ history: { fields: { state: { kind: "enum" } } },
42486
42635
  /** Clock fields: written, but excluded from the compare that decides
42487
42636
  * whether persisting is worth a SQLite commit. */
42488
42637
  volatileStateFields: ["lastChangedAt"]
@@ -43360,6 +43509,33 @@ var NcRuleTargetSchema = object({
43360
43509
  params: record(string$2(), unknown()).optional()
43361
43510
  });
43362
43511
  /**
43512
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43513
+ *
43514
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43515
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43516
+ * to the zone that fired the rule) and renders it once at send time:
43517
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43518
+ * colour and every OTHER track visible at that instant outlined thin, each
43519
+ * labelled with class and confidence ("dog 87%").
43520
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43521
+ * - `clean` — the whole scene with nothing drawn on it.
43522
+ * - `none` — no picture.
43523
+ *
43524
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43525
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43526
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43527
+ * ship a crop on one event and a boxed scene on the next depending on which
43528
+ * stored kind had landed.
43529
+ */
43530
+ var NcMediaImageSchema = _enum([
43531
+ "scene-boxes",
43532
+ "crop",
43533
+ "clean",
43534
+ "none"
43535
+ ]);
43536
+ /**
43537
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43538
+ *
43363
43539
  * Media attachment policy (P1 still-image subset).
43364
43540
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43365
43541
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43373,6 +43549,8 @@ var NcRuleTargetSchema = object({
43373
43549
  * - `none` — no attachment.
43374
43550
  */
43375
43551
  /**
43552
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43553
+ *
43376
43554
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43377
43555
  * conflate it with the selection strategy and betray the request: asking for
43378
43556
  * the clean scene frame on an object-event owner used to start at
@@ -43401,16 +43579,29 @@ var NcMediaFrameSchema = _enum([
43401
43579
  */
43402
43580
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43403
43581
  var NcMediaPolicySchema = object({
43582
+ /**
43583
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43584
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43585
+ * triple below, at load and at every write, and the store keeps only this.
43586
+ */
43587
+ image: NcMediaImageSchema.optional(),
43588
+ /**
43589
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43590
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43591
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43592
+ * Replaces `zoneCrop`.
43593
+ */
43594
+ showTriggerZone: boolean().optional(),
43595
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43404
43596
  attach: _enum([
43405
43597
  "best",
43406
43598
  "best-matching",
43407
43599
  "keyFrame",
43408
43600
  "none"
43409
- ]).default("best"),
43410
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43601
+ ]).optional(),
43602
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43411
43603
  frame: NcMediaFrameSchema.optional(),
43412
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43413
- * "show me the ZONE", not the whole scene or the subject crop. */
43604
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43414
43605
  zoneCrop: boolean().optional(),
43415
43606
  /**
43416
43607
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43582,7 +43773,9 @@ var NcRuleInputSchema = object({
43582
43773
  * targets.
43583
43774
  */
43584
43775
  targetUsers: array(string$2()).optional(),
43585
- media: NcMediaPolicySchema.default({ attach: "best" }),
43776
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43777
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43778
+ media: NcMediaPolicySchema.default({}),
43586
43779
  throttle: NcThrottleSchema.default({
43587
43780
  cooldownSec: 60,
43588
43781
  scope: "rule-device"
@@ -44519,13 +44712,37 @@ var NcAlarmModeOpeningsSchema = object({
44519
44712
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44520
44713
  unknown: array(number().int())
44521
44714
  });
44715
+ /**
44716
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44717
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44718
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44719
+ * never looks fully armed (D62: off must never look like broken).
44720
+ */
44721
+ var NcAlarmInputBypassViewSchema = object({
44722
+ ruleId: string$2(),
44723
+ /** The rule's current name (its frozen name when the rule is gone). */
44724
+ ruleName: string$2(),
44725
+ /** The input: the sensor of the match, else its camera. */
44726
+ deviceId: number().int(),
44727
+ /** The input's current name. */
44728
+ name: string$2(),
44729
+ /** When it was bypassed (ms epoch). */
44730
+ since: number(),
44731
+ /** Triggers from this input dropped since. */
44732
+ dropped: number().int().min(0)
44733
+ });
44522
44734
  var NcAlarmLiveSchema = object({
44523
44735
  state: AlarmStateSchema,
44524
44736
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44525
44737
  targetMode: AlarmArmModeSchema.nullable(),
44526
44738
  availableModes: array(AlarmArmModeSchema),
44527
44739
  openings: array(NcAlarmModeOpeningsSchema),
44528
- exclusions: array(NcAlarmExclusionViewSchema)
44740
+ exclusions: array(NcAlarmExclusionViewSchema),
44741
+ /**
44742
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44743
+ * Defaulted so an older hub answer still parses (as "none known").
44744
+ */
44745
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44529
44746
  });
44530
44747
  var NcAlarmConfigSchema = object({
44531
44748
  /**
@@ -55261,9 +55478,11 @@ var connectivityCapability = {
55261
55478
  */
55262
55479
  durability: "restored",
55263
55480
  /**
55264
- * History (D850): none — duplicates device-status.online (one authority for availability).
55481
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
55482
+ * is the upstream entity's own link (a HA connectivity sensor), not the
55483
+ * device's reachability, which stays `device-status.online`.
55265
55484
  */
55266
- history: "none",
55485
+ history: { fields: { connected: { kind: "boolean" } } },
55267
55486
  /** Clock fields: written, but excluded from the compare that decides
55268
55487
  * whether persisting is worth a SQLite commit. */
55269
55488
  volatileStateFields: ["lastChangedAt"]
@@ -56087,11 +56306,22 @@ var dishwasherCapability = {
56087
56306
  },
56088
56307
  runtimeState: DishwasherStatusSchema,
56089
56308
  durability: "session",
56090
- history: { fields: { progressPercent: {
56091
- kind: "gauge",
56092
- unit: "%",
56093
- deadband: 2
56094
- } } }
56309
+ history: { fields: {
56310
+ progressPercent: {
56311
+ kind: "gauge",
56312
+ unit: "%",
56313
+ deadband: 2
56314
+ },
56315
+ state: { kind: "enum" },
56316
+ operationState: { kind: "enum" },
56317
+ remainingSeconds: {
56318
+ kind: "gauge",
56319
+ unit: "s",
56320
+ minIntervalMs: 6e4
56321
+ },
56322
+ doorOpen: { kind: "boolean" },
56323
+ powerOn: { kind: "boolean" }
56324
+ } }
56095
56325
  };
56096
56326
  var DoorbellStatusSchema = object({
56097
56327
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -56208,9 +56438,15 @@ var enumSensorCapability = {
56208
56438
  */
56209
56439
  durability: "restored",
56210
56440
  /**
56211
- * History (D850): none — text/enum state has no history (non-goal).
56441
+ * History (D850): the value as an `enum` series (an appliance's program or
56442
+ * operation state, an HVAC action). The option set is per device, so the
56443
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
56444
+ * `format` carries a timestamp, not a state, and is not recorded.
56212
56445
  */
56213
- history: "none",
56446
+ history: { fields: { value: {
56447
+ kind: "enum",
56448
+ skipWhenSet: "format"
56449
+ } } },
56214
56450
  /** Clock fields: written, but excluded from the compare that decides
56215
56451
  * whether persisting is worth a SQLite commit. */
56216
56452
  volatileStateFields: ["lastFetchedAt"]
@@ -58184,9 +58420,10 @@ var lockControlCapability = {
58184
58420
  */
58185
58421
  durability: "restored",
58186
58422
  /**
58187
- * History (D850): none — enum state; lock events belong in the events ledger.
58423
+ * History (D850): the lock's state as an `enum` series — change-only, no
58424
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
58188
58425
  */
58189
- history: "none",
58426
+ history: { fields: { state: { kind: "enum" } } },
58190
58427
  /** Clock fields: written, but excluded from the compare that decides
58191
58428
  * whether persisting is worth a SQLite commit. */
58192
58429
  volatileStateFields: ["lastChangedAt"]
@@ -58360,9 +58597,18 @@ var mediaPlayerCapability = {
58360
58597
  */
58361
58598
  durability: "session",
58362
58599
  /**
58363
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
58600
+ * History (D850): volume (a level an operator or an automation sets; the
58601
+ * default 10 s floor folds a slider drag into its end value) and mute.
58602
+ * `positionMs` is not recorded: it moves continuously while playing.
58364
58603
  */
58365
- history: "none"
58604
+ history: { fields: {
58605
+ volumeLevel: {
58606
+ kind: "gauge",
58607
+ unit: "%",
58608
+ deadband: 1
58609
+ },
58610
+ isMuted: { kind: "boolean" }
58611
+ } }
58366
58612
  };
58367
58613
  /**
58368
58614
  * mesh-network — collection cap for mesh-VPN providers.
@@ -63655,9 +63901,29 @@ var streamParamsCapability = {
63655
63901
  */
63656
63902
  durability: "restored",
63657
63903
  /**
63658
- * History (D850): none — encoder configuration.
63904
+ * History (D850): the configured bitrate and frame rate of the main and sub
63905
+ * profiles. Configuration, so change-only on the default floor: a point is an
63906
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
63907
+ * quality over time must show.
63659
63908
  */
63660
- history: "none",
63909
+ history: { fields: {
63910
+ "main.bitrate": {
63911
+ kind: "gauge",
63912
+ unit: "kbps"
63913
+ },
63914
+ "main.framerate": {
63915
+ kind: "gauge",
63916
+ unit: "fps"
63917
+ },
63918
+ "sub.bitrate": {
63919
+ kind: "gauge",
63920
+ unit: "kbps"
63921
+ },
63922
+ "sub.framerate": {
63923
+ kind: "gauge",
63924
+ unit: "fps"
63925
+ }
63926
+ } },
63661
63927
  /** Clock fields: written, but excluded from the compare that decides
63662
63928
  * whether persisting is worth a SQLite commit. */
63663
63929
  volatileStateFields: ["lastFetchedAt"]
@@ -66835,6 +67101,15 @@ var BaseDevice = class {
66835
67101
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
66836
67102
  * with a typed cast.
66837
67103
  *
67104
+ * Answer what you KNOW. A plain array is read as the complete list only
67105
+ * while this device is `online` and probed; return
67106
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
67107
+ * now (no credentials, parent not connected, a failed or partial read) —
67108
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
67109
+ * to say "connected, and this is the complete list" explicitly. A shrink is
67110
+ * deleted only after a second agreeing complete read on a later probe (D49;
67111
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
67112
+ *
66838
67113
  * Default: no children.
66839
67114
  */
66840
67115
  getAccessoryChildren() {
@@ -70966,7 +71241,19 @@ Object.freeze({
70966
71241
  addonId: null,
70967
71242
  access: "view"
70968
71243
  },
70969
- "logDestination.query": {
71244
+ "logDestination.cancelRead": {
71245
+ capName: "log-destination",
71246
+ capScope: "system",
71247
+ addonId: null,
71248
+ access: "create"
71249
+ },
71250
+ "logDestination.describeRead": {
71251
+ capName: "log-destination",
71252
+ capScope: "system",
71253
+ addonId: null,
71254
+ access: "view"
71255
+ },
71256
+ "logDestination.read": {
70970
71257
  capName: "log-destination",
70971
71258
  capScope: "system",
70972
71259
  addonId: null,
@@ -76973,6 +77260,11 @@ Object.freeze({
76973
77260
  form: "single",
76974
77261
  optional: false
76975
77262
  }],
77263
+ "logDestination.read": [{
77264
+ name: "deviceId",
77265
+ form: "single",
77266
+ optional: true
77267
+ }],
76976
77268
  "mediaPlayer.getStatus": [{
76977
77269
  name: "deviceId",
76978
77270
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-matter-broker",
3
- "version": "0.2.132",
3
+ "version": "0.2.133",
4
4
  "description": "Matter broker addon for CamStack — owns a Matter fabric (commissioning + the long-lived controller) via the matter.js controller and brokers commissioned Matter nodes into CamStack",
5
5
  "keywords": [
6
6
  "camstack",