@camstack/types 1.2.163 → 1.2.164

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.
@@ -32,6 +32,7 @@ export declare const MotionOnMotionChangedDataSchema: z.ZodObject<{
32
32
  source: z.ZodEnum<{
33
33
  onboard: "onboard";
34
34
  analyzer: "analyzer";
35
+ "device-activity": "device-activity";
35
36
  }>;
36
37
  regions: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
37
38
  bbox: z.ZodObject<{
@@ -96,6 +97,7 @@ export declare const motionCapability: {
96
97
  source: z.ZodEnum<{
97
98
  onboard: "onboard";
98
99
  analyzer: "analyzer";
100
+ "device-activity": "device-activity";
99
101
  }>;
100
102
  regions: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
101
103
  bbox: z.ZodObject<{
@@ -93,10 +93,24 @@ export type StatelessStepRefusal = z.infer<typeof StatelessStepRefusalSchema>;
93
93
  * (analyzer attaches detected `regions[]`; onboard does not — the
94
94
  * camera typically only reports a binary signal plus an optional
95
95
  * channel/AI class which lives in dedicated event channels).
96
+ *
97
+ * - `onboard` — the camera's firmware said something moved.
98
+ * - `analyzer` — this runner's frame-diff said so, and attaches `regions[]`.
99
+ * - `device-activity` — the DEVICE said it is doing its job: the
100
+ * `recording-signal` LEVEL the same device raises for the recorder
101
+ * ([D380](../../../../docs/decisions/adr-0380-a-device-decided-recording-is-a-mode-with-no-schedule-seeded-once.md)),
102
+ * republished as a motion source. It attaches **nothing** — no regions, no
103
+ * class: the only fact it carries is that the device is active, and a robot
104
+ * vacuum that is itself the moving object has no region worth sending. It is
105
+ * a LEVEL, so unlike `onboard` it has a real falling edge, and unlike
106
+ * `analyzer` it must not open the frame-diff side-channel — the runner's
107
+ * `handleOnboardMotionAnalyzer` gate is `source === 'onboard'` and stays that
108
+ * way ([D392](../../../../docs/decisions/adr-0392-a-device-that-says-it-is-working-is-a-motion-source-of-its-own.md)).
96
109
  */
97
110
  export declare const MotionSourceEnum: z.ZodEnum<{
98
111
  onboard: "onboard";
99
112
  analyzer: "analyzer";
113
+ "device-activity": "device-activity";
100
114
  }>;
101
115
  export type MotionSource = z.infer<typeof MotionSourceEnum>;
102
116
  /**
@@ -116,6 +130,7 @@ export type MotionSource = z.infer<typeof MotionSourceEnum>;
116
130
  export declare const MotionSourcesSchema: z.ZodArray<z.ZodEnum<{
117
131
  onboard: "onboard";
118
132
  analyzer: "analyzer";
133
+ "device-activity": "device-activity";
119
134
  }>>;
120
135
  export type MotionSources = z.infer<typeof MotionSourcesSchema>;
121
136
  /**
@@ -130,6 +145,7 @@ export declare const ReportMotionInputSchema: z.ZodObject<{
130
145
  source: z.ZodDefault<z.ZodEnum<{
131
146
  onboard: "onboard";
132
147
  analyzer: "analyzer";
148
+ "device-activity": "device-activity";
133
149
  }>>;
134
150
  regions: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
135
151
  bbox: z.ZodObject<{
@@ -218,6 +234,7 @@ declare const RunnerCameraConfigSchema: z.ZodObject<{
218
234
  motionSources: z.ZodDefault<z.ZodArray<z.ZodEnum<{
219
235
  onboard: "onboard";
220
236
  analyzer: "analyzer";
237
+ "device-activity": "device-activity";
221
238
  }>>>;
222
239
  pipelineEnabled: z.ZodDefault<z.ZodBoolean>;
223
240
  steps: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodType<import("./pipeline-executor.cap.js").PipelineStepInputOutput, unknown, z.core.$ZodTypeInternals<import("./pipeline-executor.cap.js").PipelineStepInputOutput, unknown>>>>>;
@@ -477,6 +494,7 @@ export declare const pipelineRunnerCapability: {
477
494
  motionSources: z.ZodDefault<z.ZodArray<z.ZodEnum<{
478
495
  onboard: "onboard";
479
496
  analyzer: "analyzer";
497
+ "device-activity": "device-activity";
480
498
  }>>>;
481
499
  pipelineEnabled: z.ZodDefault<z.ZodBoolean>;
482
500
  steps: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodType<import("./pipeline-executor.cap.js").PipelineStepInputOutput, unknown, z.core.$ZodTypeInternals<import("./pipeline-executor.cap.js").PipelineStepInputOutput, unknown>>>>>;
@@ -545,6 +563,7 @@ export declare const pipelineRunnerCapability: {
545
563
  source: z.ZodDefault<z.ZodEnum<{
546
564
  onboard: "onboard";
547
565
  analyzer: "analyzer";
566
+ "device-activity": "device-activity";
548
567
  }>>;
549
568
  regions: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
550
569
  bbox: z.ZodObject<{
@@ -105,7 +105,7 @@ export interface DeviceProfileDefaults {
105
105
  * explicitly to enable SW motion). PIR-sourced motion currently
106
106
  * flows through `'onboard'` because Reolink's accessory PIRs feed
107
107
  * the parent camera's firmware motion event channel. */
108
- readonly motionSources?: readonly ('onboard' | 'analyzer')[];
108
+ readonly motionSources?: import('../capabilities/pipeline-runner.cap.js').MotionSources;
109
109
  readonly audioMode?: PipelinePhaseMode;
110
110
  readonly detectionMode?: PipelinePhaseMode;
111
111
  }
package/dist/index.js CHANGED
@@ -20939,8 +20939,25 @@ var occupancyRecheckFramesField = {
20939
20939
  * (analyzer attaches detected `regions[]`; onboard does not — the
20940
20940
  * camera typically only reports a binary signal plus an optional
20941
20941
  * channel/AI class which lives in dedicated event channels).
20942
- */
20943
- var MotionSourceEnum = zod.z.enum(["onboard", "analyzer"]);
20942
+ *
20943
+ * - `onboard` — the camera's firmware said something moved.
20944
+ * - `analyzer` — this runner's frame-diff said so, and attaches `regions[]`.
20945
+ * - `device-activity` — the DEVICE said it is doing its job: the
20946
+ * `recording-signal` LEVEL the same device raises for the recorder
20947
+ * ([D380](../../../../docs/decisions/adr-0380-a-device-decided-recording-is-a-mode-with-no-schedule-seeded-once.md)),
20948
+ * republished as a motion source. It attaches **nothing** — no regions, no
20949
+ * class: the only fact it carries is that the device is active, and a robot
20950
+ * vacuum that is itself the moving object has no region worth sending. It is
20951
+ * a LEVEL, so unlike `onboard` it has a real falling edge, and unlike
20952
+ * `analyzer` it must not open the frame-diff side-channel — the runner's
20953
+ * `handleOnboardMotionAnalyzer` gate is `source === 'onboard'` and stays that
20954
+ * way ([D392](../../../../docs/decisions/adr-0392-a-device-that-says-it-is-working-is-a-motion-source-of-its-own.md)).
20955
+ */
20956
+ var MotionSourceEnum = zod.z.enum([
20957
+ "onboard",
20958
+ "analyzer",
20959
+ "device-activity"
20960
+ ]);
20944
20961
  /**
20945
20962
  * List of motion sources active on a camera. Empty array is valid:
20946
20963
  * "no source" — happens for battery cams without firmware motion when
@@ -21204,13 +21221,20 @@ var RunnerCameraDeviceUIFields = [
21204
21221
  type: "multiselect",
21205
21222
  label: "Motion Sources",
21206
21223
  default: ["analyzer"],
21207
- options: [{
21208
- value: "analyzer",
21209
- label: "Frame-diff Analyzer (motion addon)"
21210
- }, {
21211
- value: "onboard",
21212
- label: "Camera Onboard Sensor"
21213
- }]
21224
+ options: [
21225
+ {
21226
+ value: "analyzer",
21227
+ label: "Frame-diff Analyzer (motion addon)"
21228
+ },
21229
+ {
21230
+ value: "onboard",
21231
+ label: "Camera Onboard Sensor"
21232
+ },
21233
+ {
21234
+ value: "device-activity",
21235
+ label: "Device activity (the device says it is working)"
21236
+ }
21237
+ ]
21214
21238
  },
21215
21239
  {
21216
21240
  key: "motionFps",
package/dist/index.mjs CHANGED
@@ -20938,8 +20938,25 @@ var occupancyRecheckFramesField = {
20938
20938
  * (analyzer attaches detected `regions[]`; onboard does not — the
20939
20939
  * camera typically only reports a binary signal plus an optional
20940
20940
  * channel/AI class which lives in dedicated event channels).
20941
- */
20942
- var MotionSourceEnum = z.enum(["onboard", "analyzer"]);
20941
+ *
20942
+ * - `onboard` — the camera's firmware said something moved.
20943
+ * - `analyzer` — this runner's frame-diff said so, and attaches `regions[]`.
20944
+ * - `device-activity` — the DEVICE said it is doing its job: the
20945
+ * `recording-signal` LEVEL the same device raises for the recorder
20946
+ * ([D380](../../../../docs/decisions/adr-0380-a-device-decided-recording-is-a-mode-with-no-schedule-seeded-once.md)),
20947
+ * republished as a motion source. It attaches **nothing** — no regions, no
20948
+ * class: the only fact it carries is that the device is active, and a robot
20949
+ * vacuum that is itself the moving object has no region worth sending. It is
20950
+ * a LEVEL, so unlike `onboard` it has a real falling edge, and unlike
20951
+ * `analyzer` it must not open the frame-diff side-channel — the runner's
20952
+ * `handleOnboardMotionAnalyzer` gate is `source === 'onboard'` and stays that
20953
+ * way ([D392](../../../../docs/decisions/adr-0392-a-device-that-says-it-is-working-is-a-motion-source-of-its-own.md)).
20954
+ */
20955
+ var MotionSourceEnum = z.enum([
20956
+ "onboard",
20957
+ "analyzer",
20958
+ "device-activity"
20959
+ ]);
20943
20960
  /**
20944
20961
  * List of motion sources active on a camera. Empty array is valid:
20945
20962
  * "no source" — happens for battery cams without firmware motion when
@@ -21203,13 +21220,20 @@ var RunnerCameraDeviceUIFields = [
21203
21220
  type: "multiselect",
21204
21221
  label: "Motion Sources",
21205
21222
  default: ["analyzer"],
21206
- options: [{
21207
- value: "analyzer",
21208
- label: "Frame-diff Analyzer (motion addon)"
21209
- }, {
21210
- value: "onboard",
21211
- label: "Camera Onboard Sensor"
21212
- }]
21223
+ options: [
21224
+ {
21225
+ value: "analyzer",
21226
+ label: "Frame-diff Analyzer (motion addon)"
21227
+ },
21228
+ {
21229
+ value: "onboard",
21230
+ label: "Camera Onboard Sensor"
21231
+ },
21232
+ {
21233
+ value: "device-activity",
21234
+ label: "Device activity (the device says it is working)"
21235
+ }
21236
+ ]
21213
21237
  },
21214
21238
  {
21215
21239
  key: "motionFps",
@@ -409,8 +409,10 @@ export interface PhaseTransitionPayload {
409
409
  from: 'watching' | 'active';
410
410
  to: 'watching' | 'active';
411
411
  reason: 'motion_detected' | 'cooldown_expired';
412
- /** Motion source that armed the cooldown — present on both ON and OFF. */
413
- source?: 'onboard' | 'analyzer';
412
+ /** Motion source that armed the cooldown — present on both ON and OFF.
413
+ * The enum itself, never a hand-copied union: this was a second list of
414
+ * the sources and it silently excluded every variant added after it. */
415
+ source?: import('../capabilities/pipeline-runner.cap.js').MotionSource;
414
416
  /** Cooldown window in ms that was/is active for this transition. */
415
417
  cooldownMs?: number;
416
418
  /** Ms epoch of the transition. */
@@ -395,6 +395,21 @@ export interface CameraDetectionConfig {
395
395
  readonly detectionStreamId: string;
396
396
  readonly motionFps: number;
397
397
  readonly detectionFps: number;
398
+ /**
399
+ * The detection rate a session opened by the `device-activity` source is
400
+ * capped to (D392). A device-activity session is LONG — a cleaning run is
401
+ * tens of minutes of continuous activity — so it is analysed at a rate that
402
+ * can be sustained for that long, while a session any other trigger opens
403
+ * keeps `detectionFps`. Resolved by the orchestrator and applied at dispatch
404
+ * (`detectionFpsForTrigger`), so what reaches a runner is still a plain
405
+ * `detectionFps` and no runner needs to know this field exists.
406
+ *
407
+ * OPTIONAL because this config is built at several sites, not all of which
408
+ * resolve the device store. Absent means "not resolved here" and the cap
409
+ * still applies at `ACTIVITY_DETECTION_FPS_DEFAULT` — the safe direction: a
410
+ * long session runs slow rather than at full rate for an hour.
411
+ */
412
+ readonly activityDetectionFps?: number;
398
413
  readonly motionCooldownMs: number;
399
414
  /**
400
415
  * Orchestrator on-motion session-hold cap (ms). While the session is active
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.163",
3
+ "version": "1.2.164",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",