2026-06-14 22:46:21 +02:00
2026-06-14 21:45:22 +02:00
2026-06-14 22:46:21 +02:00
2026-06-14 22:46:21 +02:00
2026-06-14 22:21:00 +02:00
2026-06-14 13:40:38 +02:00

appRobotFileservice

Programm-/File-Handling-Service für den AppRobot. Speichert G-Code-Programme (.gcode + .json-Sidecar), hält das aktive Programm + Cursor und unterstützt Teaching (Pose aufnehmen) und Playback (Programm abspielen).

Dieses Projekt wurde aus dem appRobotDriver ausgelagert (vormals GCode.receiveFC, ToDo_4 / ToDo_6b). Konzept und Schnittstelle: doc/draft_filehandeling.md · doc/draft_filehandeling_API.md.

Rolle in der Architektur

Steuerungen → appRobotDriver → appRobotFileservice
(Joystick, …)   (Gateway)        (dieses Projekt, passiv)
  • Steuerungen kennen nur den Driver. Datei-Befehle (FCodes wie FList, FPoint, FPlus) schickt die Steuerung an den Driver, der sie als REST-Aufrufe hierher weiterreicht.
  • Dieser Service ist passiv und driver-agnostisch: er ruft den Driver nie an, kennt weder dessen URL noch dessen Pose. Beim FPoint schickt der Driver die Pose mit.
  • Playback: dieser Service liefert die nächste Zeile driver-nativ (Radian) zurück; ausgeführt wird sie vom Driver.

Einheiten (wichtig)

  • Gespeichert wird in Grad (standardnahe .gcode, lesbar): a/b/c/e in Grad, x/y/z in mm.
  • Am Wire / zum Driver ist alles driver-nativ: a/b/c/e in Radian.
  • Die Umrechnung passiert ausschließlich hier (src/gcode/units.js) — der Driver rechnet nie um.

Dateiformat

.gcode ist die einzige verbindliche Positions-Abfolge — reiner Standard-G-Code, nur der Aufnahme-Zeitstempel steht im Kommentarfeld (;…, standardkonform):

G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 f1000 ;1759566014
G90 G1 x310 y444 z0.5 a90.00 b-90.00 c0.00 e6.88 f1000 ;1759566112
  • ;<epoch> = Aufnahme-Zeitstempel. Sonst nichts Service-Internes in der .gcode.
  • <id>.json ist ein Sidecar mit Zusatz-Infos: Name, Zeiten, lineCount, angleUnit und der cursor (Index der zuletzt angefahrenen Zeile).
  • Der Cursor lebt zur Laufzeit als In-Memory-Index (schnelles Stepping ohne Neuschreiben) und wird beim Speichern/Entladen ins .json geschrieben — die .gcode bleibt sauber.
  • Migration: alte .gcode-Dateien mit !-Cursor-Marker werden beim ersten Lesen automatisch übernommen (Marker raus, Cursor ins .json).

Start

npm install
npm start          # http://localhost:2100
npm test           # jest

HTTP (kein TLS) — der Service ist intern (Driver → Service). TLS kann später analog zum Driver-InfoServer ergänzt werden.

API (Kurzüberblick)

Vollständig in doc/draft_filehandeling_API.md.

FCode (am Driver) Endpoint
FList GET /api/programs
FShow [id] GET /api/programs/:id
FSave <name> POST /api/programs
FLoad <id> PUT /api/active
FClear POST /api/active/clear
FPoint POST /api/active/points
FPlus / FMinus POST /api/active/next / /prev
FFirst / FLast POST /api/active/first / /last
FGoto <n> POST /api/active/goto
FPlay / FStop POST /api/active/play / /stop

Beispiel:

# Teaching: leeres Programm aktiv, Pose aufnehmen, speichern
curl -X PUT  localhost:2100/api/active        -H 'content-type: application/json' -d '{"id":"demo_c"}'
curl -X POST localhost:2100/api/active/points -H 'content-type: application/json' \
     -d '{"pose":{"x":0,"y":300,"z":0,"a":1.5708,"b":-1.5708,"c":0,"e":0},"feedrate":1000}'
curl -X POST localhost:2100/api/programs      -H 'content-type: application/json' -d '{"name":"Demo C","fromActive":true}'

# Playback: laden, erste Zeile (Radian) holen → der Driver führt sie aus
curl -X PUT  localhost:2100/api/active       -H 'content-type: application/json' -d '{"id":"demo_c"}'
curl -X POST localhost:2100/api/active/first

Hinweis: PUT /api/active legt ein nicht existierendes Programm leer an (für Teaching). EMPTY_PROGRAM/CURSOR_OUT_OF_RANGE betreffen nur das Stepping/Playback.

Konfiguration (Env)

Variable Default Zweck
FILE_SERVICE_PORT 2100 Port
STORAGE_DIR ./GCodeFiles Verzeichnis für .gcode + .json
FILE_EXT gcode gcode oder ngc
STORE_ANGLE_UNIT deg Speichereinheit der Winkel
FILE_API_KEY Bearer-Token für Schreibzugriffe (fehlt → offen, Dev)

Projektstruktur

index.js                 Einstiegspunkt (startet den Server)
src/
  config.js              Env-Konfiguration
  server.js              Express-App (createApp)
  errors.js              Fehler-Envelope + Middleware
  auth.js                Bearer-Auth (für Schreibzugriffe)
  gcode/units.js         Grad↔Radian, Zeilenformat, Cursor-/Kommentar-Helfer
  store/fileStore.js     .gcode + .json Persistenz (id-basiert, kein Pfad-Zugriff)
  active/activeState.js  aktives Programm + Cursor (Single Source of Truth)
  routes/programs.js     /api/programs*
  routes/active.js       /api/active*
test/                    jest (units, fileStore, activeState)
doc/                     Konzept + API (Drafts)
GCodeFiles/              Programm-Storage (zur Laufzeit)

Status

Erste lauffähige Umsetzung. Offen u. a.: WebSocket-Event-Kanal (Live-Cursor), Playlists („nächste File"), benannte Labels im Sidecar, TLS. Siehe „Offene Fragen" in doc/draft_filehandeling.md.

Description
speichert GCode und macht diesen GCode der appRobotDriver zugänglich.
Readme 267 KiB
Languages
JavaScript 60.8%
HTML 30.2%
CSS 9%