@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/plugin.zip CHANGED
Binary file
@@ -34496,6 +34496,7 @@ class AlertManager {
34496
34496
  }
34497
34497
  /**
34498
34498
  * Get notification title based on alert type
34499
+ * For movement alerts with LLM descriptions, use the smart description as title
34499
34500
  */
34500
34501
  getNotificationTitle(alert) {
34501
34502
  const prefix = alert.severity === 'critical' ? '🚨 ' :
@@ -34506,11 +34507,27 @@ class AlertManager {
34506
34507
  : 'Object';
34507
34508
  switch (alert.type) {
34508
34509
  case 'property_entry':
34510
+ // Legacy - use simple title
34509
34511
  return `${prefix}${objectType} Arrived`;
34510
34512
  case 'property_exit':
34513
+ // Legacy - use simple title
34511
34514
  return `${prefix}${objectType} Left`;
34512
34515
  case 'movement':
34513
- // Include destination in title
34516
+ // For smart activity alerts, use the LLM description as title if available
34517
+ // This gives us rich context like "Person walking toward front door"
34518
+ if (alert.details.objectLabel && alert.details.usedLlm) {
34519
+ // Truncate to reasonable title length (first sentence or 60 chars)
34520
+ let smartTitle = alert.details.objectLabel;
34521
+ const firstPeriod = smartTitle.indexOf('.');
34522
+ if (firstPeriod > 0 && firstPeriod < 60) {
34523
+ smartTitle = smartTitle.substring(0, firstPeriod);
34524
+ }
34525
+ else if (smartTitle.length > 60) {
34526
+ smartTitle = smartTitle.substring(0, 57) + '...';
34527
+ }
34528
+ return `${prefix}${smartTitle}`;
34529
+ }
34530
+ // Fallback: include destination in title
34514
34531
  const dest = alert.details.toCameraName || 'area';
34515
34532
  return `${prefix}${objectType} → ${dest}`;
34516
34533
  case 'unusual_path':
@@ -36828,7 +36845,13 @@ Use the mount height to help estimate distances - objects at ground level will a
36828
36845
  this.status.lastScanTime = Date.now();
36829
36846
  return null;
36830
36847
  }
36831
- // Correlate if we have multiple cameras
36848
+ // ALWAYS generate suggestions from each camera's analysis first
36849
+ // This ensures landmarks and zones from individual cameras are captured
36850
+ for (const analysis of analyses) {
36851
+ this.generateSuggestionsFromAnalysis(analysis);
36852
+ }
36853
+ this.console.log(`[Discovery] Generated suggestions from ${analyses.length} camera analyses`);
36854
+ // Then correlate if we have multiple cameras (adds shared landmarks and connections)
36832
36855
  let correlation = null;
36833
36856
  if (analyses.length >= 2) {
36834
36857
  correlation = await this.correlateScenes(analyses);
@@ -36836,10 +36859,6 @@ Use the mount height to help estimate distances - objects at ground level will a
36836
36859
  this.generateSuggestionsFromCorrelation(correlation);
36837
36860
  }
36838
36861
  }
36839
- else if (analyses.length === 1) {
36840
- // Single camera - generate suggestions from its analysis
36841
- this.generateSuggestionsFromAnalysis(analyses[0]);
36842
- }
36843
36862
  this.status.lastScanTime = Date.now();
36844
36863
  this.status.pendingSuggestions = this.getPendingSuggestions().length;
36845
36864
  return correlation;
@@ -37517,33 +37536,19 @@ class TrackingEngine {
37517
37536
  spatialResult = await this.spatialReasoning.generateEntryDescription(tracked, sighting.cameraId, mediaObject);
37518
37537
  this.console.log(`[Entry Alert] Got description: "${spatialResult.description.substring(0, 60)}...", usedLlm=${spatialResult.usedLlm}`);
37519
37538
  }
37520
- if (isEntryPoint) {
37521
- // Entry point - generate property entry alert
37522
- await this.alertManager.checkAndAlert('property_entry', tracked, {
37523
- cameraId: sighting.cameraId,
37524
- cameraName: sighting.cameraName,
37525
- objectClass: sighting.detection.className,
37526
- objectLabel: spatialResult.description,
37527
- detectionId: sighting.detectionId,
37528
- involvedLandmarks: spatialResult.involvedLandmarks?.map(l => l.name),
37529
- usedLlm: spatialResult.usedLlm,
37530
- });
37531
- }
37532
- else {
37533
- // Non-entry point - still alert about activity using movement alert type
37534
- // This notifies about any activity around the property using topology context
37535
- await this.alertManager.checkAndAlert('movement', tracked, {
37536
- cameraId: sighting.cameraId,
37537
- cameraName: sighting.cameraName,
37538
- toCameraId: sighting.cameraId,
37539
- toCameraName: sighting.cameraName,
37540
- objectClass: sighting.detection.className,
37541
- objectLabel: spatialResult.description, // Use spatial reasoning description (topology-based)
37542
- detectionId: sighting.detectionId,
37543
- involvedLandmarks: spatialResult.involvedLandmarks?.map(l => l.name),
37544
- usedLlm: spatialResult.usedLlm,
37545
- });
37546
- }
37539
+ // Always use movement alert type for smart notifications with LLM descriptions
37540
+ // The property_entry/property_exit types are legacy and disabled by default
37541
+ await this.alertManager.checkAndAlert('movement', tracked, {
37542
+ cameraId: sighting.cameraId,
37543
+ cameraName: sighting.cameraName,
37544
+ toCameraId: sighting.cameraId,
37545
+ toCameraName: sighting.cameraName,
37546
+ objectClass: sighting.detection.className,
37547
+ objectLabel: spatialResult.description, // Smart LLM-generated description
37548
+ detectionId: sighting.detectionId,
37549
+ involvedLandmarks: spatialResult.involvedLandmarks?.map(l => l.name),
37550
+ usedLlm: spatialResult.usedLlm,
37551
+ });
37547
37552
  this.recordAlertTime(globalId);
37548
37553
  }, this.config.loiteringThreshold);
