7.8 KiB
appRobotFileservice — REST API
Einziger Consumer ist der Driver (
appRobotDriver). Steuerungen sprechen die appRobotFileservice nie direkt an, sondern schicken FCodes an den Driver, der sie hierher weiterreicht (robot/FCodeClient.js). Die appRobotFileservice ist passiv und driver-agnostisch: sie ruft den Driver nie an, kennt weder dessen URL noch dessen Pose.
Eine eigene Visualisierungs-UI darf direkt zugreifen — sie ist keine Steuerung.
1. Überblick
- Transport: HTTP/REST + JSON.
- Basis-URL:
http://appRobot_Fileservice:2100/api(Container-intern) ·http://thinkcentre.local:2100/api(lokal) - Identität: Programme über
id/Name — nie über Dateipfade. Storage (.gcode+.json-Sidecar) ist intern gekapselt. - Einheiten am Wire: driver-nativ (φ/θ/ψ und
ein Radian,x/y/zin mm) — exakt die G-Code-Strings, die der Driver ausführt. Gespeichert wird in Grad (standardnahe.gcode); die appRobotFileservice rechnet an ihrer Storage-Grenze um. - Auth:
Bearer <FILE_API_KEY>für schreibende Operationen.
2. Datenmodell
Program (Metadaten, aus dem .json-Sidecar)
{ "id": "besteck_spuelmaschine", "name": "Besteck Spülmaschine",
"lineCount": 12, "angleUnit": "deg",
"createdAt": "2025-10-04T10:25:00Z", "updatedAt": "2025-10-04T10:41:00Z" }
ActiveState (aktives Programm + Cursor — Single Source of Truth)
{ "programId": "besteck_spuelmaschine", "cursor": 4, "lineCount": 12,
"currentLine": "G90 G1 x310 y444 z0.5 a1.5708 b-1.5708 c0 e0.12 f1000",
"playing": false, "version": 7 }
currentLineist driver-nativ (Radian) und kommentarfrei — direkt ausführbar. Gespeichert wird in Grad mit Zeitstempel-Kommentar im Kommentarfeld (;).
Pose (vom Driver beim FPoint mitgeschickt)
{ "pose": { "x": 0, "y": 300, "z": 0, "a": 1.5708, "b": -1.5708, "c": 0, "e": 0.12 },
"feedrate": 1000 }
3. FCode ↔ Endpoint-Mapping
Der Driver (robot/FCodeClient.js) übersetzt die FCodes der Steuerungen in diese Endpoints:
| FCode | Endpoint | Antwort an Steuerung (über Driver) |
|---|---|---|
FList |
GET /programs |
Liste (Broadcast) |
FShow [id] |
GET /programs/{id} |
Inhalt in Grad (Broadcast) |
FLoad <id> |
PUT /active |
ActiveState (Broadcast) |
FSave <name> |
POST /programs |
id (Broadcast) |
FClear |
POST /active/clear |
ActiveState (Broadcast) |
FPoint |
POST /active/points |
Bestätigung (Broadcast) |
FPlus |
POST /active/next |
Bewegung → Driver führt aus → Pose-Broadcast |
FMinus |
POST /active/prev |
Bewegung → Driver führt aus → Pose-Broadcast |
FFirst |
POST /active/first |
Bewegung → Driver führt aus → Pose-Broadcast |
FLast |
POST /active/last |
Bewegung → Driver führt aus → Pose-Broadcast |
FGoto <n> |
POST /active/goto |
Bewegung → Driver führt aus → Pose-Broadcast |
FPlay / FStop |
POST /active/play / /stop |
Status (Broadcast) |
4. Endpoints — Programm-Verwaltung
GET /api/programs ← FList
{ "programs": [ { "id": "log", "name": "log", "lineCount": 36 }, … ] }
GET /api/programs/{id} ← FShow
Inhalt + Metadaten — in Grad, wie gespeichert (lesbar):
{ "id": "besteck_spuelmaschine", "displayUnit": "deg",
"lines": [ "G90 G1 x0 y614 z0 a-90.00 b90.00 c0.00 e0 f1000 ;1759566014",
"G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0 f1000 ;1759566052!" ] }
;<epoch>= Aufnahme-Zeitstempel; abschließendes!= Cursor-Zeile.
POST /api/programs ← FSave
{ "name": "Demo C", "fromActive": true } // aus aktivem Puffer
// oder expliziter Inhalt (in Grad):
{ "name": "Demo C", "lines": ["G90 G1 x0 y300 … a90.00 …"], "angleUnit": "deg" }
→ 201 { "id": "demo_c", "lineCount": 12 }
PUT /api/programs/{id} · DELETE /api/programs/{id}
Inhalt ersetzen / umbenennen · löschen (jeweils .gcode und .json).
5. Endpoints — Aktives Programm & Cursor
GET /api/active
Aktuellen ActiveState lesen (inkl. currentLine in Radian).
PUT /api/active ← FLoad
{ "id": "besteck_spuelmaschine" }
→ ActiveState. Nicht-existierendes Programm wird leer angelegt (für Teaching).
POST /api/active/clear ← FClear
Aktives Programm leeren, Cursor → 0.
Stepping — next · prev · first · last · goto
Bewegt den Cursor und gibt die driver-native, ausführbare Zeile (Radian) zurück. Der Driver führt sie selbst aus — der Fileservice pusht nichts.
POST /api/active/next · /prev · /first · /last · /goto { "index": 7 }
{ "cursor": 5, "line": "G90 G1 x310 y444 z30.5 a1.5708 b-1.5708 c0 e0.12 f1000" }
Grenzen: next am Ende / prev am Anfang → CURSOR_OUT_OF_RANGE.
6. Endpoints — Teaching / Aufnahme
POST /api/active/points ← FPoint
Der Driver schickt die aktuelle Pose mit (native Radian-Werte). Die
appRobotFileservice rechnet nach Grad um, formatiert die Zeile (Feedrate,
Zeitstempel als Kommentar ;<epoch>) und hängt sie an.
{ "pose": { "x": 0, "y": 300, "z": 0, "a": 1.5708, "b": -1.5708, "c": 0, "e": 0.12 },
"feedrate": 1000 }
→ 201 { "index": 12, "line": "G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e6.88 f1000 ;1759566014" }
POST /api/active/lines
Rohe Zeile(n) anhängen/einfügen (z. B. Pause G4):
{ "line": "G4 P0.5", "atIndex": 8 }
PUT /api/active/lines/{index} · DELETE /api/active/lines/{index}
Einzelne Zeile ersetzen / löschen.
7. Endpoints — Playback
POST /api/active/play ← FPlay
{ "mode": "run", "fromStart": false }
POST /api/active/stop ← FStop
8. Fehler-Envelope
Konsistent mit dem Driver (doc/ToDo_5_API.md): { type, code, message, input }.
Der Driver reicht Fileservice-Fehler (FILE_ERROR) an die Steuerung zurück.
code |
Bedeutung |
|---|---|
PROGRAM_NOT_FOUND |
{id} existiert nicht |
INVALID_NAME |
unzulässiger Name (kein Pfad) |
EMPTY_PROGRAM |
FLoad auf Programm ohne gültige Zeile |
CURSOR_OUT_OF_RANGE |
next/prev/goto über die Grenzen |
NO_ACTIVE_PROGRAM |
Aktion erfordert geladenes Programm |
FILE_ERROR |
Storage-Fehler (.gcode/.json) |
{ "type": "error", "code": "PROGRAM_NOT_FOUND", "message": "no program 'demo_x'", "input": "demo_x" }
9. Beispiel-Flows
Teaching-Session (Joystick → Aufnahme)
Steuerung → Driver: FLoad demo_c → Driver: PUT /api/active {id:"demo_c"}
Steuerung → Driver: G1 … (Arm bewegen, lokal — Fileservice unbeteiligt)
Steuerung → Driver: FPoint → Driver hängt Live-Pose an,
POST /api/active/points { pose, feedrate }
… weitere Punkte …
Steuerung → Driver: FSave "Demo C" → Driver: POST /api/programs {name,fromActive:true}
Playback-Session (schrittweise)
Steuerung → Driver: FList → GET /api/programs
Steuerung → Driver: FLoad demo_c → PUT /api/active
Steuerung → Driver: FFirst → POST /api/active/first → {line (Radian)}
Driver: receiveGCode(line) → Bewegung
Driver: Pose-Broadcast an alle WS-Clients
Steuerung → Driver: FPlus … / FPlay
10. Verweise
API.md— Driver-Endpunkte (/api/position, WS:2095)robot/FCodeClient.js— Gateway-Implementierung im DriverToDo_6b_FileHandling.md— gelöste DetailproblemeappRobotFileservice/README.md— Konzept, Einheiten, Dateiformat, Konfiguration