From 2ebe7b709bfc4280cfeffb9fa0af635f65555600 Mon Sep 17 00:00:00 2001
From: chk <79915315+ChKendel@users.noreply.github.com>
Date: Wed, 10 Jun 2026 12:13:34 +0200
Subject: [PATCH] send callibration
---
docker-compose.yaml | 2 +-
public/calibration.html | 23 +++++++++++++++++++-
server/server.js | 48 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/docker-compose.yaml b/docker-compose.yaml
index d1ca47c..d040ed3 100755
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -17,5 +17,5 @@ services:
ports:
- "2093:2093"
command: >
- /bin/bash -lc "npm ci || npm install && node server/server.js"
+ /bin/bash -lc "apt-get update -qq && apt-get install -y --no-install-recommends python3-pip && pip3 install --quiet --no-cache-dir opencv-python-headless numpy && npm ci || npm install && node server/server.js"
restart: unless-stopped
diff --git a/public/calibration.html b/public/calibration.html
index 3fa5157..8f62262 100644
--- a/public/calibration.html
+++ b/public/calibration.html
@@ -235,7 +235,7 @@
-
+
@@ -451,6 +451,27 @@
}
});
+ // "NPZ speichern" → an Webcam-Service übertragen
+ document.getElementById('btn-upload-npz').addEventListener('click', async () => {
+ const camera = document.getElementById('cam-select-calib').value;
+ if (!camera) { logC('⚠ Bitte zuerst eine Kamera auswählen.'); return; }
+
+ logC(`NPZ wird an Webcam-Service übertragen (${camera}) …`);
+ try {
+ const r = await fetch('/api/calibration/upload-npz', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ camera }),
+ });
+ const d = await r.json();
+ if (d.error) { logC(`❌ Fehler: ${d.error}`); return; }
+ logC(`✅ Gespeichert: ${d.webcam?.saved} (${d.size} Bytes)`);
+ logC(` calibrationUrl: ${d.webcam?.calibrationUrl}`);
+ } catch (err) {
+ logC(`❌ Fehler: ${err}`);
+ }
+ });
+
// "Kalibrierung berechnen" – SSE-Stream lesen
document.getElementById('btn-compute-calib').addEventListener('click', async () => {
const camera = document.getElementById('cam-select-calib').value;
diff --git a/server/server.js b/server/server.js
index 107e284..0ea7090 100755
--- a/server/server.js
+++ b/server/server.js
@@ -426,6 +426,54 @@ app.post('/api/calibration/compute', async (req, res) => {
}
});
+/**
+ * POST /api/calibration/upload-npz
+ * Liest {camera}_calibration.npz aus der aktuellen Session und
+ * schickt sie per PUT an den Webcam-Service.
+ * Body: { camera: "cam0" }
+ */
+app.post('/api/calibration/upload-npz', async (req, res) => {
+ try {
+ const { camera } = req.body ?? {};
+ if (!camera) return res.status(400).json({ error: '"camera" parameter fehlt' });
+ if (!WEBCAM_URL) return res.status(501).json({ error: 'WEBCAM_URL ist nicht konfiguriert' });
+
+ const session = await findLatestCalibSession();
+ if (!session) return res.status(400).json({ error: 'Keine Kalibrierungs-Session vorhanden' });
+
+ const npzPath = path.join(calibDataDir, session, `${camera}_calibration.npz`);
+
+ try {
+ await fsPromises.access(npzPath);
+ } catch {
+ return res.status(404).json({
+ error: `Datei nicht gefunden: ${camera}_calibration.npz — bitte zuerst "Kalibrierung berechnen".`
+ });
+ }
+
+ const npzData = await fsPromises.readFile(npzPath);
+ const putUrl = new URL(`/api/cameras/${camera}/calibration`, WEBCAM_URL).toString();
+
+ const putRes = await fetch(putUrl, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/octet-stream' },
+ body: npzData,
+ });
+
+ if (!putRes.ok) {
+ const text = await putRes.text();
+ return res.status(putRes.status).json({ error: `Webcam-Service: ${putRes.status} – ${text}` });
+ }
+
+ const result = await putRes.json();
+ return res.json({ ok: true, camera, session, size: npzData.length, webcam: result });
+
+ } catch (err) {
+ console.error('calibration/upload-npz error:', err);
+ return res.status(500).json({ error: String(err) });
+ }
+});
+
async function checkServiceReachability(name, url) {
try {
const controller = new AbortController();