37549
37554
  }
@@ -37651,9 +37656,12 @@ class TrackingEngine {
37651
37656
  spatialResult = await this.spatialReasoning.generateExitDescription(current, sighting.cameraId, mediaObject);
37652
37657
  this.console.log(`[Exit Alert] Got description: "${spatialResult.description.substring(0, 60)}...", usedLlm=${spatialResult.usedLlm}`);
37653
37658
  }
37654
- await this.alertManager.checkAndAlert('property_exit', current, {
37659
+ // Use movement alert for exit too - smart notifications with LLM descriptions
37660
+ await this.alertManager.checkAndAlert('movement', current, {
37655
37661
  cameraId: sighting.cameraId,
37656
37662
  cameraName: sighting.cameraName,
37663
+ toCameraId: sighting.cameraId,
37664
+ toCameraName: sighting.cameraName,
37657
37665
  objectClass: current.className,
37658
37666
  objectLabel: spatialResult.description,
37659
37667
  involvedLandmarks: spatialResult.involvedLandmarks?.map(l => l.name),
@@ -40829,6 +40837,8 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
40829
40837
  const landmarkData = suggestion.landmark;
40830
40838
  const distanceFeet = landmarkData.distanceFeet || 50; // Default 50ft if not set
40831
40839
  const distanceInPixels = distanceFeet * floorPlanScale;
40840
+ // Debug: log the distance data to verify it's being used correctly
40841
+ this.console.log(`[Discovery] Landmark "${suggestion.landmark.name}" distance data: distanceFeet=${distanceFeet}, distance="${landmarkData.distance || 'not set'}", floorPlanScale=${floorPlanScale}, distanceInPixels=${distanceInPixels}`);
40832
40842
  // Use bounding box for horizontal positioning within the FOV
40833
40843
  const bbox = landmarkData.boundingBox;
40834
40844
  let angleOffset;
@@ -41203,8 +41213,8 @@ function createDefaultRules() {
41203
41213
  return [
41204
41214
  {
41205
41215
  id: 'property-entry',
41206
- name: 'Property Entry',
41207
- enabled: true,
41216
+ name: 'Property Entry (Legacy)',
41217
+ enabled: false, // Disabled - use movement alerts with LLM descriptions instead
41208
41218
  type: 'property_entry',
41209
41219
  conditions: [],
41210
41220
  severity: 'info',
@@ -41213,8 +41223,8 @@ function createDefaultRules() {
41213
41223
  },
41214
41224
  {
41215
41225
  id: 'property-exit',
41216
- name: 'Property Exit',
41217
- enabled: true,
41226
+ name: 'Property Exit (Legacy)',
41227
+ enabled: false, // Disabled - use movement alerts with LLM descriptions instead
41218
41228
  type: 'property_exit',
41219
41229
  conditions: [],
41220
41230
  severity: 'info',
@@ -41223,7 +41233,7 @@ function createDefaultRules() {
41223
41233
  },
41224
41234
  {
41225
41235
  id: 'movement',
41226
- name: 'Movement Between Cameras',
41236
+ name: 'Smart Activity Alerts',
41227
41237
  enabled: true,
41228
41238
  type: 'movement',
41229
41239
  conditions: [],