@blueharford/scrypted-spatial-awareness 0.5.8 → 0.5.9
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 +93 -7
- package/out/main.nodejs.js.map +1 -1
- package/out/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/core/topology-discovery.ts +2 -2
- package/src/main.ts +96 -5
- package/src/ui/editor-html.ts +6 -0
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/out/main.nodejs.js
CHANGED
|
@@ -36275,7 +36275,7 @@ class TopologyDiscoveryEngine {
|
|
|
36275
36275
|
],
|
|
36276
36276
|
},
|
|
36277
36277
|
],
|
|
36278
|
-
max_tokens:
|
|
36278
|
+
max_tokens: 1500,
|
|
36279
36279
|
temperature: 0.3,
|
|
36280
36280
|
});
|
|
36281
36281
|
const content = result?.choices?.[0]?.message?.content;
|
|
@@ -36484,7 +36484,7 @@ class TopologyDiscoveryEngine {
|
|
|
36484
36484
|
const prompt = CORRELATION_PROMPT.replace('{scenes}', scenesText);
|
|
36485
36485
|
const result = await llm.getChatCompletion({
|
|
36486
36486
|
messages: [{ role: 'user', content: prompt }],
|
|
36487
|
-
max_tokens:
|
|
36487
|
+
max_tokens: 2000,
|
|
36488
36488
|
temperature: 0.4,
|
|
36489
36489
|
});
|
|
36490
36490
|
const content = result?.choices?.[0]?.message?.content;
|
|
@@ -40224,12 +40224,38 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
|
|
|
40224
40224
|
const topology = this.trackingEngine.getTopology();
|
|
40225
40225
|
let updated = false;
|
|
40226
40226
|
if (suggestion.type === 'landmark' && suggestion.landmark) {
|
|
40227
|
+
// Calculate a reasonable position for the landmark
|
|
40228
|
+
// Use the first visible camera's position as a starting point, or canvas center
|
|
40229
|
+
let position = suggestion.landmark.position;
|
|
40230
|
+
if (!position || (position.x === 0 && position.y === 0)) {
|
|
40231
|
+
// Find a camera that can see this landmark
|
|
40232
|
+
const visibleCameraId = suggestion.landmark.visibleFromCameras?.[0];
|
|
40233
|
+
const camera = visibleCameraId ? topology.cameras.find(c => c.deviceId === visibleCameraId) : null;
|
|
40234
|
+
if (camera?.floorPlanPosition) {
|
|
40235
|
+
// Position near the camera with some offset
|
|
40236
|
+
const offset = (topology.landmarks?.length || 0) * 30;
|
|
40237
|
+
position = {
|
|
40238
|
+
x: camera.floorPlanPosition.x + 50 + (offset % 100),
|
|
40239
|
+
y: camera.floorPlanPosition.y + 50 + Math.floor(offset / 100) * 30,
|
|
40240
|
+
};
|
|
40241
|
+
}
|
|
40242
|
+
else {
|
|
40243
|
+
// Position in a grid pattern starting from center
|
|
40244
|
+
const landmarkCount = topology.landmarks?.length || 0;
|
|
40245
|
+
const gridSize = 80;
|
|
40246
|
+
const cols = 5;
|
|
40247
|
+
position = {
|
|
40248
|
+
x: 200 + (landmarkCount % cols) * gridSize,
|
|
40249
|
+
y: 100 + Math.floor(landmarkCount / cols) * gridSize,
|
|
40250
|
+
};
|
|
40251
|
+
}
|
|
40252
|
+
}
|
|
40227
40253
|
// Add new landmark to topology
|
|
40228
40254
|
const landmark = {
|
|
40229
40255
|
id: `landmark_${Date.now()}`,
|
|
40230
40256
|
name: suggestion.landmark.name,
|
|
40231
40257
|
type: suggestion.landmark.type,
|
|
40232
|
-
position
|
|
40258
|
+
position,
|
|
40233
40259
|
description: suggestion.landmark.description,
|
|
40234
40260
|
visibleFromCameras: suggestion.landmark.visibleFromCameras,
|
|
40235
40261
|
aiSuggested: true,
|
|
@@ -40240,15 +40266,69 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
|
|
|
40240
40266
|
}
|
|
40241
40267
|
topology.landmarks.push(landmark);
|
|
40242
40268
|
updated = true;
|
|
40243
|
-
this.console.log(`[Discovery] Added landmark: ${landmark.name}`);
|
|
40269
|
+
this.console.log(`[Discovery] Added landmark: ${landmark.name} at (${position.x}, ${position.y})`);
|
|
40270
|
+
}
|
|
40271
|
+
if (suggestion.type === 'zone' && suggestion.zone) {
|
|
40272
|
+
// Create a drawn zone from the discovery zone
|
|
40273
|
+
const zone = suggestion.zone;
|
|
40274
|
+
// Find cameras that see this zone type to determine position
|
|
40275
|
+
const cameraWithZone = suggestion.sourceCameras?.[0];
|
|
40276
|
+
const camera = cameraWithZone ? topology.cameras.find(c => c.deviceId === cameraWithZone || c.name === cameraWithZone) : null;
|
|
40277
|
+
// Create a default polygon near the camera or at a default location
|
|
40278
|
+
let centerX = 300;
|
|
40279
|
+
let centerY = 200;
|
|
40280
|
+
if (camera?.floorPlanPosition) {
|
|
40281
|
+
centerX = camera.floorPlanPosition.x;
|
|
40282
|
+
centerY = camera.floorPlanPosition.y + 80;
|
|
40283
|
+
}
|
|
40284
|
+
// Create a rectangular zone (user can edit later)
|
|
40285
|
+
const size = 100;
|
|
40286
|
+
const drawnZone = {
|
|
40287
|
+
id: `zone_${Date.now()}`,
|
|
40288
|
+
name: zone.name,
|
|
40289
|
+
type: (zone.type || 'custom'),
|
|
40290
|
+
description: zone.description,
|
|
40291
|
+
polygon: [
|
|
40292
|
+
{ x: centerX - size / 2, y: centerY - size / 2 },
|
|
40293
|
+
{ x: centerX + size / 2, y: centerY - size / 2 },
|
|
40294
|
+
{ x: centerX + size / 2, y: centerY + size / 2 },
|
|
40295
|
+
{ x: centerX - size / 2, y: centerY + size / 2 },
|
|
40296
|
+
],
|
|
40297
|
+
};
|
|
40298
|
+
if (!topology.drawnZones) {
|
|
40299
|
+
topology.drawnZones = [];
|
|
40300
|
+
}
|
|
40301
|
+
topology.drawnZones.push(drawnZone);
|
|
40302
|
+
updated = true;
|
|
40303
|
+
this.console.log(`[Discovery] Added zone: ${zone.name} (${zone.type})`);
|
|
40244
40304
|
}
|
|
40245
40305
|
if (suggestion.type === 'connection' && suggestion.connection) {
|
|
40246
40306
|
// Add new connection to topology
|
|
40247
40307
|
const conn = suggestion.connection;
|
|
40308
|
+
// Ensure cameras have floor plan positions for visibility
|
|
40309
|
+
const fromCamera = topology.cameras.find(c => c.deviceId === conn.fromCameraId || c.name === conn.fromCameraId);
|
|
40310
|
+
const toCamera = topology.cameras.find(c => c.deviceId === conn.toCameraId || c.name === conn.toCameraId);
|
|
40311
|
+
// Auto-assign floor plan positions if missing
|
|
40312
|
+
if (fromCamera && !fromCamera.floorPlanPosition) {
|
|
40313
|
+
const idx = topology.cameras.indexOf(fromCamera);
|
|
40314
|
+
fromCamera.floorPlanPosition = {
|
|
40315
|
+
x: 150 + (idx % 3) * 200,
|
|
40316
|
+
y: 150 + Math.floor(idx / 3) * 150,
|
|
40317
|
+
};
|
|
40318
|
+
this.console.log(`[Discovery] Auto-positioned camera: ${fromCamera.name}`);
|
|
40319
|
+
}
|
|
40320
|
+
if (toCamera && !toCamera.floorPlanPosition) {
|
|
40321
|
+
const idx = topology.cameras.indexOf(toCamera);
|
|
40322
|
+
toCamera.floorPlanPosition = {
|
|
40323
|
+
x: 150 + (idx % 3) * 200,
|
|
40324
|
+
y: 150 + Math.floor(idx / 3) * 150,
|
|
40325
|
+
};
|
|
40326
|
+
this.console.log(`[Discovery] Auto-positioned camera: ${toCamera.name}`);
|
|
40327
|
+
}
|
|
40248
40328
|
const newConnection = {
|
|
40249
40329
|
id: `conn_${Date.now()}`,
|
|
40250
|
-
fromCameraId: conn.fromCameraId,
|
|
40251
|
-
toCameraId: conn.toCameraId,
|
|
40330
|
+
fromCameraId: fromCamera?.deviceId || conn.fromCameraId,
|
|
40331
|
+
toCameraId: toCamera?.deviceId || conn.toCameraId,
|
|
40252
40332
|
bidirectional: conn.bidirectional,
|
|
40253
40333
|
// Default exit/entry zones covering full frame
|
|
40254
40334
|
exitZone: [[0, 0], [100, 0], [100, 100], [0, 100]],
|
|
@@ -40262,7 +40342,7 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
|
|
|
40262
40342
|
};
|
|
40263
40343
|
topology.connections.push(newConnection);
|
|
40264
40344
|
updated = true;
|
|
40265
|
-
this.console.log(`[Discovery] Added connection: ${conn.fromCameraId} -> ${conn.toCameraId}`);
|
|
40345
|
+
this.console.log(`[Discovery] Added connection: ${fromCamera?.name || conn.fromCameraId} -> ${toCamera?.name || conn.toCameraId}`);
|
|
40266
40346
|
}
|
|
40267
40347
|
if (updated) {
|
|
40268
40348
|
// Save updated topology
|
|
@@ -42311,6 +42391,12 @@ exports.EDITOR_HTML = `<!DOCTYPE html>
|
|
|
42311
42391
|
for (let i = 1; i < currentZonePoints.length; i++) {
|
|
42312
42392
|
ctx.lineTo(currentZonePoints[i].x, currentZonePoints[i].y);
|
|
42313
42393
|
}
|
|
42394
|
+
// Close the polygon if we have 3+ points
|
|
42395
|
+
if (currentZonePoints.length >= 3) {
|
|
42396
|
+
ctx.closePath();
|
|
42397
|
+
ctx.fillStyle = color;
|
|
42398
|
+
ctx.fill();
|
|
42399
|
+
}
|
|
42314
42400
|
ctx.strokeStyle = strokeColor;
|
|
42315
42401
|
ctx.lineWidth = 2;
|
|
42316
42402
|
ctx.stroke();
|