Script Callibrate
This commit is contained in:
@@ -6,6 +6,7 @@ import fs from 'fs';
|
||||
import fsPromises from 'fs/promises';
|
||||
import { fileURLToPath } from 'url';
|
||||
import process from 'process';
|
||||
import { spawn } from 'child_process';
|
||||
import { WebcamClient } from './webcamClient.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
@@ -332,6 +333,79 @@ app.post('/api/calibration/foto', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/calibration/compute
|
||||
* Führt scripts/callibriate.py für eine Kamera aus.
|
||||
* Body: { camera: "cam0" }
|
||||
* Antwortet als Server-Sent Events (SSE): jede Zeile stdout/stderr als
|
||||
* data: {"type":"log","text":"..."}
|
||||
* Abschluss:
|
||||
* data: {"type":"done","exitCode":0}
|
||||
*/
|
||||
const PYTHON_BIN = process.env.PYTHON_BIN || 'python';
|
||||
const calibScriptPath = path.join(__dirname, '..', 'scripts', 'callibriate.py');
|
||||
|
||||
app.post('/api/calibration/compute', async (req, res) => {
|
||||
const { camera } = req.body ?? {};
|
||||
if (!camera) return res.status(400).json({ error: '"camera" parameter fehlt' });
|
||||
|
||||
const session = await findLatestCalibSession();
|
||||
if (!session) return res.status(400).json({ error: 'Keine Kalibrierungs-Session vorhanden' });
|
||||
|
||||
const sessionDir = path.join(calibDataDir, session);
|
||||
|
||||
// SSE-Header
|
||||
res.setHeader('Content-Type', 'text/event-stream');
|
||||
res.setHeader('Cache-Control', 'no-cache');
|
||||
res.setHeader('Connection', 'keep-alive');
|
||||
res.flushHeaders();
|
||||
|
||||
const send = (obj) => res.write(`data: ${JSON.stringify(obj)}\n\n`);
|
||||
|
||||
send({ type: 'log', text: `▶ Session: ${session}` });
|
||||
send({ type: 'log', text: `▶ Kamera: ${camera}` });
|
||||
send({ type: 'log', text: `▶ Script: ${calibScriptPath}` });
|
||||
send({ type: 'log', text: '' });
|
||||
|
||||
const proc = spawn(PYTHON_BIN, [
|
||||
calibScriptPath,
|
||||
'--camera', camera,
|
||||
'--input-dir', sessionDir,
|
||||
'--output-dir', sessionDir,
|
||||
]);
|
||||
|
||||
// stdout zeilenweise weiterleiten
|
||||
let stdoutBuf = '';
|
||||
proc.stdout.on('data', (chunk) => {
|
||||
stdoutBuf += chunk.toString();
|
||||
const lines = stdoutBuf.split('\n');
|
||||
stdoutBuf = lines.pop(); // letztes (unvollständiges) Fragment behalten
|
||||
for (const line of lines) send({ type: 'log', text: line });
|
||||
});
|
||||
|
||||
// stderr als Warnung weiterleiten
|
||||
let stderrBuf = '';
|
||||
proc.stderr.on('data', (chunk) => {
|
||||
stderrBuf += chunk.toString();
|
||||
const lines = stderrBuf.split('\n');
|
||||
stderrBuf = lines.pop();
|
||||
for (const line of lines) send({ type: 'log', text: `[stderr] ${line}` });
|
||||
});
|
||||
|
||||
proc.on('error', (err) => {
|
||||
send({ type: 'log', text: `Fehler beim Starten: ${err.message}` });
|
||||
send({ type: 'done', exitCode: -1 });
|
||||
res.end();
|
||||
});
|
||||
|
||||
proc.on('close', (code) => {
|
||||
if (stdoutBuf) send({ type: 'log', text: stdoutBuf }); // Rest ausgeben
|
||||
if (stderrBuf) send({ type: 'log', text: `[stderr] ${stderrBuf}` });
|
||||
send({ type: 'done', exitCode: code });
|
||||
res.end();
|
||||
});
|
||||
});
|
||||
|
||||
async function checkServiceReachability(name, url) {
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
|
||||
Reference in New Issue
Block a user