@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/plugin.zip CHANGED
Binary file
@@ -36275,7 +36275,7 @@ class TopologyDiscoveryEngine {
36275
36275
  ],
36276
36276
  },
36277
36277
  ],
36278
- max_tokens: 500,
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: 800,
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: suggestion.landmark.position || { x: 0, y: 0 },
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();