@blueharford/scrypted-spatial-awareness 0.6.30 → 0.6.31
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 +26 -13
- 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 +18 -2
- package/src/core/spatial-reasoning.ts +2 -2
- package/src/core/tracking-engine.ts +10 -8
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/out/main.nodejs.js
CHANGED
|
@@ -34457,6 +34457,12 @@ class AlertManager {
|
|
|
34457
34457
|
const notifierIds = rule.notifiers.length > 0
|
|
34458
34458
|
? rule.notifiers
|
|
34459
34459
|
: this.getDefaultNotifiers();
|
|
34460
|
+
// Debug: log which notifiers we're using
|
|
34461
|
+
this.console.log(`[Notification] Rule ${rule.id} has ${rule.notifiers.length} notifiers, using ${notifierIds.length} notifier(s): ${notifierIds.join(', ') || 'NONE'}`);
|
|
34462
|
+
if (notifierIds.length === 0) {
|
|
34463
|
+
this.console.warn(`[Notification] No notifiers configured! Configure a notifier in plugin settings.`);
|
|
34464
|
+
return;
|
|
34465
|
+
}
|
|
34460
34466
|
// Try to get a thumbnail from the camera
|
|
34461
34467
|
let mediaObject;
|
|
34462
34468
|
const cameraId = alert.details.toCameraId || alert.details.cameraId;
|
|
@@ -34551,27 +34557,34 @@ class AlertManager {
|
|
|
34551
34557
|
try {
|
|
34552
34558
|
// Try new multiple notifiers setting first
|
|
34553
34559
|
const notifiers = this.storage.getItem('defaultNotifiers');
|
|
34560
|
+
this.console.log(`[Notifiers] Raw storage value: ${notifiers}`);
|
|
34554
34561
|
if (notifiers) {
|
|
34555
34562
|
// Could be JSON array or comma-separated string
|
|
34556
34563
|
try {
|
|
34557
34564
|
const parsed = JSON.parse(notifiers);
|
|
34558
34565
|
if (Array.isArray(parsed)) {
|
|
34566
|
+
this.console.log(`[Notifiers] Parsed JSON array: ${parsed.join(', ')}`);
|
|
34559
34567
|
return parsed;
|
|
34560
34568
|
}
|
|
34561
34569
|
}
|
|
34562
34570
|
catch {
|
|
34563
34571
|
// Not JSON, might be comma-separated or single value
|
|
34564
34572
|
if (notifiers.includes(',')) {
|
|
34565
|
-
|
|
34573
|
+
const result = notifiers.split(',').map(s => s.trim()).filter(Boolean);
|
|
34574
|
+
this.console.log(`[Notifiers] Parsed comma-separated: ${result.join(', ')}`);
|
|
34575
|
+
return result;
|
|
34566
34576
|
}
|
|
34577
|
+
this.console.log(`[Notifiers] Single value: ${notifiers}`);
|
|
34567
34578
|
return [notifiers];
|
|
34568
34579
|
}
|
|
34569
34580
|
}
|
|
34570
34581
|
// Fallback to old single notifier setting
|
|
34571
34582
|
const defaultNotifier = this.storage.getItem('defaultNotifier');
|
|
34583
|
+
this.console.log(`[Notifiers] Fallback single notifier: ${defaultNotifier || 'NONE'}`);
|
|
34572
34584
|
return defaultNotifier ? [defaultNotifier] : [];
|
|
34573
34585
|
}
|
|
34574
|
-
catch {
|
|
34586
|
+
catch (e) {
|
|
34587
|
+
this.console.error(`[Notifiers] Error reading notifiers:`, e);
|
|
34575
34588
|
return [];
|
|
34576
34589
|
}
|
|
34577
34590
|
}
|
|
@@ -35427,7 +35440,7 @@ class SpatialReasoningEngine {
|
|
|
35427
35440
|
id: deviceId,
|
|
35428
35441
|
name: device.name || deviceId,
|
|
35429
35442
|
providerType: providerTypeEnum,
|
|
35430
|
-
lastUsed:
|
|
35443
|
+
lastUsed: Date.now() - 60000, // Initialize to 1 minute ago so all LLMs start equal
|
|
35431
35444
|
errorCount: 0,
|
|
35432
35445
|
});
|
|
35433
35446
|
this.console.log(`[LLM] Using configured LLM: ${device.name}`);
|
|
@@ -35455,7 +35468,7 @@ class SpatialReasoningEngine {
|
|
|
35455
35468
|
id,
|
|
35456
35469
|
name: device.name || id,
|
|
35457
35470
|
providerType: providerTypeEnum,
|
|
35458
|
-
lastUsed:
|
|
35471
|
+
lastUsed: Date.now() - 60000, // Initialize to 1 minute ago so all LLMs start equal
|
|
35459
35472
|
errorCount: 0,
|
|
35460
35473
|
});
|
|
35461
35474
|
this.console.log(`[LLM] Auto-discovered: ${device.name}`);
|
|
@@ -37706,31 +37719,31 @@ class TrackingEngine {
|
|
|
37706
37719
|
}
|
|
37707
37720
|
/** Capture and cache a snapshot for a tracked object, and start LLM analysis immediately */
|
|
37708
37721
|
async captureAndCacheSnapshot(globalId, cameraId, eventType = 'entry') {
|
|
37722
|
+
// Skip if we already have a recent snapshot for this object (within 5 seconds)
|
|
37723
|
+
const existingSnapshot = this.snapshotCache.get(globalId);
|
|
37724
|
+
if (existingSnapshot && eventType !== 'exit') {
|
|
37725
|
+
// For entry/movement, we can reuse existing snapshot
|
|
37726
|
+
// For exit, we want a fresh snapshot while they're still visible
|
|
37727
|
+
return;
|
|
37728
|
+
}
|
|
37709
37729
|
try {
|
|
37710
37730
|
const camera = systemManager.getDeviceById(cameraId);
|
|
37711
37731
|
if (camera?.interfaces?.includes(sdk_1.ScryptedInterface.Camera)) {
|
|
37712
37732
|
const mediaObject = await camera.takePicture();
|
|
37713
37733
|
if (mediaObject) {
|
|
37714
37734
|
this.snapshotCache.set(globalId, mediaObject);
|
|
37715
|
-
this.console.log(`[Snapshot] Cached snapshot for ${globalId.slice(0, 8)} from ${cameraId}`);
|
|
37716
37735
|
// Start LLM analysis immediately in parallel (don't await) - but respect rate limits
|
|
37717
37736
|
const tracked = this.state.getObject(globalId);
|
|
37718
37737
|
if (tracked && this.config.useLlmDescriptions && this.tryLlmCall()) {
|
|
37719
|
-
this.console.log(`[LLM Prefetch] Starting ${eventType} analysis for ${globalId.slice(0, 8)}`);
|
|
37720
37738
|
const descriptionPromise = eventType === 'exit'
|
|
37721
37739
|
? this.spatialReasoning.generateExitDescription(tracked, cameraId, mediaObject)
|
|
37722
37740
|
: this.spatialReasoning.generateEntryDescription(tracked, cameraId, mediaObject);
|
|
37723
37741
|
this.pendingDescriptions.set(globalId, descriptionPromise);
|
|
37724
|
-
// Log when complete (
|
|
37725
|
-
descriptionPromise.
|
|
37726
|
-
this.console.log(`[LLM Prefetch] ${eventType} analysis ready for ${globalId.slice(0, 8)}: "${result.description.substring(0, 40)}..."`);
|
|
37727
|
-
}).catch(e => {
|
|
37742
|
+
// Log when complete (but don't spam logs)
|
|
37743
|
+
descriptionPromise.catch(e => {
|
|
37728
37744
|
this.console.warn(`[LLM Prefetch] Failed for ${globalId.slice(0, 8)}: ${e}`);
|
|
37729
37745
|
});
|
|
37730
37746
|
}
|
|
37731
|
-
else if (tracked && this.config.useLlmDescriptions) {
|
|
37732
|
-
this.console.log(`[LLM Prefetch] Skipped for ${globalId.slice(0, 8)} - rate limited`);
|
|
37733
|
-
}
|
|
37734
37747
|
}
|
|
37735
37748
|
}
|
|
37736
37749
|
}
|