@blueharford/scrypted-spatial-awareness 0.4.6 → 0.4.7
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 +93 -369
- package/dist/main.nodejs.js +1 -1
- package/dist/main.nodejs.js.map +1 -1
- package/dist/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/alerts/alert-manager.ts +16 -9
- package/src/core/object-correlator.ts +14 -5
- package/src/main.ts +3 -3
- package/src/models/alert.ts +2 -2
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -159,25 +159,32 @@ export class AlertManager {
|
|
|
159
159
|
const prefix = alert.severity === 'critical' ? '🚨 ' :
|
|
160
160
|
alert.severity === 'warning' ? '⚠️ ' : '';
|
|
161
161
|
|
|
162
|
+
// Use object class in title
|
|
163
|
+
const objectType = alert.details.objectClass
|
|
164
|
+
? alert.details.objectClass.charAt(0).toUpperCase() + alert.details.objectClass.slice(1)
|
|
165
|
+
: 'Object';
|
|
166
|
+
|
|
162
167
|
switch (alert.type) {
|
|
163
168
|
case 'property_entry':
|
|
164
|
-
return `${prefix}
|
|
169
|
+
return `${prefix}${objectType} Arrived`;
|
|
165
170
|
case 'property_exit':
|
|
166
|
-
return `${prefix}
|
|
171
|
+
return `${prefix}${objectType} Left`;
|
|
167
172
|
case 'movement':
|
|
168
|
-
|
|
173
|
+
// Include destination in title
|
|
174
|
+
const dest = alert.details.toCameraName || 'area';
|
|
175
|
+
return `${prefix}${objectType} → ${dest}`;
|
|
169
176
|
case 'unusual_path':
|
|
170
|
-
return `${prefix}Unusual
|
|
177
|
+
return `${prefix}Unusual Route`;
|
|
171
178
|
case 'dwell_time':
|
|
172
|
-
return `${prefix}
|
|
179
|
+
return `${prefix}${objectType} Lingering`;
|
|
173
180
|
case 'restricted_zone':
|
|
174
|
-
return `${prefix}Restricted Zone
|
|
181
|
+
return `${prefix}Restricted Zone!`;
|
|
175
182
|
case 'lost_tracking':
|
|
176
|
-
return `${prefix}Lost
|
|
183
|
+
return `${prefix}${objectType} Lost`;
|
|
177
184
|
case 'reappearance':
|
|
178
|
-
return `${prefix}
|
|
185
|
+
return `${prefix}${objectType} Reappeared`;
|
|
179
186
|
default:
|
|
180
|
-
return `${prefix}Spatial
|
|
187
|
+
return `${prefix}Spatial Alert`;
|
|
181
188
|
}
|
|
182
189
|
}
|
|
183
190
|
|
|
@@ -125,6 +125,9 @@ export class ObjectCorrelator {
|
|
|
125
125
|
return 1.0;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
// Calculate transit time first
|
|
129
|
+
const transitTime = sighting.timestamp - lastSighting.timestamp;
|
|
130
|
+
|
|
128
131
|
// Find connection between cameras
|
|
129
132
|
const connection = findConnection(
|
|
130
133
|
this.topology,
|
|
@@ -133,12 +136,17 @@ export class ObjectCorrelator {
|
|
|
133
136
|
);
|
|
134
137
|
|
|
135
138
|
if (!connection) {
|
|
136
|
-
// No defined connection -
|
|
137
|
-
//
|
|
139
|
+
// No defined connection - still allow correlation based on reasonable timing
|
|
140
|
+
// Allow up to 2 minutes transit between any cameras
|
|
141
|
+
const MAX_UNCHARTED_TRANSIT = 120000; // 2 minutes
|
|
142
|
+
if (transitTime > 0 && transitTime < MAX_UNCHARTED_TRANSIT) {
|
|
143
|
+
// Score based on how reasonable the timing is
|
|
144
|
+
// Shorter transits are more likely to be the same object
|
|
145
|
+
const timingScore = Math.max(0.3, 1 - (transitTime / MAX_UNCHARTED_TRANSIT));
|
|
146
|
+
return timingScore;
|
|
147
|
+
}
|
|
138
148
|
return 0.2;
|
|
139
149
|
}
|
|
140
|
-
|
|
141
|
-
const transitTime = sighting.timestamp - lastSighting.timestamp;
|
|
142
150
|
const { min, typical, max } = connection.transitTime;
|
|
143
151
|
|
|
144
152
|
// Way outside range
|
|
@@ -217,7 +225,8 @@ export class ObjectCorrelator {
|
|
|
217
225
|
);
|
|
218
226
|
|
|
219
227
|
if (!connection) {
|
|
220
|
-
|
|
228
|
+
// No connection defined - give neutral score (don't penalize)
|
|
229
|
+
return 0.5;
|
|
221
230
|
}
|
|
222
231
|
|
|
223
232
|
let score = 0;
|
package/src/main.ts
CHANGED
|
@@ -78,8 +78,8 @@ export class SpatialAwarenessPlugin extends ScryptedDeviceBase
|
|
|
78
78
|
correlationThreshold: {
|
|
79
79
|
title: 'Correlation Confidence Threshold',
|
|
80
80
|
type: 'number',
|
|
81
|
-
defaultValue: 0.
|
|
82
|
-
description: 'Minimum confidence (0-1) for automatic object correlation',
|
|
81
|
+
defaultValue: 0.35,
|
|
82
|
+
description: 'Minimum confidence (0-1) for automatic object correlation. Lower values allow more matches.',
|
|
83
83
|
group: 'Tracking',
|
|
84
84
|
},
|
|
85
85
|
lostTimeout: {
|
|
@@ -324,7 +324,7 @@ export class SpatialAwarenessPlugin extends ScryptedDeviceBase
|
|
|
324
324
|
|
|
325
325
|
const config: TrackingEngineConfig = {
|
|
326
326
|
correlationWindow: (this.storageSettings.values.correlationWindow as number || 30) * 1000,
|
|
327
|
-
correlationThreshold: this.storageSettings.values.correlationThreshold as number || 0.
|
|
327
|
+
correlationThreshold: this.storageSettings.values.correlationThreshold as number || 0.35,
|
|
328
328
|
lostTimeout: (this.storageSettings.values.lostTimeout as number || 300) * 1000,
|
|
329
329
|
useVisualMatching: this.storageSettings.values.useVisualMatching as boolean ?? true,
|
|
330
330
|
loiteringThreshold: (this.storageSettings.values.loiteringThreshold as number || 3) * 1000,
|
package/src/models/alert.ts
CHANGED
|
@@ -214,9 +214,9 @@ export function generateAlertMessage(
|
|
|
214
214
|
|
|
215
215
|
switch (type) {
|
|
216
216
|
case 'property_entry':
|
|
217
|
-
return `${objectDesc}
|
|
217
|
+
return `${objectDesc} arrived at ${details.cameraName || 'property'}`;
|
|
218
218
|
case 'property_exit':
|
|
219
|
-
return `${objectDesc}
|
|
219
|
+
return `${objectDesc} left from ${details.cameraName || 'property'}`;
|
|
220
220
|
case 'movement':
|
|
221
221
|
// If we have a rich description from LLM/RAG, use it
|
|
222
222
|
if (details.objectLabel && details.usedLlm) {
|