@camstack/types 1.2.242 → 1.2.244

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.
@@ -0,0 +1,705 @@
1
+ import { z } from 'zod';
2
+ import { DeviceType } from '../device/device-type.js';
3
+ import { type InferNativeProvider } from './capability-definition.js';
4
+ /**
5
+ * Vendor-neutral **onboard** recording + storage cap — what the CAMERA
6
+ * writes to the CAMERA's own card, on the camera's own schedule.
7
+ *
8
+ * This is NOT `recording.cap.ts`. That one is CamStack's recorder: our
9
+ * footage ledger, our storage locations, our retention. This one has a
10
+ * different authority — the camera's firmware — and per D62 it stores
11
+ * nothing of its own. Every value here is read from the camera and every
12
+ * write goes back to the camera; there is no CamStack-side mirror that
13
+ * could disagree with the device.
14
+ *
15
+ * ## One shape, two firmwares
16
+ *
17
+ * Measured 2026-09-22 against the live fleet:
18
+ *
19
+ * | fact | Hikvision (ISAPI) | Reolink (Baichuan) |
20
+ * | --- | --- | --- |
21
+ * | storage | `ContentMgmt/Storage` `<hdd>` rows: status, capacity, freeSpace (MB) | `getHddInfoList` (cmd 102): `mount`, `format`, `capacity` GB + `capacityM` MB remainder |
22
+ * | tracks | several (101 **and** 103 on both 1436 and 3833), each with its own schedule | one per channel |
23
+ * | schedule | per track, 7 `ScheduleAction` blocks: DayOfWeek + TimeOfDay range + ONE `ActionRecordingMode` | per trigger type, a 168-char weekly HOUR mask |
24
+ * | triggers | `CMR`, `MOTION` | `Normal`, `MD`, `people`, `vehicle`, `dog_cat`, `crossline`, `intrude`, `loitering` |
25
+ * | pre-record | `PreRecordTimeSeconds` | `preRecordTime` |
26
+ * | post-record | `PostRecordTimeSeconds` | `recordDelayTime` |
27
+ * | overwrite | per track `LoopEnable` | `cycle`, with `cycleList` enumerating the accepted values |
28
+ * | segment length | not exposed on V5.7.1 | `packageTime` (minutes) |
29
+ *
30
+ * The two schedule models look different and are the same thing in
31
+ * different coordinates: both answer "for this trigger, during which
32
+ * weekly windows does the camera record". {@link RecordWindow} is that
33
+ * question in one shape — Hikvision's ranges map straight onto it,
34
+ * Reolink's mask expands into hour-aligned windows.
35
+ *
36
+ * ## Union, not intersection
37
+ *
38
+ * **The same fields exist on every camera.** What differs per device is
39
+ * which VALUES that device accepts, and that is what {@link
40
+ * RecordingOnboardOptions} reports — a `{ readable, writable, reason }`
41
+ * per field plus the schedule's own limits. A control a camera cannot
42
+ * honour is rendered DISABLED WITH ITS REASON, never missing and never
43
+ * dead: disabled must not look like broken.
44
+ *
45
+ * ## Refusal by name
46
+ *
47
+ * A write a camera cannot honour is refused with a sentence the operator
48
+ * can read — never accepted and dropped. Both providers refuse through
49
+ * {@link describeOnboardRefusal}, so the vocabulary is one function and
50
+ * one test, not two hand-written vendor opinions.
51
+ *
52
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
53
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
54
+ * injected from `status`) reports the live values, and a single
55
+ * `setSettings` mutation applies a partial change. No hand-written
56
+ * settings-contribution methods.
57
+ */
58
+ /**
59
+ * What makes the camera start recording during a window.
60
+ *
61
+ * The union of both vendors' vocabularies. `continuous` is Hikvision's
62
+ * `CMR` and Reolink's `Normal`; `motion` is `MOTION` / `MD`. The
63
+ * object-class triggers are Reolink-only today and the smart-event ones
64
+ * (`lineCrossing`, `intrusion`, `loitering`) are Reolink-only on the
65
+ * firmwares measured — a camera that cannot record on a trigger simply
66
+ * does not list it in `options.schedule.triggers`, and a window naming
67
+ * it is REFUSED, not dropped.
68
+ */
69
+ export declare const RecordTriggerSchema: z.ZodEnum<{
70
+ person: "person";
71
+ vehicle: "vehicle";
72
+ animal: "animal";
73
+ motion: "motion";
74
+ loitering: "loitering";
75
+ continuous: "continuous";
76
+ lineCrossing: "lineCrossing";
77
+ intrusion: "intrusion";
78
+ alarmInput: "alarmInput";
79
+ }>;
80
+ /**
81
+ * One weekly recording window: "on `day`, from `startMinute` to
82
+ * `endMinute`, record on `trigger`".
83
+ *
84
+ * `day` is 0 = Monday … 6 = Sunday (ISO order, which is also the order
85
+ * both firmwares enumerate). Minutes are local camera time since
86
+ * midnight; `endMinute` may be 1440, meaning end of day — that is
87
+ * Hikvision's literal `24:00` and Reolink's 24th mask slot, and
88
+ * collapsing it to 0 would turn a whole-day window into an empty one.
89
+ */
90
+ export declare const RecordWindowSchema: z.ZodObject<{
91
+ trigger: z.ZodEnum<{
92
+ person: "person";
93
+ vehicle: "vehicle";
94
+ animal: "animal";
95
+ motion: "motion";
96
+ loitering: "loitering";
97
+ continuous: "continuous";
98
+ lineCrossing: "lineCrossing";
99
+ intrusion: "intrusion";
100
+ alarmInput: "alarmInput";
101
+ }>;
102
+ day: z.ZodNumber;
103
+ startMinute: z.ZodNumber;
104
+ endMinute: z.ZodNumber;
105
+ }, z.core.$strip>;
106
+ /** Status of one physical volume, as the camera itself describes it. */
107
+ export declare const OnboardStorageVolumeSchema: z.ZodObject<{
108
+ id: z.ZodString;
109
+ label: z.ZodOptional<z.ZodString>;
110
+ status: z.ZodEnum<{
111
+ unknown: "unknown";
112
+ error: "error";
113
+ ok: "ok";
114
+ offline: "offline";
115
+ unformatted: "unformatted";
116
+ }>;
117
+ capacityMb: z.ZodNullable<z.ZodNumber>;
118
+ freeMb: z.ZodNullable<z.ZodNumber>;
119
+ writable: z.ZodOptional<z.ZodBoolean>;
120
+ }, z.core.$strip>;
121
+ /**
122
+ * Whether the camera has usable onboard storage.
123
+ *
124
+ * Three states, never two: an unreadable answer is `unknown`, never
125
+ * folded into `absent`. Folding a failed read into "no card" is how a
126
+ * healthy camera gets reported as broken, and the inverse is how a
127
+ * camera with no card reports `ok` and then an empty list (D393).
128
+ */
129
+ export declare const OnboardStorageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
130
+ kind: z.ZodLiteral<"present">;
131
+ volumes: z.ZodArray<z.ZodObject<{
132
+ id: z.ZodString;
133
+ label: z.ZodOptional<z.ZodString>;
134
+ status: z.ZodEnum<{
135
+ unknown: "unknown";
136
+ error: "error";
137
+ ok: "ok";
138
+ offline: "offline";
139
+ unformatted: "unformatted";
140
+ }>;
141
+ capacityMb: z.ZodNullable<z.ZodNumber>;
142
+ freeMb: z.ZodNullable<z.ZodNumber>;
143
+ writable: z.ZodOptional<z.ZodBoolean>;
144
+ }, z.core.$strip>>;
145
+ }, z.core.$strip>, z.ZodObject<{
146
+ kind: z.ZodLiteral<"absent">;
147
+ reason: z.ZodString;
148
+ }, z.core.$strip>, z.ZodObject<{
149
+ kind: z.ZodLiteral<"unknown">;
150
+ reason: z.ZodString;
151
+ }, z.core.$strip>], "kind">;
152
+ /**
153
+ * One recording track the camera exposes. Read-only.
154
+ *
155
+ * Hikvision lists several — 1436 and 3833 each list 101 AND 103, with
156
+ * DIFFERENT schedules (101 MOTION all day, 103 CMR 00:05–23:57) — so a
157
+ * cap that reported one number for "the schedule" would be lying on
158
+ * every Hikvision in the fleet. Reolink has exactly one per channel.
159
+ *
160
+ * There is deliberately **no `framerate`**. Hikvision declares it in the
161
+ * track `Description` and it is WRONG: 1436 says `2.260000 fps` while
162
+ * the media measures 12.55 fps. `codec` and `resolution` from the same
163
+ * string ARE right — those are the only two worth surfacing.
164
+ */
165
+ export declare const OnboardRecordTrackSchema: z.ZodObject<{
166
+ id: z.ZodString;
167
+ enabled: z.ZodBoolean;
168
+ isVideo: z.ZodBoolean;
169
+ codec: z.ZodNullable<z.ZodString>;
170
+ resolution: z.ZodNullable<z.ZodString>;
171
+ overwriteWhenFull: z.ZodNullable<z.ZodBoolean>;
172
+ }, z.core.$strip>;
173
+ /**
174
+ * What the camera is doing with its own storage, right now.
175
+ *
176
+ * Every scalar is nullable and **null means the camera did not answer**,
177
+ * never a default. A form that seeds `0` from an unanswered read invites
178
+ * the operator to save that 0 back onto the camera.
179
+ */
180
+ export declare const RecordingOnboardStatusSchema: z.ZodObject<{
181
+ storage: z.ZodDiscriminatedUnion<[z.ZodObject<{
182
+ kind: z.ZodLiteral<"present">;
183
+ volumes: z.ZodArray<z.ZodObject<{
184
+ id: z.ZodString;
185
+ label: z.ZodOptional<z.ZodString>;
186
+ status: z.ZodEnum<{
187
+ unknown: "unknown";
188
+ error: "error";
189
+ ok: "ok";
190
+ offline: "offline";
191
+ unformatted: "unformatted";
192
+ }>;
193
+ capacityMb: z.ZodNullable<z.ZodNumber>;
194
+ freeMb: z.ZodNullable<z.ZodNumber>;
195
+ writable: z.ZodOptional<z.ZodBoolean>;
196
+ }, z.core.$strip>>;
197
+ }, z.core.$strip>, z.ZodObject<{
198
+ kind: z.ZodLiteral<"absent">;
199
+ reason: z.ZodString;
200
+ }, z.core.$strip>, z.ZodObject<{
201
+ kind: z.ZodLiteral<"unknown">;
202
+ reason: z.ZodString;
203
+ }, z.core.$strip>], "kind">;
204
+ tracks: z.ZodArray<z.ZodObject<{
205
+ id: z.ZodString;
206
+ enabled: z.ZodBoolean;
207
+ isVideo: z.ZodBoolean;
208
+ codec: z.ZodNullable<z.ZodString>;
209
+ resolution: z.ZodNullable<z.ZodString>;
210
+ overwriteWhenFull: z.ZodNullable<z.ZodBoolean>;
211
+ }, z.core.$strip>>;
212
+ primaryTrackId: z.ZodNullable<z.ZodString>;
213
+ enabled: z.ZodNullable<z.ZodBoolean>;
214
+ overwriteWhenFull: z.ZodNullable<z.ZodBoolean>;
215
+ preRecordSec: z.ZodNullable<z.ZodNumber>;
216
+ postRecordSec: z.ZodNullable<z.ZodNumber>;
217
+ segmentMinutes: z.ZodNullable<z.ZodNumber>;
218
+ windows: z.ZodArray<z.ZodObject<{
219
+ trigger: z.ZodEnum<{
220
+ person: "person";
221
+ vehicle: "vehicle";
222
+ animal: "animal";
223
+ motion: "motion";
224
+ loitering: "loitering";
225
+ continuous: "continuous";
226
+ lineCrossing: "lineCrossing";
227
+ intrusion: "intrusion";
228
+ alarmInput: "alarmInput";
229
+ }>;
230
+ day: z.ZodNumber;
231
+ startMinute: z.ZodNumber;
232
+ endMinute: z.ZodNumber;
233
+ }, z.core.$strip>>;
234
+ unreadableWindows: z.ZodNumber;
235
+ recordingToNowhere: z.ZodBoolean;
236
+ lastFetchedAt: z.ZodNumber;
237
+ }, z.core.$strip>;
238
+ /**
239
+ * The values a camera actually takes for a numeric field, when they are a SET
240
+ * rather than a range.
241
+ *
242
+ * `{min,max,step}` cannot say what these two firmwares do. Measured on 1436
243
+ * (I91DN) on 2026-09-22 by writing each value and reading it back:
244
+ *
245
+ * - pre-record: `0, 5, 10, 15, 20, 25, 30` and `2147483647` (INT32_MAX, the
246
+ * camera's "no limit" — `-1` and `4294967295` both land on it);
247
+ * - post-record: `5, 10, 30, 60, 120, 300, 600`.
248
+ *
249
+ * Neither is expressible as a step: the first has a sentinel two billion away
250
+ * from its neighbours, the second doubles and then jumps. A range that tried
251
+ * would forbid values the camera takes AND permit values it silently replaces
252
+ * with 5 — wrong in both directions at once.
253
+ *
254
+ * `sentinel` names the member that is not a duration, so a surface can render
255
+ * "no limit" instead of `2147483647` seconds.
256
+ */
257
+ declare const AllowedValuesSchema: z.ZodObject<{
258
+ values: z.ZodArray<z.ZodNumber>;
259
+ sentinel: z.ZodOptional<z.ZodObject<{
260
+ value: z.ZodNumber;
261
+ meaning: z.ZodEnum<{
262
+ disabled: "disabled";
263
+ "no-limit": "no-limit";
264
+ }>;
265
+ }, z.core.$strip>>;
266
+ }, z.core.$strip>;
267
+ export type OnboardAllowedValues = z.infer<typeof AllowedValuesSchema>;
268
+ /**
269
+ * Per-field availability on ONE camera.
270
+ *
271
+ * The field exists on every camera — this says whether this one can be
272
+ * read and whether it can be written, and `reason` says why not when
273
+ * either is false. The UI renders the control DISABLED with the reason
274
+ * rather than hiding it, so a limitation is legible instead of looking
275
+ * like a missing feature.
276
+ */
277
+ export declare const OnboardFieldSupportSchema: z.ZodObject<{
278
+ readable: z.ZodBoolean;
279
+ writable: z.ZodBoolean;
280
+ reason: z.ZodOptional<z.ZodString>;
281
+ }, z.core.$strip>;
282
+ /** What this camera's schedule model can express. */
283
+ export declare const OnboardScheduleSupportSchema: z.ZodObject<{
284
+ support: z.ZodObject<{
285
+ readable: z.ZodBoolean;
286
+ writable: z.ZodBoolean;
287
+ reason: z.ZodOptional<z.ZodString>;
288
+ }, z.core.$strip>;
289
+ granularityMinutes: z.ZodNumber;
290
+ triggers: z.ZodArray<z.ZodEnum<{
291
+ person: "person";
292
+ vehicle: "vehicle";
293
+ animal: "animal";
294
+ motion: "motion";
295
+ loitering: "loitering";
296
+ continuous: "continuous";
297
+ lineCrossing: "lineCrossing";
298
+ intrusion: "intrusion";
299
+ alarmInput: "alarmInput";
300
+ }>>;
301
+ supportsOverlappingTriggers: z.ZodBoolean;
302
+ }, z.core.$strip>;
303
+ export declare const RecordingOnboardOptionsSchema: z.ZodObject<{
304
+ enabled: z.ZodObject<{
305
+ readable: z.ZodBoolean;
306
+ writable: z.ZodBoolean;
307
+ reason: z.ZodOptional<z.ZodString>;
308
+ }, z.core.$strip>;
309
+ overwriteWhenFull: z.ZodObject<{
310
+ readable: z.ZodBoolean;
311
+ writable: z.ZodBoolean;
312
+ reason: z.ZodOptional<z.ZodString>;
313
+ }, z.core.$strip>;
314
+ preRecordSec: z.ZodObject<{
315
+ readable: z.ZodBoolean;
316
+ writable: z.ZodBoolean;
317
+ reason: z.ZodOptional<z.ZodString>;
318
+ }, z.core.$strip>;
319
+ preRecordSecRange: z.ZodOptional<z.ZodObject<{
320
+ min: z.ZodNumber;
321
+ max: z.ZodNumber;
322
+ step: z.ZodNumber;
323
+ }, z.core.$strip>>;
324
+ preRecordSecAllowed: z.ZodOptional<z.ZodObject<{
325
+ values: z.ZodArray<z.ZodNumber>;
326
+ sentinel: z.ZodOptional<z.ZodObject<{
327
+ value: z.ZodNumber;
328
+ meaning: z.ZodEnum<{
329
+ disabled: "disabled";
330
+ "no-limit": "no-limit";
331
+ }>;
332
+ }, z.core.$strip>>;
333
+ }, z.core.$strip>>;
334
+ postRecordSec: z.ZodObject<{
335
+ readable: z.ZodBoolean;
336
+ writable: z.ZodBoolean;
337
+ reason: z.ZodOptional<z.ZodString>;
338
+ }, z.core.$strip>;
339
+ postRecordSecRange: z.ZodOptional<z.ZodObject<{
340
+ min: z.ZodNumber;
341
+ max: z.ZodNumber;
342
+ step: z.ZodNumber;
343
+ }, z.core.$strip>>;
344
+ postRecordSecAllowed: z.ZodOptional<z.ZodObject<{
345
+ values: z.ZodArray<z.ZodNumber>;
346
+ sentinel: z.ZodOptional<z.ZodObject<{
347
+ value: z.ZodNumber;
348
+ meaning: z.ZodEnum<{
349
+ disabled: "disabled";
350
+ "no-limit": "no-limit";
351
+ }>;
352
+ }, z.core.$strip>>;
353
+ }, z.core.$strip>>;
354
+ segmentMinutes: z.ZodObject<{
355
+ readable: z.ZodBoolean;
356
+ writable: z.ZodBoolean;
357
+ reason: z.ZodOptional<z.ZodString>;
358
+ }, z.core.$strip>;
359
+ segmentMinutesRange: z.ZodOptional<z.ZodObject<{
360
+ min: z.ZodNumber;
361
+ max: z.ZodNumber;
362
+ step: z.ZodNumber;
363
+ }, z.core.$strip>>;
364
+ segmentMinutesAllowed: z.ZodOptional<z.ZodObject<{
365
+ values: z.ZodArray<z.ZodNumber>;
366
+ sentinel: z.ZodOptional<z.ZodObject<{
367
+ value: z.ZodNumber;
368
+ meaning: z.ZodEnum<{
369
+ disabled: "disabled";
370
+ "no-limit": "no-limit";
371
+ }>;
372
+ }, z.core.$strip>>;
373
+ }, z.core.$strip>>;
374
+ schedule: z.ZodObject<{
375
+ support: z.ZodObject<{
376
+ readable: z.ZodBoolean;
377
+ writable: z.ZodBoolean;
378
+ reason: z.ZodOptional<z.ZodString>;
379
+ }, z.core.$strip>;
380
+ granularityMinutes: z.ZodNumber;
381
+ triggers: z.ZodArray<z.ZodEnum<{
382
+ person: "person";
383
+ vehicle: "vehicle";
384
+ animal: "animal";
385
+ motion: "motion";
386
+ loitering: "loitering";
387
+ continuous: "continuous";
388
+ lineCrossing: "lineCrossing";
389
+ intrusion: "intrusion";
390
+ alarmInput: "alarmInput";
391
+ }>>;
392
+ supportsOverlappingTriggers: z.ZodBoolean;
393
+ }, z.core.$strip>;
394
+ }, z.core.$strip>;
395
+ /**
396
+ * A partial change. Every field optional.
397
+ *
398
+ * Unlike the other `deviceConfig` caps, a provider here does **NOT**
399
+ * silently ignore a field it cannot support — it refuses, by name,
400
+ * through {@link describeOnboardRefusal}. Silence on a recording setting
401
+ * is the failure D62 exists to prevent: the operator believes the camera
402
+ * is recording the way the form says, and it is not.
403
+ */
404
+ export declare const RecordingOnboardPatchSchema: z.ZodObject<{
405
+ enabled: z.ZodOptional<z.ZodBoolean>;
406
+ overwriteWhenFull: z.ZodOptional<z.ZodBoolean>;
407
+ preRecordSec: z.ZodOptional<z.ZodNumber>;
408
+ postRecordSec: z.ZodOptional<z.ZodNumber>;
409
+ segmentMinutes: z.ZodOptional<z.ZodNumber>;
410
+ windows: z.ZodOptional<z.ZodArray<z.ZodObject<{
411
+ trigger: z.ZodEnum<{
412
+ person: "person";
413
+ vehicle: "vehicle";
414
+ animal: "animal";
415
+ motion: "motion";
416
+ loitering: "loitering";
417
+ continuous: "continuous";
418
+ lineCrossing: "lineCrossing";
419
+ intrusion: "intrusion";
420
+ alarmInput: "alarmInput";
421
+ }>;
422
+ day: z.ZodNumber;
423
+ startMinute: z.ZodNumber;
424
+ endMinute: z.ZodNumber;
425
+ }, z.core.$strip>>>;
426
+ }, z.core.$strip>;
427
+ export type RecordTrigger = z.infer<typeof RecordTriggerSchema>;
428
+ export type RecordWindow = z.infer<typeof RecordWindowSchema>;
429
+ export type OnboardStorageVolume = z.infer<typeof OnboardStorageVolumeSchema>;
430
+ export type OnboardStorage = z.infer<typeof OnboardStorageSchema>;
431
+ export type OnboardRecordTrack = z.infer<typeof OnboardRecordTrackSchema>;
432
+ export type OnboardFieldSupport = z.infer<typeof OnboardFieldSupportSchema>;
433
+ export type OnboardScheduleSupport = z.infer<typeof OnboardScheduleSupportSchema>;
434
+ export type RecordingOnboardStatus = z.infer<typeof RecordingOnboardStatusSchema>;
435
+ export type RecordingOnboardOptions = z.infer<typeof RecordingOnboardOptionsSchema>;
436
+ export type RecordingOnboardPatch = z.infer<typeof RecordingOnboardPatchSchema>;
437
+ export declare const recordingOnboardCapability: {
438
+ readonly name: "recording-onboard";
439
+ readonly scope: "device";
440
+ readonly deviceNative: true;
441
+ readonly mode: "singleton";
442
+ readonly deviceTypes: readonly [DeviceType.Camera];
443
+ readonly deviceConfig: {
444
+ readonly ui: {
445
+ readonly kind: "derived-form";
446
+ readonly builderId: "recording-onboard";
447
+ readonly tab: "recording";
448
+ };
449
+ };
450
+ readonly methods: {
451
+ readonly getOptions: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
452
+ deviceId: z.ZodNumber;
453
+ }, z.core.$strip>, z.ZodObject<{
454
+ enabled: z.ZodObject<{
455
+ readable: z.ZodBoolean;
456
+ writable: z.ZodBoolean;
457
+ reason: z.ZodOptional<z.ZodString>;
458
+ }, z.core.$strip>;
459
+ overwriteWhenFull: z.ZodObject<{
460
+ readable: z.ZodBoolean;
461
+ writable: z.ZodBoolean;
462
+ reason: z.ZodOptional<z.ZodString>;
463
+ }, z.core.$strip>;
464
+ preRecordSec: z.ZodObject<{
465
+ readable: z.ZodBoolean;
466
+ writable: z.ZodBoolean;
467
+ reason: z.ZodOptional<z.ZodString>;
468
+ }, z.core.$strip>;
469
+ preRecordSecRange: z.ZodOptional<z.ZodObject<{
470
+ min: z.ZodNumber;
471
+ max: z.ZodNumber;
472
+ step: z.ZodNumber;
473
+ }, z.core.$strip>>;
474
+ preRecordSecAllowed: z.ZodOptional<z.ZodObject<{
475
+ values: z.ZodArray<z.ZodNumber>;
476
+ sentinel: z.ZodOptional<z.ZodObject<{
477
+ value: z.ZodNumber;
478
+ meaning: z.ZodEnum<{
479
+ disabled: "disabled";
480
+ "no-limit": "no-limit";
481
+ }>;
482
+ }, z.core.$strip>>;
483
+ }, z.core.$strip>>;
484
+ postRecordSec: z.ZodObject<{
485
+ readable: z.ZodBoolean;
486
+ writable: z.ZodBoolean;
487
+ reason: z.ZodOptional<z.ZodString>;
488
+ }, z.core.$strip>;
489
+ postRecordSecRange: z.ZodOptional<z.ZodObject<{
490
+ min: z.ZodNumber;
491
+ max: z.ZodNumber;
492
+ step: z.ZodNumber;
493
+ }, z.core.$strip>>;
494
+ postRecordSecAllowed: z.ZodOptional<z.ZodObject<{
495
+ values: z.ZodArray<z.ZodNumber>;
496
+ sentinel: z.ZodOptional<z.ZodObject<{
497
+ value: z.ZodNumber;
498
+ meaning: z.ZodEnum<{
499
+ disabled: "disabled";
500
+ "no-limit": "no-limit";
501
+ }>;
502
+ }, z.core.$strip>>;
503
+ }, z.core.$strip>>;
504
+ segmentMinutes: z.ZodObject<{
505
+ readable: z.ZodBoolean;
506
+ writable: z.ZodBoolean;
507
+ reason: z.ZodOptional<z.ZodString>;
508
+ }, z.core.$strip>;
509
+ segmentMinutesRange: z.ZodOptional<z.ZodObject<{
510
+ min: z.ZodNumber;
511
+ max: z.ZodNumber;
512
+ step: z.ZodNumber;
513
+ }, z.core.$strip>>;
514
+ segmentMinutesAllowed: z.ZodOptional<z.ZodObject<{
515
+ values: z.ZodArray<z.ZodNumber>;
516
+ sentinel: z.ZodOptional<z.ZodObject<{
517
+ value: z.ZodNumber;
518
+ meaning: z.ZodEnum<{
519
+ disabled: "disabled";
520
+ "no-limit": "no-limit";
521
+ }>;
522
+ }, z.core.$strip>>;
523
+ }, z.core.$strip>>;
524
+ schedule: z.ZodObject<{
525
+ support: z.ZodObject<{
526
+ readable: z.ZodBoolean;
527
+ writable: z.ZodBoolean;
528
+ reason: z.ZodOptional<z.ZodString>;
529
+ }, z.core.$strip>;
530
+ granularityMinutes: z.ZodNumber;
531
+ triggers: z.ZodArray<z.ZodEnum<{
532
+ person: "person";
533
+ vehicle: "vehicle";
534
+ animal: "animal";
535
+ motion: "motion";
536
+ loitering: "loitering";
537
+ continuous: "continuous";
538
+ lineCrossing: "lineCrossing";
539
+ intrusion: "intrusion";
540
+ alarmInput: "alarmInput";
541
+ }>>;
542
+ supportsOverlappingTriggers: z.ZodBoolean;
543
+ }, z.core.$strip>;
544
+ }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
545
+ readonly setSettings: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
546
+ deviceId: z.ZodNumber;
547
+ settings: z.ZodObject<{
548
+ enabled: z.ZodOptional<z.ZodBoolean>;
549
+ overwriteWhenFull: z.ZodOptional<z.ZodBoolean>;
550
+ preRecordSec: z.ZodOptional<z.ZodNumber>;
551
+ postRecordSec: z.ZodOptional<z.ZodNumber>;
552
+ segmentMinutes: z.ZodOptional<z.ZodNumber>;
553
+ windows: z.ZodOptional<z.ZodArray<z.ZodObject<{
554
+ trigger: z.ZodEnum<{
555
+ person: "person";
556
+ vehicle: "vehicle";
557
+ animal: "animal";
558
+ motion: "motion";
559
+ loitering: "loitering";
560
+ continuous: "continuous";
561
+ lineCrossing: "lineCrossing";
562
+ intrusion: "intrusion";
563
+ alarmInput: "alarmInput";
564
+ }>;
565
+ day: z.ZodNumber;
566
+ startMinute: z.ZodNumber;
567
+ endMinute: z.ZodNumber;
568
+ }, z.core.$strip>>>;
569
+ }, z.core.$strip>;
570
+ }, z.core.$strip>, z.ZodVoid, "mutation">;
571
+ };
572
+ readonly status: {
573
+ readonly schema: z.ZodObject<{
574
+ storage: z.ZodDiscriminatedUnion<[z.ZodObject<{
575
+ kind: z.ZodLiteral<"present">;
576
+ volumes: z.ZodArray<z.ZodObject<{
577
+ id: z.ZodString;
578
+ label: z.ZodOptional<z.ZodString>;
579
+ status: z.ZodEnum<{
580
+ unknown: "unknown";
581
+ error: "error";
582
+ ok: "ok";
583
+ offline: "offline";
584
+ unformatted: "unformatted";
585
+ }>;
586
+ capacityMb: z.ZodNullable<z.ZodNumber>;
587
+ freeMb: z.ZodNullable<z.ZodNumber>;
588
+ writable: z.ZodOptional<z.ZodBoolean>;
589
+ }, z.core.$strip>>;
590
+ }, z.core.$strip>, z.ZodObject<{
591
+ kind: z.ZodLiteral<"absent">;
592
+ reason: z.ZodString;
593
+ }, z.core.$strip>, z.ZodObject<{
594
+ kind: z.ZodLiteral<"unknown">;
595
+ reason: z.ZodString;
596
+ }, z.core.$strip>], "kind">;
597
+ tracks: z.ZodArray<z.ZodObject<{
598
+ id: z.ZodString;
599
+ enabled: z.ZodBoolean;
600
+ isVideo: z.ZodBoolean;
601
+ codec: z.ZodNullable<z.ZodString>;
602
+ resolution: z.ZodNullable<z.ZodString>;
603
+ overwriteWhenFull: z.ZodNullable<z.ZodBoolean>;
604
+ }, z.core.$strip>>;
605
+ primaryTrackId: z.ZodNullable<z.ZodString>;
606
+ enabled: z.ZodNullable<z.ZodBoolean>;
607
+ overwriteWhenFull: z.ZodNullable<z.ZodBoolean>;
608
+ preRecordSec: z.ZodNullable<z.ZodNumber>;
609
+ postRecordSec: z.ZodNullable<z.ZodNumber>;
610
+ segmentMinutes: z.ZodNullable<z.ZodNumber>;
611
+ windows: z.ZodArray<z.ZodObject<{
612
+ trigger: z.ZodEnum<{
613
+ person: "person";
614
+ vehicle: "vehicle";
615
+ animal: "animal";
616
+ motion: "motion";
617
+ loitering: "loitering";
618
+ continuous: "continuous";
619
+ lineCrossing: "lineCrossing";
620
+ intrusion: "intrusion";
621
+ alarmInput: "alarmInput";
622
+ }>;
623
+ day: z.ZodNumber;
624
+ startMinute: z.ZodNumber;
625
+ endMinute: z.ZodNumber;
626
+ }, z.core.$strip>>;
627
+ unreadableWindows: z.ZodNumber;
628
+ recordingToNowhere: z.ZodBoolean;
629
+ lastFetchedAt: z.ZodNumber;
630
+ }, z.core.$strip>;
631
+ readonly kind: "poll";
632
+ };
633
+ readonly runtimeState: z.ZodObject<{
634
+ storage: z.ZodDiscriminatedUnion<[z.ZodObject<{
635
+ kind: z.ZodLiteral<"present">;
636
+ volumes: z.ZodArray<z.ZodObject<{
637
+ id: z.ZodString;
638
+ label: z.ZodOptional<z.ZodString>;
639
+ status: z.ZodEnum<{
640
+ unknown: "unknown";
641
+ error: "error";
642
+ ok: "ok";
643
+ offline: "offline";
644
+ unformatted: "unformatted";
645
+ }>;
646
+ capacityMb: z.ZodNullable<z.ZodNumber>;
647
+ freeMb: z.ZodNullable<z.ZodNumber>;
648
+ writable: z.ZodOptional<z.ZodBoolean>;
649
+ }, z.core.$strip>>;
650
+ }, z.core.$strip>, z.ZodObject<{
651
+ kind: z.ZodLiteral<"absent">;
652
+ reason: z.ZodString;
653
+ }, z.core.$strip>, z.ZodObject<{
654
+ kind: z.ZodLiteral<"unknown">;
655
+ reason: z.ZodString;
656
+ }, z.core.$strip>], "kind">;
657
+ tracks: z.ZodArray<z.ZodObject<{
658
+ id: z.ZodString;
659
+ enabled: z.ZodBoolean;
660
+ isVideo: z.ZodBoolean;
661
+ codec: z.ZodNullable<z.ZodString>;
662
+ resolution: z.ZodNullable<z.ZodString>;
663
+ overwriteWhenFull: z.ZodNullable<z.ZodBoolean>;
664
+ }, z.core.$strip>>;
665
+ primaryTrackId: z.ZodNullable<z.ZodString>;
666
+ enabled: z.ZodNullable<z.ZodBoolean>;
667
+ overwriteWhenFull: z.ZodNullable<z.ZodBoolean>;
668
+ preRecordSec: z.ZodNullable<z.ZodNumber>;
669
+ postRecordSec: z.ZodNullable<z.ZodNumber>;
670
+ segmentMinutes: z.ZodNullable<z.ZodNumber>;
671
+ windows: z.ZodArray<z.ZodObject<{
672
+ trigger: z.ZodEnum<{
673
+ person: "person";
674
+ vehicle: "vehicle";
675
+ animal: "animal";
676
+ motion: "motion";
677
+ loitering: "loitering";
678
+ continuous: "continuous";
679
+ lineCrossing: "lineCrossing";
680
+ intrusion: "intrusion";
681
+ alarmInput: "alarmInput";
682
+ }>;
683
+ day: z.ZodNumber;
684
+ startMinute: z.ZodNumber;
685
+ endMinute: z.ZodNumber;
686
+ }, z.core.$strip>>;
687
+ unreadableWindows: z.ZodNumber;
688
+ recordingToNowhere: z.ZodBoolean;
689
+ lastFetchedAt: z.ZodNumber;
690
+ }, z.core.$strip>;
691
+ /**
692
+ * Runtime-state durability: **restored** — operator-set camera-side
693
+ * recording config; mutation-driven, and the storage half is the last
694
+ * thing the camera said about its own card.
695
+ *
696
+ * See `RuntimeStateDurability`. Enforced by
697
+ * `scripts/check-runtime-state-durability.ts`.
698
+ */
699
+ readonly durability: "restored";
700
+ /** Clock fields: written, but excluded from the compare that decides
701
+ * whether persisting is worth a SQLite commit. */
702
+ readonly volatileStateFields: readonly ["lastFetchedAt"];
703
+ };
704
+ export type IRecordingOnboardProvider = InferNativeProvider<typeof recordingOnboardCapability>;
705
+ export {};