8.0 KiB
robot.json – Zugriff via appRobotDriver
Stand: 2026-06-15
Beschreibt die geplante Umstellung: robot.json kommt vom appRobotDriver, nicht mehr aus einer lokalen Datei.
Ist-Zustand
appRobotHoming liest und schreibt die Roboter-Konfiguration direkt aus einer
lokalen Datei:
ROBOT_JSON = process.env.ROBOT_JSON
|| 'scripts/robot_1781069752019.json'
Die Python-Skripte erhalten den Dateipfad als CLI-Argument (-robot, --robot).
Alle Kalibrierungs-Endpoints schreiben ebenfalls in diese Datei.
Problem: Der appRobotDriver besitzt die maßgebliche Konfiguration — nicht das Homing-System. Nach einem Neustart könnten Konfiguration und Driver auseinanderlaufen.
Ziel-Zustand
Startup GET {ROBOT_URL}/api/robot/config → robot.json laden
Kalibrierung schreiben → lokal anpassen → POST {ROBOT_URL}/api/robot/config
Python-Skripte → weiterhin lokale Datei (Cache) (unverändert)
appRobotDriver ist die Single Source of Truth.
appRobotHoming hält eine lokale Kopie (Cache-Datei) nur für die Dauer eines
Laufs — Python-Skripte müssen nicht angepasst werden.
appRobotDriver API (Platzhalter)
Die genaue API ist noch zu klären. Annahmen:
| Aktion | Endpoint | Body / Antwort |
|---|---|---|
| Konfiguration lesen | GET {ROBOT_URL}/api/robot/config |
→ JSON (robot.json-Inhalt) |
| Konfiguration schreiben | POST {ROBOT_URL}/api/robot/config |
Body: JSON (robot.json-Inhalt), → { ok: true } |
Sobald die echten Endpoints bekannt sind, diese Tabelle und die Implementierung
(server/robotConfig.js) entsprechend anpassen.
Implementierungsplan
Schritt 1 — server/robotConfig.js (neu)
Kapselt den gesamten robot.json-Zugriff. server.js und editRobot.js importieren
nur noch diese Funktionen — kein direktes fsPromises.readFile / writeFile mehr.
// server/robotConfig.js (ESM)
import fsPromises from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROBOT_URL = process.env.ROBOT_URL || '';
// Lokale Cache-Datei: bleibt als Fallback und für Python-Skripte
const ROBOT_JSON = process.env.ROBOT_JSON
|| path.join(__dirname, '..', 'scripts', 'robot_1781069752019.json');
/**
* Lädt robot.json.
* Reihenfolge: (1) ROBOT_URL/api/robot/config, (2) lokale Datei als Fallback.
* Schreibt das Ergebnis immer in die lokale Cache-Datei (für Python-Skripte).
*/
export async function fetchRobot() {
if (ROBOT_URL) {
const res = await fetch(new URL('/api/robot/config', ROBOT_URL));
if (!res.ok) throw new Error(`Driver ${res.status}: ${await res.text()}`);
const data = await res.json();
// Cache für Python-Skripte aktualisieren
await fsPromises.writeFile(ROBOT_JSON, JSON.stringify(data, null, 2), 'utf8');
return data;
}
// Fallback: lokale Datei (Entwicklung ohne Driver)
return JSON.parse(await fsPromises.readFile(ROBOT_JSON, 'utf8'));
}
/**
* Speichert robot.json.
* Schreibt immer in lokale Cache-Datei; sendet zusätzlich an Driver wenn konfiguriert.
*/
export async function pushRobot(data) {
await fsPromises.writeFile(ROBOT_JSON, JSON.stringify(data, null, 2), 'utf8');
if (ROBOT_URL) {
const res = await fetch(new URL('/api/robot/config', ROBOT_URL), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!res.ok) throw new Error(`Driver ${res.status}: ${await res.text()}`);
}
}
/** Pfad zur lokalen Cache-Datei – wird an Python-Skripte als -robot-Argument übergeben. */
export const robotCachePath = ROBOT_JSON;
Schritt 2 — server/editRobot.js anpassen
readRobot() und writeRobot() sind die einzigen I/O-Primitiven in editRobot.js.
Sie müssen auf fetchRobot() / pushRobot() umgestellt werden.
Aktuell:
async function readRobot(robotPath) {
return JSON.parse(await fsPromises.readFile(robotPath, 'utf8'));
}
async function writeRobot(robotPath, data) {
await fsPromises.writeFile(robotPath, JSON.stringify(data, null, 2), 'utf8');
}
Neu:
import { fetchRobot, pushRobot } from './robotConfig.js';
async function readRobot(_robotPath) { // _robotPath ignoriert – Quelle ist Driver
return fetchRobot();
}
async function writeRobot(_robotPath, data) {
return pushRobot(data);
}
Alle exportierten Funktionen (assignByZRange, setArmMarkerSpin, adoptXAxis,
setJointOriginYZ, …) bleiben unverändert — sie rufen intern readRobot /
writeRobot auf.
Der
robotPath-Parameter bleibt in den Signaturen erhalten (Kompatibilität), wird aber ignoriert. Alternativ: alle Aufrufer inserver.jsbereinigen und Parameter entfernen (Folgeschritt).
Schritt 3 — server/server.js anpassen
3a — Python-Skripte erhalten weiterhin die Cache-Datei
// Vorher:
import { ROBOT_JSON } from './config.js'; // oder const direkt
// '-robot', ROBOT_JSON
// Nachher:
import { robotCachePath } from './robotConfig.js';
// '-robot', robotCachePath
Die Pipeline (runBoardPipeline, runHoming) fetcht robot.json einmal vor dem
Lauf via fetchRobot(), um den Cache zu aktualisieren:
import { fetchRobot, robotCachePath } from './robotConfig.js';
async function runBoardPipeline(runDir, send, refSet) {
// Cache aktualisieren bevor Python startet
await fetchRobot();
// Python-Skripte erhalten robotCachePath wie bisher
const script1Args = [..., '-robot', robotCachePath, ...];
// …
}
3b — GET /api/robot liest via fetchRobot()
// Vorher:
app.get('/api/robot', async (req, res) => {
const robot = JSON.parse(await fsPromises.readFile(ROBOT_JSON, 'utf8'));
return res.json(robot);
});
// Nachher:
import { fetchRobot } from './robotConfig.js';
app.get('/api/robot', async (req, res) => {
try {
const robot = await fetchRobot();
return res.json(robot);
} catch (err) {
return res.status(502).json({ error: `Driver nicht erreichbar: ${err.message}` });
}
});
3c — Kalibrierungs-Endpoints: kein Änderungsbedarf
Da editRobot.js intern readRobot / writeRobot verwendet und diese umgestellt
werden (Schritt 2), propagieren sich alle Kalibrierungs-Schreibvorgänge automatisch
zum Driver. Kein Änderungsbedarf in den einzelnen Endpoints.
Startup-Verhalten
Beim Start von server.js einmalig robot.json laden und cachen:
// server.js – nach HTTPS-Server-Start
try {
await fetchRobot();
console.log('✅ robot.json vom Driver geladen und gecacht.');
} catch (err) {
console.warn(`⚠ Driver nicht erreichbar – nutze lokale Datei: ${err.message}`);
}
Fallback-Verhalten
| Szenario | Verhalten |
|---|---|
ROBOT_URL nicht gesetzt |
Nur lokale Datei — Entwicklungsmodus, Driver nicht nötig |
| Driver beim Start nicht erreichbar | Warnung, lokale Cache-Datei wird verwendet |
| Driver während Lauf nicht erreichbar | pushRobot() wirft Fehler → Kalibrierungs-Endpoint antwortet 502 |
| Python-Skript schlägt fehl | Kein push nötig (Python schreibt nicht in robot.json) |
Datei-Übersicht nach Umbau
| Datei | Rolle |
|---|---|
server/robotConfig.js (neu) |
fetchRobot(), pushRobot(), robotCachePath |
server/editRobot.js |
readRobot / writeRobot delegieren an robotConfig.js |
server/server.js |
importiert robotCachePath statt lokalem ROBOT_JSON; ruft fetchRobot() vor Pipelines |
scripts/robot_1781069752019.json |
Bleibt als lokale Cache-Datei; nicht mehr primäre Quelle der Wahrheit |
Offene Fragen
- Genaue Endpoints des appRobotDriver für GET / POST robot.json bestätigen
- Soll der Driver eine Versions-/Konflikterkennung haben (z.B. ETag /
updatedAt)? - Soll
pushRobot()bei Driver-Fehler still auf lokal-only zurückfallen, oder hard fail? - Authentifizierung zwischen appRobotHoming und appRobotDriver nötig?