Files
appRobotDriver/doc/fileserviceAPI.md
2026-06-14 11:18:46 +02:00

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/Namenie über Dateipfade. Storage (.gcode + .json-Sidecar) ist intern gekapselt.
  • Einheiten am Wire: driver-nativ (φ/θ/ψ und e in Radian, x/y/z in 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 }

currentLine ist 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/programsFList

{ "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/programsFSave

{ "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/activeFLoad

{ "id": "besteck_spuelmaschine" }

ActiveState. Nicht-existierendes Programm wird leer angelegt (für Teaching).

POST /api/active/clearFClear

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/pointsFPoint

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/playFPlay

{ "mode": "run", "fromStart": false }

POST /api/active/stopFStop


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 Driver
  • ToDo_6b_FileHandling.md — gelöste Detailprobleme
  • appRobotFileservice/README.md — Konzept, Einheiten, Dateiformat, Konfiguration