@trillboards/edge-sdk 0.2.3 → 0.2.6
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.
- package/README.md +4 -3
- package/deploy/docker/Dockerfile.cloud-sense +117 -0
- package/deploy/docker/Dockerfile.cpu +30 -21
- package/deploy/docker/Dockerfile.cuda +30 -21
- package/deploy/docker/Dockerfile.openvino +30 -20
- package/deploy/docker/README.md +9 -4
- package/deploy/docker/connector-entrypoint.sh +122 -0
- package/deploy/helm/README.md +1 -1
- package/deploy/k8s/daemonset.yaml +1 -1
- package/deploy/macos/README.md +161 -0
- package/deploy/macos/TrillboardsSetupApp.m +603 -0
- package/deploy/macos/build-macos-pkg.sh +588 -0
- package/deploy/macos/com.trillboards.edge.plist +62 -0
- package/deploy/macos/com.trillboards.litertlm.plist +45 -0
- package/deploy/macos/pair.command +519 -0
- package/deploy/macos/scripts/ensure-litertlm.sh +62 -0
- package/deploy/macos/scripts/postinstall +153 -0
- package/deploy/macos/scripts/setup-litertlm.sh +272 -0
- package/deploy/macos/test-install-pair.sh +383 -0
- package/deploy/macos/test-setup-litertlm-reinstall.sh +109 -0
- package/deploy/systemd/install.sh +25 -15
- package/deploy/systemd/trillboards-edge.service +4 -1
- package/deploy/windows/README.md +70 -0
- package/deploy/windows/build-windows.ps1 +225 -0
- package/deploy/windows/bundle-windows-installer.ps1 +153 -0
- package/deploy/windows/check-feeds.js +26 -0
- package/deploy/windows/e2e/fixtures/person.jpg +0 -0
- package/deploy/windows/e2e/test-local-sense.ps1 +185 -0
- package/deploy/windows/install-update.ps1 +101 -0
- package/deploy/windows/installer.nsi +138 -0
- package/deploy/windows/register-litertlm-task.ps1 +42 -0
- package/deploy/windows/register-task.ps1 +44 -0
- package/deploy/windows/run-connector.ps1 +69 -0
- package/deploy/windows/setup-litertlm.ps1 +361 -0
- package/deploy/windows/stop-existing.ps1 +72 -0
- package/deploy/windows/trillboards-edge-task.vbs +25 -0
- package/deploy/windows/trillboards-edge.cmd +33 -0
- package/deploy/windows/trillboards-pair.cmd +276 -0
- package/deploy/windows/trillboards-setup.ps1 +456 -0
- package/deploy/windows/trillboards-setup.vbs +13 -0
- package/dist/AudienceAnalyzeClient.d.ts +136 -0
- package/dist/AudienceAnalyzeClient.d.ts.map +1 -0
- package/dist/AudienceAnalyzeClient.js +246 -0
- package/dist/AudienceAnalyzeClient.js.map +1 -0
- package/dist/ChannelProber.d.ts +150 -0
- package/dist/ChannelProber.d.ts.map +1 -0
- package/dist/ChannelProber.js +887 -0
- package/dist/ChannelProber.js.map +1 -0
- package/dist/CloudEscalationPolicy.d.ts +143 -0
- package/dist/CloudEscalationPolicy.d.ts.map +1 -0
- package/dist/CloudEscalationPolicy.js +137 -0
- package/dist/CloudEscalationPolicy.js.map +1 -0
- package/dist/CloudSensingManager.d.ts +533 -0
- package/dist/CloudSensingManager.d.ts.map +1 -0
- package/dist/CloudSensingManager.js +1254 -0
- package/dist/CloudSensingManager.js.map +1 -0
- package/dist/DiscoveryReportClient.d.ts +66 -0
- package/dist/DiscoveryReportClient.d.ts.map +1 -0
- package/dist/DiscoveryReportClient.js +85 -0
- package/dist/DiscoveryReportClient.js.map +1 -0
- package/dist/EdgeAgent.d.ts +12 -2
- package/dist/EdgeAgent.d.ts.map +1 -1
- package/dist/EdgeAgent.js +122 -65
- package/dist/EdgeAgent.js.map +1 -1
- package/dist/LiteRtVlmProvider.d.ts +193 -0
- package/dist/LiteRtVlmProvider.d.ts.map +1 -0
- package/dist/LiteRtVlmProvider.js +436 -0
- package/dist/LiteRtVlmProvider.js.map +1 -0
- package/dist/MosaicSource.d.ts +108 -0
- package/dist/MosaicSource.d.ts.map +1 -0
- package/dist/MosaicSource.js +274 -0
- package/dist/MosaicSource.js.map +1 -0
- package/dist/OnvifClient.d.ts +83 -0
- package/dist/OnvifClient.d.ts.map +1 -0
- package/dist/OnvifClient.js +209 -0
- package/dist/OnvifClient.js.map +1 -0
- package/dist/PairClient.d.ts +106 -0
- package/dist/PairClient.d.ts.map +1 -0
- package/dist/PairClient.js +186 -0
- package/dist/PairClient.js.map +1 -0
- package/dist/RecorderAddressRecovery.d.ts +53 -0
- package/dist/RecorderAddressRecovery.d.ts.map +1 -0
- package/dist/RecorderAddressRecovery.js +359 -0
- package/dist/RecorderAddressRecovery.js.map +1 -0
- package/dist/SceneChangeDetector.d.ts +291 -0
- package/dist/SceneChangeDetector.d.ts.map +1 -0
- package/dist/SceneChangeDetector.js +682 -0
- package/dist/SceneChangeDetector.js.map +1 -0
- package/dist/SensingProfileClient.d.ts +59 -0
- package/dist/SensingProfileClient.d.ts.map +1 -0
- package/dist/SensingProfileClient.js +78 -0
- package/dist/SensingProfileClient.js.map +1 -0
- package/dist/SetupSessionClient.d.ts +114 -0
- package/dist/SetupSessionClient.d.ts.map +1 -0
- package/dist/SetupSessionClient.js +95 -0
- package/dist/SetupSessionClient.js.map +1 -0
- package/dist/VlmAdmissionGate.d.ts +126 -0
- package/dist/VlmAdmissionGate.d.ts.map +1 -0
- package/dist/VlmAdmissionGate.js +166 -0
- package/dist/VlmAdmissionGate.js.map +1 -0
- package/dist/autoSense.d.ts +216 -0
- package/dist/autoSense.d.ts.map +1 -0
- package/dist/autoSense.js +521 -0
- package/dist/autoSense.js.map +1 -0
- package/dist/cli.d.ts +27 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +511 -21
- package/dist/cli.js.map +1 -1
- package/dist/combinedSense.d.ts +128 -0
- package/dist/combinedSense.d.ts.map +1 -0
- package/dist/combinedSense.js +261 -0
- package/dist/combinedSense.js.map +1 -0
- package/dist/config.d.ts +351 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +99 -2
- package/dist/config.js.map +1 -1
- package/dist/connectorCadence.d.ts +135 -0
- package/dist/connectorCadence.d.ts.map +1 -0
- package/dist/connectorCadence.js +151 -0
- package/dist/connectorCadence.js.map +1 -0
- package/dist/dataDir.d.ts +33 -0
- package/dist/dataDir.d.ts.map +1 -0
- package/dist/dataDir.js +76 -0
- package/dist/dataDir.js.map +1 -0
- package/dist/deployedCadence.d.ts +167 -0
- package/dist/deployedCadence.d.ts.map +1 -0
- package/dist/deployedCadence.js +209 -0
- package/dist/deployedCadence.js.map +1 -0
- package/dist/deployedCadenceSource.d.ts +48 -0
- package/dist/deployedCadenceSource.d.ts.map +1 -0
- package/dist/deployedCadenceSource.js +74 -0
- package/dist/deployedCadenceSource.js.map +1 -0
- package/dist/diagnose.d.ts +1 -1
- package/dist/diagnose.d.ts.map +1 -1
- package/dist/diagnose.js +13 -12
- package/dist/diagnose.js.map +1 -1
- package/dist/discovery.d.ts +131 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +499 -0
- package/dist/discovery.js.map +1 -0
- package/dist/gemmaModelOta.d.ts +118 -0
- package/dist/gemmaModelOta.d.ts.map +1 -0
- package/dist/gemmaModelOta.js +291 -0
- package/dist/gemmaModelOta.js.map +1 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -1
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +41 -18
- package/dist/init.js.map +1 -1
- package/dist/keepAwake.d.ts +33 -0
- package/dist/keepAwake.d.ts.map +1 -0
- package/dist/keepAwake.js +54 -0
- package/dist/keepAwake.js.map +1 -0
- package/dist/legacyRecorderProfile.d.ts +20 -0
- package/dist/legacyRecorderProfile.d.ts.map +1 -0
- package/dist/legacyRecorderProfile.js +27 -0
- package/dist/legacyRecorderProfile.js.map +1 -0
- package/dist/localInferenceSchema.d.ts +132 -0
- package/dist/localInferenceSchema.d.ts.map +1 -0
- package/dist/localInferenceSchema.js +274 -0
- package/dist/localInferenceSchema.js.map +1 -0
- package/dist/localSenseE2eHarness.d.ts +101 -0
- package/dist/localSenseE2eHarness.d.ts.map +1 -0
- package/dist/localSenseE2eHarness.js +279 -0
- package/dist/localSenseE2eHarness.js.map +1 -0
- package/dist/localSensing.d.ts +268 -0
- package/dist/localSensing.d.ts.map +1 -0
- package/dist/localSensing.js +492 -0
- package/dist/localSensing.js.map +1 -0
- package/dist/modelIntegrity.d.ts +59 -0
- package/dist/modelIntegrity.d.ts.map +1 -0
- package/dist/modelIntegrity.js +165 -0
- package/dist/modelIntegrity.js.map +1 -0
- package/dist/pairVerify.d.ts +100 -0
- package/dist/pairVerify.d.ts.map +1 -0
- package/dist/pairVerify.js +296 -0
- package/dist/pairVerify.js.map +1 -0
- package/dist/qrScanner.d.ts +33 -0
- package/dist/qrScanner.d.ts.map +1 -0
- package/dist/qrScanner.js +103 -0
- package/dist/qrScanner.js.map +1 -0
- package/dist/runtimePaths.d.ts +10 -0
- package/dist/runtimePaths.d.ts.map +1 -0
- package/dist/runtimePaths.js +79 -0
- package/dist/runtimePaths.js.map +1 -0
- package/dist/sensingRunMode.d.ts +68 -0
- package/dist/sensingRunMode.d.ts.map +1 -0
- package/dist/sensingRunMode.js +346 -0
- package/dist/sensingRunMode.js.map +1 -0
- package/dist/setupMode.d.ts +98 -0
- package/dist/setupMode.d.ts.map +1 -0
- package/dist/setupMode.js +828 -0
- package/dist/setupMode.js.map +1 -0
- package/dist/setupProgress.d.ts +31 -0
- package/dist/setupProgress.d.ts.map +1 -0
- package/dist/setupProgress.js +173 -0
- package/dist/setupProgress.js.map +1 -0
- package/package.json +13 -4
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import type { CameraProvider } from '@trillboards/edge-core';
|
|
3
|
+
import { AudienceAnalyzeClient, type AudienceAnalyzeResponse, type CameraHealthFailureClass, type CameraHealthReport, type HttpPoster } from './AudienceAnalyzeClient';
|
|
4
|
+
import { SharedFrameSource } from './MosaicSource';
|
|
5
|
+
import type { EdgeAgentConfig, MosaicTile, RecorderIdentity } from './config';
|
|
6
|
+
import { type VlmAdmissionStats } from './VlmAdmissionGate';
|
|
7
|
+
import { type MotionGateOptions } from './SceneChangeDetector';
|
|
8
|
+
import type { DeployedCadence } from './deployedCadence';
|
|
9
|
+
export declare function classifyRtspFailureClass(err: unknown): CameraHealthFailureClass;
|
|
10
|
+
/**
|
|
11
|
+
* The subset of AudienceAnalyzeClient the cadence loop needs. A local-inference
|
|
12
|
+
* client (LocalSensingClient — see localSensing.ts) substitutes here to run the
|
|
13
|
+
* VLM ON-DEVICE and POST the structured result as `preAnalyzed`, so the manager
|
|
14
|
+
* runs UNCHANGED for both the cloud and local paths.
|
|
15
|
+
*/
|
|
16
|
+
export interface SensingClient {
|
|
17
|
+
analyze(request: {
|
|
18
|
+
jpeg: Buffer;
|
|
19
|
+
captureMode?: string;
|
|
20
|
+
}): Promise<AudienceAnalyzeResponse>;
|
|
21
|
+
reportCameraHealth?(cameraHealth: CameraHealthReport): Promise<AudienceAnalyzeResponse>;
|
|
22
|
+
getEndpoint(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Cloud escalations this client has made (LocalSensingClient only). Optional
|
|
25
|
+
* so the plain cloud client — which has nothing to escalate TO — implements
|
|
26
|
+
* nothing. Aggregated into `getSensingHealth()` because a frame leaving the
|
|
27
|
+
* premises has to be countable by the operator, not just documented.
|
|
28
|
+
*/
|
|
29
|
+
getEscalationStats?(): {
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
escalated: number;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** A camera + its dedicated sensing client (one feed = one token). */
|
|
35
|
+
export interface SensingLoopDeps {
|
|
36
|
+
/** Label for logs/stats (defaults to the feed name or screenId). */
|
|
37
|
+
name: string;
|
|
38
|
+
camera: CameraProvider;
|
|
39
|
+
client: SensingClient;
|
|
40
|
+
}
|
|
41
|
+
export interface CloudSensingManagerOptions {
|
|
42
|
+
/** Per-feed capture loops. */
|
|
43
|
+
loops: SensingLoopDeps[];
|
|
44
|
+
/** Capture interval (ms) when NO faces. Default: 300000. */
|
|
45
|
+
periodicIntervalMs?: number;
|
|
46
|
+
/** Capture interval (ms) when faces ARE detected. Default: 30000. */
|
|
47
|
+
faceTriggeredIntervalMs?: number;
|
|
48
|
+
/** JPEG quality for the POSTed frame. Default: 70. */
|
|
49
|
+
jpegQuality?: number;
|
|
50
|
+
/** Skip the POST when no faces (still captures periodically). Default: true. */
|
|
51
|
+
skipPostWhenNoFaces?: boolean;
|
|
52
|
+
/** Frame width (for raw RGB24 → JPEG encoding). */
|
|
53
|
+
width?: number;
|
|
54
|
+
/** Frame height (for raw RGB24 → JPEG encoding). */
|
|
55
|
+
height?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Initial delay (ms) before the first RTSP re-open attempt after a drop.
|
|
58
|
+
* Doubles each consecutive failure up to `reconnectMaxDelayMs`, then holds at
|
|
59
|
+
* the cap and retries FOREVER. Default: 1000. The connector self-recovers when
|
|
60
|
+
* the camera/feed comes back; it never permanently gives up.
|
|
61
|
+
*/
|
|
62
|
+
reconnectInitialDelayMs?: number;
|
|
63
|
+
/** Cap (ms) for the exponential reconnect backoff. Default: 30000. */
|
|
64
|
+
reconnectMaxDelayMs?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Additional per-feed phase offset (ms) added by loop index when multiple
|
|
67
|
+
* cameras run in one connector. Default: 1000 for multi-feed, 0 for single.
|
|
68
|
+
*/
|
|
69
|
+
feedStaggerMs?: number;
|
|
70
|
+
/** Cap for the computed per-feed phase offset. Default: 15000. */
|
|
71
|
+
maxFeedStaggerMs?: number;
|
|
72
|
+
/**
|
|
73
|
+
* Consecutive non-auth RTSP failures tolerated before reporting failed
|
|
74
|
+
* camera health. Auth failures still report immediately. Default: 3.
|
|
75
|
+
*/
|
|
76
|
+
cameraHealthFailureGraceCount?: number;
|
|
77
|
+
/**
|
|
78
|
+
* Decode-only camera probe cadence while every inference slot is busy.
|
|
79
|
+
* This keeps video liveness independent from AI throughput without opening
|
|
80
|
+
* a second persistent RTSP session. Default: 120000.
|
|
81
|
+
*/
|
|
82
|
+
cameraHealthProbeIntervalMs?: number;
|
|
83
|
+
/** Maximum gap between connector/sensing status beacons. Default: 60000. */
|
|
84
|
+
cameraHealthHeartbeatIntervalMs?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Concurrent analyze() calls allowed across ALL feeds in this process — the
|
|
87
|
+
* global admission gate. Default: one slot per loop (i.e. today's unbounded
|
|
88
|
+
* fan-out), so the cloud path, whose backend really is concurrent, is
|
|
89
|
+
* unchanged. LOCAL sensing MUST set this to 1: `litert-lm serve` is a
|
|
90
|
+
* single-conversation server and 16 free-running loops oversubscribe it ~17x.
|
|
91
|
+
*/
|
|
92
|
+
maxConcurrentAnalyses?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Reclaim an admission slot held longer than this (ms). Default 180000 — the
|
|
95
|
+
* provider's 120 s HTTP timeout plus retry headroom. Guards a 24/7 connector
|
|
96
|
+
* against one lost promise wedging every camera forever.
|
|
97
|
+
*/
|
|
98
|
+
maxAnalysisInFlightMs?: number;
|
|
99
|
+
/**
|
|
100
|
+
* Delay (ms) before a tick the admission gate denied tries again. Default:
|
|
101
|
+
* the derived stagger step, clamped to 250…5000. Short on purpose — the loop
|
|
102
|
+
* dropped its frame, so this is a cheap poll for a freed slot, not a queue.
|
|
103
|
+
*/
|
|
104
|
+
admissionRetryDelayMs?: number;
|
|
105
|
+
/**
|
|
106
|
+
* Cheap motion cascade in front of the model. Omitted ⇒ disabled and every
|
|
107
|
+
* captured frame is analyzed (today's behavior). `heartbeatIntervalMs`
|
|
108
|
+
* defaults to `periodicIntervalMs` and `minAnalyzeIntervalMs` to
|
|
109
|
+
* `faceTriggeredIntervalMs`, so the analyze rate stays inside the cadence
|
|
110
|
+
* band the config already declares — the gate can only REMOVE calls.
|
|
111
|
+
*/
|
|
112
|
+
motionGate?: Partial<MotionGateOptions> & {
|
|
113
|
+
enabled?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* How often a STILL feed takes a look (ms) once the cascade is on.
|
|
116
|
+
* Defaults to `faceTriggeredIntervalMs`. Looking is the cheap half — an
|
|
117
|
+
* RTSP grab plus a few ms of motion — so it runs at the responsive
|
|
118
|
+
* cadence while `periodicIntervalMs` becomes the gate's heartbeat: the
|
|
119
|
+
* guaranteed reporting floor for a scene where genuinely nothing happens.
|
|
120
|
+
*/
|
|
121
|
+
scanIntervalMs?: number;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Let the motion verdict drive the periodic/face-triggered cadence switch —
|
|
125
|
+
* finally supplying the `setFaceDetected` signal this loop was always
|
|
126
|
+
* documented to consume. Default: true whenever `motionGate` is enabled.
|
|
127
|
+
*/
|
|
128
|
+
motionDrivesCadence?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Where this connector learns the cadence its OPERATOR deployed. Polled every
|
|
131
|
+
* `cadenceRefreshIntervalMs`; a null answer leaves the current cadence alone.
|
|
132
|
+
* Omitted ⇒ the cadence is whatever the config said at construction, which is
|
|
133
|
+
* the behavior every connector had before this existed.
|
|
134
|
+
*/
|
|
135
|
+
cadenceSource?: CadenceSource;
|
|
136
|
+
/** How often to ask `cadenceSource`. Default 300000 (the profile TTL). */
|
|
137
|
+
cadenceRefreshIntervalMs?: number;
|
|
138
|
+
/** Clock injection for tests. Default `Date.now`. */
|
|
139
|
+
now?: () => number;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The connector's link to the cadence its operator actually deployed.
|
|
143
|
+
*
|
|
144
|
+
* `resolve()` returns the FULL verdict rather than a number so the clamp — and,
|
|
145
|
+
* on the cloud path, the bill the operator is being protected from — stays
|
|
146
|
+
* legible in `getSensingHealth()` instead of being silently applied.
|
|
147
|
+
*/
|
|
148
|
+
export interface CadenceSource {
|
|
149
|
+
resolve(): Promise<DeployedCadence | null>;
|
|
150
|
+
}
|
|
151
|
+
export declare class CloudSensingManager extends EventEmitter {
|
|
152
|
+
private readonly loops;
|
|
153
|
+
/**
|
|
154
|
+
* NOT readonly: the deployed profile's cadence must be able to reach a
|
|
155
|
+
* RUNNING connector. Until this changed, the interval was frozen at
|
|
156
|
+
* construction and the only way to alter a venue's cadence was to edit
|
|
157
|
+
* trillboards.config.json on their machine and restart the process — while
|
|
158
|
+
* the server was already serving the operator's chosen value every 5 minutes
|
|
159
|
+
* to a client that discarded it. See setPeriodicIntervalMs + deployedCadence.
|
|
160
|
+
*/
|
|
161
|
+
private periodicIntervalMs;
|
|
162
|
+
/** The last cadence verdict applied, surfaced by getSensingHealth(). */
|
|
163
|
+
private cadence;
|
|
164
|
+
private readonly cadenceSource?;
|
|
165
|
+
private readonly cadenceRefreshIntervalMs;
|
|
166
|
+
private cadenceTimer;
|
|
167
|
+
private readonly faceTriggeredIntervalMs;
|
|
168
|
+
private readonly jpegQuality;
|
|
169
|
+
private readonly skipPostWhenNoFaces;
|
|
170
|
+
private readonly width?;
|
|
171
|
+
private readonly height?;
|
|
172
|
+
private readonly reconnectInitialDelayMs;
|
|
173
|
+
private readonly reconnectMaxDelayMs;
|
|
174
|
+
private readonly feedStaggerMs;
|
|
175
|
+
private readonly maxFeedStaggerMs;
|
|
176
|
+
private readonly cameraHealthFailureGraceCount;
|
|
177
|
+
private readonly cameraHealthProbeIntervalMs;
|
|
178
|
+
private readonly cameraHealthHeartbeatIntervalMs;
|
|
179
|
+
private readonly admissionGate;
|
|
180
|
+
private readonly admissionRetryDelayMs;
|
|
181
|
+
private readonly motionDrivesCadence;
|
|
182
|
+
/** Retained so a cadence change can rebuild each feed's gate heartbeat. */
|
|
183
|
+
private motionGateOptions;
|
|
184
|
+
/** Look-rate for a still feed when the cascade is on. null ⇒ cascade off. */
|
|
185
|
+
private motionScanIntervalMs;
|
|
186
|
+
private readonly now;
|
|
187
|
+
private running;
|
|
188
|
+
private startGeneration;
|
|
189
|
+
private runStartedAtMs;
|
|
190
|
+
/** One decode-only probe at a time protects recorder session limits. */
|
|
191
|
+
private healthCaptureInFlight;
|
|
192
|
+
constructor(options: CloudSensingManagerOptions);
|
|
193
|
+
/**
|
|
194
|
+
* Retune a RUNNING connector's still-scene cadence.
|
|
195
|
+
*
|
|
196
|
+
* Timers are NOT cancelled: each loop re-arms from `nextDelayFor` in its own
|
|
197
|
+
* `.finally`, so the new interval takes effect on the next tick. Cancelling
|
|
198
|
+
* and rescheduling here would collapse every feed's carefully-staggered phase
|
|
199
|
+
* onto the same instant — the multi-camera NVR stampede `staggerStepMs`
|
|
200
|
+
* exists to prevent — for no gain, since the worst-case lag is one old
|
|
201
|
+
* period.
|
|
202
|
+
*
|
|
203
|
+
* The motion gate's HEARTBEAT tracks the cadence, because the heartbeat IS
|
|
204
|
+
* the still-scene reporting floor: leaving it at the old value would let a
|
|
205
|
+
* gate keep reporting on a cadence the operator has replaced.
|
|
206
|
+
*
|
|
207
|
+
* The heartbeat is retuned IN PLACE (`MotionGate.setHeartbeatIntervalMs`) and
|
|
208
|
+
* NOT by rebuilding the gate. A fresh `MotionGate` is a fresh
|
|
209
|
+
* `SceneChangeDetector`: no background model, `calibrating` re-armed, the
|
|
210
|
+
* contrast ring un-seeded, the stationary signature forgotten and — the
|
|
211
|
+
* expensive one — `lastAnalyzedAtMs` back to null, which makes the very next
|
|
212
|
+
* look heartbeat-DUE and forces an inference on a scene the gate had already
|
|
213
|
+
* proven still. Measured: a byte-identical still frame costs 0 analyses over
|
|
214
|
+
* ten looks, then exactly +1 per feed the instant the cadence moves. On a
|
|
215
|
+
* 16-camera store that is 16 forced generations against the connector's single
|
|
216
|
+
* slot for a change that was meant to cost nothing. Rebuilding also swapped
|
|
217
|
+
* the object mid-tick, so a frame's `evaluate()` and its `markAnalyzed()`
|
|
218
|
+
* could land on two different gates.
|
|
219
|
+
*
|
|
220
|
+
* @returns true when the interval actually changed.
|
|
221
|
+
*/
|
|
222
|
+
setPeriodicIntervalMs(intervalMs: number): boolean;
|
|
223
|
+
/** The still-scene cadence currently in force. */
|
|
224
|
+
getPeriodicIntervalMs(): number;
|
|
225
|
+
/**
|
|
226
|
+
* Ask the cadence source what the operator deployed and apply it. Best-effort
|
|
227
|
+
* and never throws: a failed lookup leaves the running cadence untouched,
|
|
228
|
+
* because a connector that resets to a default every time the API blips is
|
|
229
|
+
* worse than one that is briefly stale.
|
|
230
|
+
*/
|
|
231
|
+
refreshDeployedCadence(): Promise<DeployedCadence | null>;
|
|
232
|
+
/** Number of independent capture loops (== number of feeds/tokens). */
|
|
233
|
+
getLoopCount(): number;
|
|
234
|
+
/** Per-loop stats (capture + POST counts, cadence, cascade drops). */
|
|
235
|
+
getStats(): Array<{
|
|
236
|
+
name: string;
|
|
237
|
+
captureCount: number;
|
|
238
|
+
postCount: number;
|
|
239
|
+
faceDetected: boolean;
|
|
240
|
+
currentIntervalMs: number;
|
|
241
|
+
admissionDeniedCount: number;
|
|
242
|
+
motionSkipCount: number;
|
|
243
|
+
}>;
|
|
244
|
+
/** Live admission-gate counters (admitted / dropped / stale-reclaimed). */
|
|
245
|
+
getAdmissionStats(): VlmAdmissionStats;
|
|
246
|
+
/**
|
|
247
|
+
* The operator-facing answer to "why is my 16-camera store only sampling
|
|
248
|
+
* every N seconds?" — sustained analyses/minute is what the machine can
|
|
249
|
+
* actually do, and `effectiveSampleIntervalMs` is what that buys each camera.
|
|
250
|
+
* Drops are attributed: `admissionDenied` means the backend is the ceiling,
|
|
251
|
+
* `motionSkipped` means the cascade decided the frame was not worth paying
|
|
252
|
+
* for. Both are wins over the old failure mode, where the surplus vanished
|
|
253
|
+
* into 120 s timeouts.
|
|
254
|
+
*/
|
|
255
|
+
getSensingHealth(): {
|
|
256
|
+
loops: number;
|
|
257
|
+
maxConcurrentAnalyses: number;
|
|
258
|
+
inFlight: number;
|
|
259
|
+
uptimeMs: number;
|
|
260
|
+
analyses: number;
|
|
261
|
+
analysesPerMinute: number;
|
|
262
|
+
effectiveSampleIntervalMs: number | null;
|
|
263
|
+
/** The still-scene cadence in force right now (a deployed profile can move it). */
|
|
264
|
+
periodicIntervalMs: number;
|
|
265
|
+
/**
|
|
266
|
+
* What the operator's deployed profile asked for, and what actually
|
|
267
|
+
* happened to it. null before the first successful lookup, or when this
|
|
268
|
+
* connector has no cadence source. The clamp is REPORTED rather than
|
|
269
|
+
* silently applied — an operator who set 30 s and is running 303 s has to
|
|
270
|
+
* be able to see both numbers and the reason.
|
|
271
|
+
*/
|
|
272
|
+
deployedCadence: DeployedCadence | null;
|
|
273
|
+
admissionDenied: number;
|
|
274
|
+
motionSkipped: number;
|
|
275
|
+
/**
|
|
276
|
+
* Frames sent to the cloud VLM for confirmation (local sensing with
|
|
277
|
+
* escalation enabled). 0 — and `cloudEscalationEnabled:false` — for a
|
|
278
|
+
* fully-local or cloud-sensing deployment.
|
|
279
|
+
*/
|
|
280
|
+
cloudEscalated: number;
|
|
281
|
+
cloudEscalationEnabled: boolean;
|
|
282
|
+
perFeed: Array<{
|
|
283
|
+
name: string;
|
|
284
|
+
captures: number;
|
|
285
|
+
analyses: number;
|
|
286
|
+
admissionDenied: number;
|
|
287
|
+
motionSkipped: number;
|
|
288
|
+
cloudEscalated: number;
|
|
289
|
+
faceDetected: boolean;
|
|
290
|
+
currentIntervalMs: number;
|
|
291
|
+
}>;
|
|
292
|
+
};
|
|
293
|
+
isRunning(): boolean;
|
|
294
|
+
/** Open cameras, prove one frame, and start capture loops without one slow feed blocking others. */
|
|
295
|
+
start(): Promise<void>;
|
|
296
|
+
/** Stop all loops and close cameras. */
|
|
297
|
+
stop(): Promise<void>;
|
|
298
|
+
/**
|
|
299
|
+
* Notify a loop (by feed name) that its face-detection state changed —
|
|
300
|
+
* switches that loop between the periodic and face-triggered cadence.
|
|
301
|
+
*/
|
|
302
|
+
setFaceDetected(loopName: string, detected: boolean): void;
|
|
303
|
+
/**
|
|
304
|
+
* Same cadence switch, but from INSIDE a running tick: record the new state
|
|
305
|
+
* and announce it WITHOUT rescheduling. The tick's own `finally` already
|
|
306
|
+
* calls scheduleNext and will read the updated interval — rescheduling here
|
|
307
|
+
* as well would leave the feed running two concurrent timers.
|
|
308
|
+
*/
|
|
309
|
+
private applyMotionCadence;
|
|
310
|
+
/**
|
|
311
|
+
* Capture + (conditionally) POST one frame for a given loop, immediately.
|
|
312
|
+
*
|
|
313
|
+
* Goes through the SAME cascade as a scheduled tick — an out-of-band capture
|
|
314
|
+
* that jumped the admission gate would break the very invariant the gate
|
|
315
|
+
* exists to hold. Returns `null` (rather than waiting) when the gate is
|
|
316
|
+
* closed or the motion stage judged the frame not worth an inference.
|
|
317
|
+
*/
|
|
318
|
+
captureNow(loopName: string): Promise<AudienceAnalyzeResponse | null>;
|
|
319
|
+
private isCurrentStart;
|
|
320
|
+
private startLoop;
|
|
321
|
+
private closeCameraQuietly;
|
|
322
|
+
/**
|
|
323
|
+
* How long until this feed's next LOOK.
|
|
324
|
+
*
|
|
325
|
+
* Without the cascade this is the historical rule: fast while faces are
|
|
326
|
+
* present, slow otherwise. With the cascade on, a still feed keeps looking at
|
|
327
|
+
* the scan cadence — looking is cheap and only analysis is gated — and
|
|
328
|
+
* `periodicIntervalMs` becomes the gate's heartbeat, i.e. the floor on
|
|
329
|
+
* REPORTING rather than the rate of watching.
|
|
330
|
+
*/
|
|
331
|
+
private intervalFor;
|
|
332
|
+
/**
|
|
333
|
+
* Per-feed phase step, derived from FEED COUNT and CADENCE instead of a fixed
|
|
334
|
+
* per-feed cap.
|
|
335
|
+
*
|
|
336
|
+
* The spread window is the smaller of the configured `maxFeedStaggerMs` and
|
|
337
|
+
* the fastest capture cadence (a spread longer than one period would just
|
|
338
|
+
* re-alias), and the step is the largest value that fits every feed inside
|
|
339
|
+
* it, never exceeding the configured `feedStaggerMs`. Small installs keep
|
|
340
|
+
* exactly today's offsets (4 feeds x 1000 ms); a 16-camera store gets 16
|
|
341
|
+
* DISTINCT offsets instead of feeds 15+ colliding on the cap.
|
|
342
|
+
*/
|
|
343
|
+
private staggerStepMs;
|
|
344
|
+
private staggerFor;
|
|
345
|
+
/**
|
|
346
|
+
* Delay before the next tick.
|
|
347
|
+
*
|
|
348
|
+
* - Camera dropped → the reconnect backoff, PLUS the phase offset so a
|
|
349
|
+
* recorder that rebooted does not get all N feeds re-opening in lock-step.
|
|
350
|
+
* - Admission denied → a short one-shot retry (consumed here) so the loop
|
|
351
|
+
* takes the inference slot as soon as it frees rather than idling a full
|
|
352
|
+
* cadence.
|
|
353
|
+
* - Otherwise → exactly the capture cadence. The phase offset is applied ONCE
|
|
354
|
+
* at startup (and on reconnect); adding it to every tick would make feed i's
|
|
355
|
+
* period `cadence + offset_i`, quietly stretching the last feed's cadence by
|
|
356
|
+
* the whole spread window — a 47 % slower camera 16 at the 30 s cadence.
|
|
357
|
+
* Equal periods preserve the startup phase difference forever.
|
|
358
|
+
*/
|
|
359
|
+
private nextDelayFor;
|
|
360
|
+
/**
|
|
361
|
+
* Arm this feed's next tick, for ONE run of the manager.
|
|
362
|
+
*
|
|
363
|
+
* `generation` is not decoration. A tick re-arms from its own `.finally`, and
|
|
364
|
+
* that `.finally` can run AFTER a stop()/start() cycle — the auto-sense
|
|
365
|
+
* supervisor stops and restarts the SAME manager instance every time
|
|
366
|
+
* `litert-lm` appears or disappears, and a cloud analyze can be in flight for
|
|
367
|
+
* up to two minutes. Without the generation the surviving tick re-arms a
|
|
368
|
+
* chain, `startLoop` arms another, and `s.timer` holds only the second one, so
|
|
369
|
+
* `stop()` can never clear the first: the feed now captures twice per cadence,
|
|
370
|
+
* permanently, and every further flap adds another chain. Measured: two
|
|
371
|
+
* pending timers for ONE feed after a single cycle. On the cloud path
|
|
372
|
+
* `maxConcurrentAnalyses` defaults to one slot PER LOOP, so the duplicate
|
|
373
|
+
* chain is duplicate Vertex spend, not just duplicate RTSP load.
|
|
374
|
+
*/
|
|
375
|
+
private scheduleNext;
|
|
376
|
+
/**
|
|
377
|
+
* One scheduled loop iteration with built-in RTSP self-recovery.
|
|
378
|
+
*
|
|
379
|
+
* If the camera is dropped (closed), this attempts to RE-OPEN it (the keystone
|
|
380
|
+
* 24/7 fix — a transient feed/network blip used to wedge the loop on "camera
|
|
381
|
+
* is not open" forever). On a successful re-open the backoff resets and the
|
|
382
|
+
* tick falls through to a normal capture so sensing resumes immediately; on a
|
|
383
|
+
* failed re-open the backoff doubles (capped) and we retry FOREVER. The
|
|
384
|
+
* per-attempt connect timeout still lives in the RTSP provider's open() — only
|
|
385
|
+
* the give-up-forever behavior changes to retry-forever.
|
|
386
|
+
*/
|
|
387
|
+
private runScheduledTick;
|
|
388
|
+
/**
|
|
389
|
+
* Attempt one camera re-open. Returns true on success (backoff cleared, sensing
|
|
390
|
+
* resumes), false on failure (backoff doubled+capped for the next attempt).
|
|
391
|
+
* Emits `reconnecting` before each attempt and `reconnected` on recovery so
|
|
392
|
+
* operators can observe the self-healing on an unattended connector.
|
|
393
|
+
*/
|
|
394
|
+
private tryReopen;
|
|
395
|
+
/**
|
|
396
|
+
* Put a loop into reconnect mode (camera dropped). Idempotent: an already
|
|
397
|
+
* dropped loop keeps its current (climbing) backoff rather than resetting to
|
|
398
|
+
* the initial delay.
|
|
399
|
+
*/
|
|
400
|
+
private enterReconnect;
|
|
401
|
+
private emitLoopError;
|
|
402
|
+
private reportCameraFailure;
|
|
403
|
+
private reportCameraHealth;
|
|
404
|
+
private reportCameraOpen;
|
|
405
|
+
private healthProbeDue;
|
|
406
|
+
/**
|
|
407
|
+
* Prove video locally without waiting for the model. The global boolean keeps
|
|
408
|
+
* legacy recorders to one extra short-lived ffmpeg pull at a time.
|
|
409
|
+
*/
|
|
410
|
+
private captureHealthFrame;
|
|
411
|
+
/**
|
|
412
|
+
* One cascade pass for a feed: admission → capture → motion → inference,
|
|
413
|
+
* with a bounded decode-only health probe when admission is denied.
|
|
414
|
+
*
|
|
415
|
+
* The admission check comes first so denied inference frames are dropped,
|
|
416
|
+
* never buffered. Video health is independent: at most one feed at a time
|
|
417
|
+
* may take a slow-cadence decode-only proof while the model is occupied.
|
|
418
|
+
*/
|
|
419
|
+
private captureAndPost;
|
|
420
|
+
/**
|
|
421
|
+
* Convert a camera frame to JPEG bytes for the POST.
|
|
422
|
+
*
|
|
423
|
+
* RTSP frames arrive as raw RGB24 Buffers, so we encode them with `sharp`
|
|
424
|
+
* when available (the standard sensing dep). If `sharp` is missing AND the
|
|
425
|
+
* frame is already JPEG (some providers emit JPEG directly), we ship it
|
|
426
|
+
* as-is; raw-RGB-without-sharp is rejected loudly so it never silently POSTs
|
|
427
|
+
* an un-decodable frame.
|
|
428
|
+
*
|
|
429
|
+
* Dimensions are needed to decode raw RGB24. Resolution order: the camera's
|
|
430
|
+
* own getResolution() (passed in by the caller — works for multi-channel
|
|
431
|
+
* feeds with no top-level camera.width/height), then the manager's configured
|
|
432
|
+
* width/height, then EdgeImageData's own dims.
|
|
433
|
+
*/
|
|
434
|
+
private toJpeg;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Build the per-feed capture loops from an EdgeAgentConfig — the bridge between
|
|
438
|
+
* config (`cameras: [...]` multi-channel, or single `camera`) and the manager.
|
|
439
|
+
*
|
|
440
|
+
* - Multi-channel: one loop per `cameras[]` entry, each with its own token +
|
|
441
|
+
* its own RTSP provider.
|
|
442
|
+
* - Single-camera (back-compat): one loop from the top-level `camera`/token.
|
|
443
|
+
*
|
|
444
|
+
* `rtspProviderFactory` / `clientFactory` are injectable for tests; defaults
|
|
445
|
+
* use the neutral RTSP package + AudienceAnalyzeClient.
|
|
446
|
+
*/
|
|
447
|
+
export declare function buildSensingLoops(config: EdgeAgentConfig, deps?: {
|
|
448
|
+
rtspProviderFactory?: (feed: ResolvedFeed) => CameraProvider;
|
|
449
|
+
streamUrlResolver?: (feed: ResolvedFeed, currentUrl: string, error: Error) => Promise<string | null>;
|
|
450
|
+
clientFactory?: (feed: ResolvedFeed) => AudienceAnalyzeClient;
|
|
451
|
+
httpPoster?: HttpPoster;
|
|
452
|
+
/** Freshness window (ms) a mosaic tile reuses the shared pull. Default 5000. */
|
|
453
|
+
sharedFrameMaxAgeMs?: number;
|
|
454
|
+
/** Shared per-mosaic-source pull registry so the VLM attaches to the SAME
|
|
455
|
+
* SharedFrameSource the on-device zoo uses (one RTSP pull for both rails). */
|
|
456
|
+
sharedSources?: Map<string, SharedFrameSource>;
|
|
457
|
+
}): SensingLoopDeps[];
|
|
458
|
+
/**
|
|
459
|
+
* Build one CameraProvider per feed, collapsing mosaic tiles that share a source
|
|
460
|
+
* onto a SINGLE shared RTSP pull. This is the ONE implementation of mosaic
|
|
461
|
+
* tiling, used by BOTH cloud-sense (buildSensingLoops) and local-sense
|
|
462
|
+
* (buildLocalSensingLoops) — no split-brain between run modes. Returns feed↔camera
|
|
463
|
+
* pairs so each caller attaches its own sensing client.
|
|
464
|
+
*
|
|
465
|
+
* Grouping: a feed opts into sharing a pull only via `sourceFeedId` (a tile → its
|
|
466
|
+
* mosaic source) or by being that source (`id`); a feed with neither is solo
|
|
467
|
+
* (keyed uniquely) and gets exactly the historical one-provider-per-feed path.
|
|
468
|
+
*
|
|
469
|
+
* `rtspFactory` builds the underlying RTSP provider and MUST honor `feed.crop`
|
|
470
|
+
* (used by the per-tile-pull fallback when no source feed is configured).
|
|
471
|
+
*/
|
|
472
|
+
export declare function buildTiledCameras(feeds: ResolvedFeed[], rtspFactory: (feed: ResolvedFeed) => CameraProvider, opts?: {
|
|
473
|
+
sharedFrameMaxAgeMs?: number;
|
|
474
|
+
/**
|
|
475
|
+
* Memoizes the per-mosaic-source SharedFrameSource so MULTIPLE consumers
|
|
476
|
+
* (the VLM rail AND the on-device ONNX zoo rail) attach to the SAME single
|
|
477
|
+
* RTSP pull instead of each opening its own. Keyed by the mosaic group key
|
|
478
|
+
* (the source feed's `id`). When omitted, each call builds its own sources
|
|
479
|
+
* (unchanged single-consumer behavior).
|
|
480
|
+
*/
|
|
481
|
+
sharedSources?: Map<string, SharedFrameSource>;
|
|
482
|
+
/**
|
|
483
|
+
* Pixel format each tile's CropViewProvider emits: 'jpeg' (default, the
|
|
484
|
+
* VLM/cloud POST) or 'rgb24' (raw RGB the on-device ONNX FaceDetector
|
|
485
|
+
* consumes). Both carve from the SAME JPEG mosaic pull; only the per-tile
|
|
486
|
+
* re-encode differs, so two consumers can share one pull at different formats.
|
|
487
|
+
*/
|
|
488
|
+
cropOutputFormat?: 'jpeg' | 'rgb24';
|
|
489
|
+
}): Array<{
|
|
490
|
+
feed: ResolvedFeed;
|
|
491
|
+
camera: CameraProvider;
|
|
492
|
+
}>;
|
|
493
|
+
/** A fully-resolved feed (token + rtspUrl guaranteed present). */
|
|
494
|
+
export interface ResolvedFeed {
|
|
495
|
+
name: string;
|
|
496
|
+
/** Config-local feed id (set on a mosaic source feed; tiles point at it). */
|
|
497
|
+
id?: string;
|
|
498
|
+
screenId?: string;
|
|
499
|
+
deviceToken: string;
|
|
500
|
+
rtspUrl: string;
|
|
501
|
+
sourceType?: 'recorder' | 'direct_url';
|
|
502
|
+
channelKey?: string;
|
|
503
|
+
recorder?: RecorderIdentity;
|
|
504
|
+
width?: number;
|
|
505
|
+
height?: number;
|
|
506
|
+
fps?: number;
|
|
507
|
+
transport?: 'tcp' | 'udp';
|
|
508
|
+
ffmpegPath?: string;
|
|
509
|
+
/**
|
|
510
|
+
* Mosaic tiling. `sourceFeedId` groups this tile with its mosaic source (the
|
|
511
|
+
* feed whose `id` matches) so the source RTSP is pulled ONCE; `crop` is the
|
|
512
|
+
* tile's sub-rectangle in source pixels, carved in ffmpeg. Both omitted ⇒ a
|
|
513
|
+
* normal whole-frame feed with its own dedicated pull (unchanged).
|
|
514
|
+
*/
|
|
515
|
+
sourceFeedId?: string;
|
|
516
|
+
crop?: MosaicTile;
|
|
517
|
+
/**
|
|
518
|
+
* Frame encoding the RTSP provider should emit. Cloud-sense always wants
|
|
519
|
+
* 'jpeg' so ffmpeg encodes directly and NO image library (sharp) is needed
|
|
520
|
+
* for the POST. Set on every resolved feed by resolveFeeds().
|
|
521
|
+
*/
|
|
522
|
+
outputFormat?: 'rgb24' | 'jpeg';
|
|
523
|
+
/** JPEG quality (1-100) when outputFormat='jpeg'. */
|
|
524
|
+
jpegQuality?: number;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Flatten an EdgeAgentConfig into the list of feeds to run. Multi-channel
|
|
528
|
+
* `cameras[]` wins; otherwise the single `camera` (+ top-level token) becomes
|
|
529
|
+
* a one-element list (back-compat). Feeds without both a token and rtspUrl are
|
|
530
|
+
* skipped (the single-camera fallback needs both for cloud sensing).
|
|
531
|
+
*/
|
|
532
|
+
export declare function resolveFeeds(config: EdgeAgentConfig): ResolvedFeed[];
|
|
533
|
+
//# sourceMappingURL=CloudSensingManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CloudSensingManager.d.ts","sourceRoot":"","sources":["../src/CloudSensingManager.ts"],"names":[],"mappings":"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"}
|