@blueharford/scrypted-spatial-awareness 0.4.2 → 0.4.4
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/package.json +1 -1
- package/src/main.ts +45 -11
- package/src/ui/editor-html.ts +8 -4
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/main.ts
CHANGED
|
@@ -15,6 +15,8 @@ import sdk, {
|
|
|
15
15
|
Readme,
|
|
16
16
|
} from '@scrypted/sdk';
|
|
17
17
|
import { StorageSettings } from '@scrypted/sdk/storage-settings';
|
|
18
|
+
import * as fs from 'fs';
|
|
19
|
+
import * as path from 'path';
|
|
18
20
|
import {
|
|
19
21
|
CameraTopology,
|
|
20
22
|
createEmptyTopology,
|
|
@@ -35,7 +37,7 @@ import { EDITOR_HTML } from './ui/editor-html';
|
|
|
35
37
|
import { TRAINING_HTML } from './ui/training-html';
|
|
36
38
|
import { TrainingConfig, TrainingLandmark } from './models/training';
|
|
37
39
|
|
|
38
|
-
const { deviceManager, systemManager } = sdk;
|
|
40
|
+
const { deviceManager, systemManager, mediaManager } = sdk;
|
|
39
41
|
|
|
40
42
|
const TRACKING_ZONE_PREFIX = 'tracking-zone:';
|
|
41
43
|
const GLOBAL_TRACKER_ID = 'global-tracker';
|
|
@@ -1044,14 +1046,36 @@ export class SpatialAwarenessPlugin extends ScryptedDeviceBase
|
|
|
1044
1046
|
}
|
|
1045
1047
|
}
|
|
1046
1048
|
|
|
1047
|
-
private
|
|
1049
|
+
private async getFloorPlanPath(): Promise<string> {
|
|
1050
|
+
// Use mediaManager.getFilesPath() for proper persistent storage
|
|
1051
|
+
const filesPath = await mediaManager.getFilesPath();
|
|
1052
|
+
this.console.log('Files path from mediaManager:', filesPath);
|
|
1053
|
+
// Ensure directory exists
|
|
1054
|
+
if (!fs.existsSync(filesPath)) {
|
|
1055
|
+
fs.mkdirSync(filesPath, { recursive: true });
|
|
1056
|
+
}
|
|
1057
|
+
return path.join(filesPath, 'floorplan.png');
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
private async handleFloorPlanRequest(request: HttpRequest, response: HttpResponse): Promise<void> {
|
|
1048
1061
|
if (request.method === 'GET') {
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1062
|
+
try {
|
|
1063
|
+
const floorPlanPath = await this.getFloorPlanPath();
|
|
1064
|
+
this.console.log('Loading floor plan from:', floorPlanPath, 'exists:', fs.existsSync(floorPlanPath));
|
|
1065
|
+
if (fs.existsSync(floorPlanPath)) {
|
|
1066
|
+
const imageBuffer = fs.readFileSync(floorPlanPath);
|
|
1067
|
+
const imageData = 'data:image/png;base64,' + imageBuffer.toString('base64');
|
|
1068
|
+
this.console.log('Floor plan loaded, size:', imageBuffer.length);
|
|
1069
|
+
response.send(JSON.stringify({ imageData }), {
|
|
1070
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1071
|
+
});
|
|
1072
|
+
} else {
|
|
1073
|
+
response.send(JSON.stringify({ imageData: null }), {
|
|
1074
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
} catch (e) {
|
|
1078
|
+
this.console.error('Failed to read floor plan:', e);
|
|
1055
1079
|
response.send(JSON.stringify({ imageData: null }), {
|
|
1056
1080
|
headers: { 'Content-Type': 'application/json' },
|
|
1057
1081
|
});
|
|
@@ -1059,13 +1083,23 @@ export class SpatialAwarenessPlugin extends ScryptedDeviceBase
|
|
|
1059
1083
|
} else if (request.method === 'POST') {
|
|
1060
1084
|
try {
|
|
1061
1085
|
const body = JSON.parse(request.body!);
|
|
1062
|
-
|
|
1086
|
+
const imageData = body.imageData as string;
|
|
1087
|
+
|
|
1088
|
+
// Extract base64 data (remove data:image/xxx;base64, prefix)
|
|
1089
|
+
const base64Data = imageData.replace(/^data:image\/\w+;base64,/, '');
|
|
1090
|
+
const imageBuffer = Buffer.from(base64Data, 'base64');
|
|
1091
|
+
|
|
1092
|
+
const floorPlanPath = await this.getFloorPlanPath();
|
|
1093
|
+
fs.writeFileSync(floorPlanPath, imageBuffer);
|
|
1094
|
+
|
|
1095
|
+
this.console.log('Floor plan saved to:', floorPlanPath, 'size:', imageBuffer.length);
|
|
1063
1096
|
response.send(JSON.stringify({ success: true }), {
|
|
1064
1097
|
headers: { 'Content-Type': 'application/json' },
|
|
1065
1098
|
});
|
|
1066
1099
|
} catch (e) {
|
|
1067
|
-
|
|
1068
|
-
|
|
1100
|
+
this.console.error('Failed to save floor plan:', e);
|
|
1101
|
+
response.send(JSON.stringify({ error: 'Failed to save floor plan' }), {
|
|
1102
|
+
code: 500,
|
|
1069
1103
|
headers: { 'Content-Type': 'application/json' },
|
|
1070
1104
|
});
|
|
1071
1105
|
}
|
package/src/ui/editor-html.ts
CHANGED
|
@@ -346,19 +346,23 @@ export const EDITOR_HTML = `<!DOCTYPE html>
|
|
|
346
346
|
if (topology.floorPlan?.imageData) {
|
|
347
347
|
// Legacy: imageData was stored in topology
|
|
348
348
|
await loadFloorPlanImage(topology.floorPlan.imageData);
|
|
349
|
-
} else if (topology.floorPlan?.type === '
|
|
350
|
-
|
|
349
|
+
} else if (topology.floorPlan?.type === 'blank') {
|
|
350
|
+
blankCanvasMode = true;
|
|
351
|
+
} else {
|
|
352
|
+
// Always try to load from floor-plan endpoint (handles uploaded and missing cases)
|
|
351
353
|
try {
|
|
352
354
|
const fpResponse = await fetch('../api/floor-plan');
|
|
353
355
|
if (fpResponse.ok) {
|
|
354
356
|
const fpData = await fpResponse.json();
|
|
355
357
|
if (fpData.imageData) {
|
|
356
358
|
await loadFloorPlanImage(fpData.imageData);
|
|
359
|
+
// Update topology reference if not set
|
|
360
|
+
if (!topology.floorPlan || topology.floorPlan.type !== 'uploaded') {
|
|
361
|
+
topology.floorPlan = { type: 'uploaded', width: floorPlanImage.width, height: floorPlanImage.height };
|
|
362
|
+
}
|
|
357
363
|
}
|
|
358
364
|
}
|
|
359
365
|
} catch (err) { console.error('Failed to load floor plan:', err); }
|
|
360
|
-
} else if (topology.floorPlan?.type === 'blank') {
|
|
361
|
-
blankCanvasMode = true;
|
|
362
366
|
}
|
|
363
367
|
}
|
|
364
368
|
} catch (e) { console.error('Failed to load topology:', e); }
|