@blueharford/scrypted-spatial-awareness 0.6.22 → 0.6.24
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/dist/main.nodejs.js +1 -1
- package/dist/main.nodejs.js.map +1 -1
- package/dist/plugin.zip +0 -0
- package/out/main.nodejs.js +49 -39
- package/out/main.nodejs.js.map +1 -1
- package/out/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/alerts/alert-manager.ts +17 -1
- package/src/core/topology-discovery.ts +8 -4
- package/src/core/tracking-engine.ts +17 -27
- package/src/main.ts +3 -0
- package/src/models/alert.ts +5 -5
package/out/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -155,6 +155,7 @@ export class AlertManager {
|
|
|
155
155
|
|
|
156
156
|
/**
|
|
157
157
|
* Get notification title based on alert type
|
|
158
|
+
* For movement alerts with LLM descriptions, use the smart description as title
|
|
158
159
|
*/
|
|
159
160
|
private getNotificationTitle(alert: Alert): string {
|
|
160
161
|
const prefix = alert.severity === 'critical' ? '🚨 ' :
|
|
@@ -167,11 +168,26 @@ export class AlertManager {
|
|
|
167
168
|
|
|
168
169
|
switch (alert.type) {
|
|
169
170
|
case 'property_entry':
|
|
171
|
+
// Legacy - use simple title
|
|
170
172
|
return `${prefix}${objectType} Arrived`;
|
|
171
173
|
case 'property_exit':
|
|
174
|
+
// Legacy - use simple title
|
|
172
175
|
return `${prefix}${objectType} Left`;
|
|
173
176
|
case 'movement':
|
|
174
|
-
//
|
|
177
|
+
// For smart activity alerts, use the LLM description as title if available
|
|
178
|
+
// This gives us rich context like "Person walking toward front door"
|
|
179
|
+
if (alert.details.objectLabel && alert.details.usedLlm) {
|
|
180
|
+
// Truncate to reasonable title length (first sentence or 60 chars)
|
|
181
|
+
let smartTitle = alert.details.objectLabel;
|
|
182
|
+
const firstPeriod = smartTitle.indexOf('.');
|
|
183
|
+
if (firstPeriod > 0 && firstPeriod < 60) {
|
|
184
|
+
smartTitle = smartTitle.substring(0, firstPeriod);
|
|
185
|
+
} else if (smartTitle.length > 60) {
|
|
186
|
+
smartTitle = smartTitle.substring(0, 57) + '...';
|
|
187
|
+
}
|
|
188
|
+
return `${prefix}${smartTitle}`;
|
|
189
|
+
}
|
|
190
|
+
// Fallback: include destination in title
|
|
175
191
|
const dest = alert.details.toCameraName || 'area';
|
|
176
192
|
return `${prefix}${objectType} → ${dest}`;
|
|
177
193
|
case 'unusual_path':
|
|
@@ -748,16 +748,20 @@ Use the mount height to help estimate distances - objects at ground level will a
|
|
|
748
748
|
return null;
|
|
749
749
|
}
|
|
750
750
|
|
|
751
|
-
//
|
|
751
|
+
// ALWAYS generate suggestions from each camera's analysis first
|
|
752
|
+
// This ensures landmarks and zones from individual cameras are captured
|
|
753
|
+
for (const analysis of analyses) {
|
|
754
|
+
this.generateSuggestionsFromAnalysis(analysis);
|
|
755
|
+
}
|
|
756
|
+
this.console.log(`[Discovery] Generated suggestions from ${analyses.length} camera analyses`);
|
|
757
|
+
|
|
758
|
+
// Then correlate if we have multiple cameras (adds shared landmarks and connections)
|
|
752
759
|
let correlation: TopologyCorrelation | null = null;
|
|
753
760
|
if (analyses.length >= 2) {
|
|
754
761
|
correlation = await this.correlateScenes(analyses);
|
|
755
762
|
if (correlation) {
|
|
756
763
|
this.generateSuggestionsFromCorrelation(correlation);
|
|
757
764
|
}
|
|
758
|
-
} else if (analyses.length === 1) {
|
|
759
|
-
// Single camera - generate suggestions from its analysis
|
|
760
|
-
this.generateSuggestionsFromAnalysis(analyses[0]);
|
|
761
765
|
}
|
|
762
766
|
|
|
763
767
|
this.status.lastScanTime = Date.now();
|
|
@@ -579,32 +579,19 @@ export class TrackingEngine {
|
|
|
579
579
|
this.console.log(`[Entry Alert] Got description: "${spatialResult.description.substring(0, 60)}...", usedLlm=${spatialResult.usedLlm}`);
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
// This notifies about any activity around the property using topology context
|
|
596
|
-
await this.alertManager.checkAndAlert('movement', tracked, {
|
|
597
|
-
cameraId: sighting.cameraId,
|
|
598
|
-
cameraName: sighting.cameraName,
|
|
599
|
-
toCameraId: sighting.cameraId,
|
|
600
|
-
toCameraName: sighting.cameraName,
|
|
601
|
-
objectClass: sighting.detection.className,
|
|
602
|
-
objectLabel: spatialResult.description, // Use spatial reasoning description (topology-based)
|
|
603
|
-
detectionId: sighting.detectionId,
|
|
604
|
-
involvedLandmarks: spatialResult.involvedLandmarks?.map(l => l.name),
|
|
605
|
-
usedLlm: spatialResult.usedLlm,
|
|
606
|
-
});
|
|
607
|
-
}
|
|
582
|
+
// Always use movement alert type for smart notifications with LLM descriptions
|
|
583
|
+
// The property_entry/property_exit types are legacy and disabled by default
|
|
584
|
+
await this.alertManager.checkAndAlert('movement', tracked, {
|
|
585
|
+
cameraId: sighting.cameraId,
|
|
586
|
+
cameraName: sighting.cameraName,
|
|
587
|
+
toCameraId: sighting.cameraId,
|
|
588
|
+
toCameraName: sighting.cameraName,
|
|
589
|
+
objectClass: sighting.detection.className,
|
|
590
|
+
objectLabel: spatialResult.description, // Smart LLM-generated description
|
|
591
|
+
detectionId: sighting.detectionId,
|
|
592
|
+
involvedLandmarks: spatialResult.involvedLandmarks?.map(l => l.name),
|
|
593
|
+
usedLlm: spatialResult.usedLlm,
|
|
594
|
+
});
|
|
608
595
|
|
|
609
596
|
this.recordAlertTime(globalId);
|
|
610
597
|
}, this.config.loiteringThreshold);
|
|
@@ -731,9 +718,12 @@ export class TrackingEngine {
|
|
|
731
718
|
this.console.log(`[Exit Alert] Got description: "${spatialResult.description.substring(0, 60)}...", usedLlm=${spatialResult.usedLlm}`);
|
|
732
719
|
}
|
|
733
720
|
|
|
734
|
-
|
|
721
|
+
// Use movement alert for exit too - smart notifications with LLM descriptions
|
|
722
|
+
await this.alertManager.checkAndAlert('movement', current, {
|
|
735
723
|
cameraId: sighting.cameraId,
|
|
736
724
|
cameraName: sighting.cameraName,
|
|
725
|
+
toCameraId: sighting.cameraId,
|
|
726
|
+
toCameraName: sighting.cameraName,
|
|
737
727
|
objectClass: current.className,
|
|
738
728
|
objectLabel: spatialResult.description,
|
|
739
729
|
involvedLandmarks: spatialResult.involvedLandmarks?.map(l => l.name),
|
package/src/main.ts
CHANGED
|
@@ -1919,6 +1919,9 @@ export class SpatialAwarenessPlugin extends ScryptedDeviceBase
|
|
|
1919
1919
|
const distanceFeet = landmarkData.distanceFeet || 50; // Default 50ft if not set
|
|
1920
1920
|
const distanceInPixels = distanceFeet * floorPlanScale;
|
|
1921
1921
|
|
|
1922
|
+
// Debug: log the distance data to verify it's being used correctly
|
|
1923
|
+
this.console.log(`[Discovery] Landmark "${suggestion.landmark.name}" distance data: distanceFeet=${distanceFeet}, distance="${landmarkData.distance || 'not set'}", floorPlanScale=${floorPlanScale}, distanceInPixels=${distanceInPixels}`);
|
|
1924
|
+
|
|
1922
1925
|
// Use bounding box for horizontal positioning within the FOV
|
|
1923
1926
|
const bbox = landmarkData.boundingBox as [number, number, number, number] | undefined;
|
|
1924
1927
|
|
package/src/models/alert.ts
CHANGED
|
@@ -128,8 +128,8 @@ export function createDefaultRules(): AlertRule[] {
|
|
|
128
128
|
return [
|
|
129
129
|
{
|
|
130
130
|
id: 'property-entry',
|
|
131
|
-
name: 'Property Entry',
|
|
132
|
-
enabled:
|
|
131
|
+
name: 'Property Entry (Legacy)',
|
|
132
|
+
enabled: false, // Disabled - use movement alerts with LLM descriptions instead
|
|
133
133
|
type: 'property_entry',
|
|
134
134
|
conditions: [],
|
|
135
135
|
severity: 'info',
|
|
@@ -138,8 +138,8 @@ export function createDefaultRules(): AlertRule[] {
|
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
id: 'property-exit',
|
|
141
|
-
name: 'Property Exit',
|
|
142
|
-
enabled:
|
|
141
|
+
name: 'Property Exit (Legacy)',
|
|
142
|
+
enabled: false, // Disabled - use movement alerts with LLM descriptions instead
|
|
143
143
|
type: 'property_exit',
|
|
144
144
|
conditions: [],
|
|
145
145
|
severity: 'info',
|
|
@@ -148,7 +148,7 @@ export function createDefaultRules(): AlertRule[] {
|
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
150
|
id: 'movement',
|
|
151
|
-
name: '
|
|
151
|
+
name: 'Smart Activity Alerts',
|
|
152
152
|
enabled: true,
|
|
153
153
|
type: 'movement',
|
|
154
154
|
conditions: [],
|