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), Playback (Programm abspielen) sowie einen
Browser-basierten Datei-Browser auf Port 2100.
Rolle in der Architektur
Steuerungen → appRobotDriver → appRobotFileservice ← Browser (Port 2100)
(Joystick, …) (Gateway) (dieses Projekt)
│
[Senden-Modus, lokales Netz]
└──► appRobotDriver WS
- 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. - Browser spricht direkt mit dem Fileservice (Port 2100). Im Senden-Modus sendet der Fileservice die G-Code-Zeile server-seitig an den Driver — der Browser verbindet sich nie direkt mit dem Driver.
- 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 (Standard-G-Code, lesbar):
a/b/c/ein Grad,x/y/zin mm. - Am Wire / zum Driver ist alles driver-nativ:
a/b/c/ein Radian. - Die Umrechnung passiert ausschließlich hier (
src/gcode/units.js).
Dateiformat
.gcode ist die einzige verbindliche Positions-Abfolge — reiner Standard-G-Code,
Zeitstempel und Cursor-Marker stehen im Kommentarfeld:
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.;!(Ausrufezeichen am Ende des Kommentars) = Cursor-Marker: zeigt die zuletzt angefahrene Zeile. Primäre Cursor-Quelle beim Lesen. Direkt im Texteditor sichtbar.<id>.jsonist ein Sidecar mit Metadaten (Name, Zeiten,lineCount,angleUnit).cursorim Sidecar dient nur als Fallback für Altdateien ohne;!-Marker.
Start
npm install
npm start # http://localhost:2100
npm test # jest
HTTP (kein TLS) — der Service ist intern. Konfiguration via Env-Variablen (s. u.).
Konfiguration (Env)
| Variable | Default | Zweck |
|---|---|---|
FILE_SERVICE_PORT |
2100 |
Port |
STORAGE_DIR |
./GCodeFiles |
Wurzel-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) |
DRIVER_WS_URL |
– | WS-URL des appRobotDriver (z. B. wss://appRobotDriver:2095); leer → Senden-Modus deaktiviert |
DRIVER_TIMEOUT_MS |
10000 |
Maximale Wartezeit auf Driver-Antwort (ms) |
API (Kurzüberblick)
Programme
| Endpoint | Methode | Zweck |
|---|---|---|
GET /api/programs?dir= |
GET | Programme auflisten |
POST /api/programs |
POST | Programm anlegen |
DELETE /api/programs/:id?dir= |
DELETE | Programm löschen |
GET /api/programs/:id/download |
GET | .gcode-Datei herunterladen |
Ordner
| Endpoint | Methode | Zweck |
|---|---|---|
GET /api/folders?dir= |
GET | Unterordner auflisten |
POST /api/folders |
POST | Unterordner anlegen |
DELETE /api/folders/:name?dir= |
DELETE | Unterordner (rekursiv) löschen |
Aktives Programm
| FCode (am Driver) | Endpoint | Hinweis |
|---|---|---|
FList |
GET /api/programs |
|
FLoad <id> |
PUT /api/active |
{ id, dir } |
FClear |
POST /api/active/clear |
|
FPoint |
POST /api/active/points |
|
FPlus / FMinus |
POST /api/active/next / /prev |
?execute=true → auch an Driver senden |
FFirst / FLast |
POST /api/active/first / /last |
?execute=true → auch an Driver senden |
FGoto <n> |
POST /api/active/goto |
|
FPlay / FStop |
POST /api/active/play / /stop |
|
| — | DELETE /api/active/lines/:index |
Zeile löschen |
Senden-Modus (?execute=true)
POST /api/active/next?execute=true bewegt den Cursor UND sendet die G-Code-Zeile
an den Driver (server-seitig). Der Endpoint wartet auf die Driver-Antwort:
- Erfolg (M114-Broadcast) → HTTP 200
{ cursor, line, driverPos } - Driver-Fehler → HTTP 502
{ error, message } - Timeout → HTTP 504
Konfiguration
| Endpoint | Zweck |
|---|---|
GET /api/health |
Liveness-Check |
GET /api/config |
{ driverConfigured: bool } — ob DRIVER_WS_URL gesetzt ist |
Projektstruktur
index.js Einstiegspunkt (startet den Server)
src/
config.js Env-Konfiguration (inkl. driverWsUrl, driverTimeoutMs)
server.js Express-App (createApp, /api/config, /api/health)
errors.js Fehler-Envelope + Middleware
auth.js Bearer-Auth (für Schreibzugriffe)
driverClient.js WS-Client zum Driver (Senden-Modus)
gcode/units.js Grad↔Radian, Zeilenformat, Cursor-Marker (;!)
store/fileStore.js .gcode + .json Persistenz (mit dir-Support, max. 5 Ebenen)
active/activeState.js Aktives Programm + Cursor (Singleton, ;!-Persistenz)
routes/programs.js /api/programs* inkl. /download
routes/active.js /api/active* inkl. ?execute=true
routes/folders.js /api/folders*
public/
index.html Browser-UI (Datei-Browser + Stepping + Senden-Modus)
index.css Design-System (dark theme, CSS-Variablen)
test/
units.test.js Einheiten + Cursor-Marker-Funktionen
fileStore.test.js Persistenz-Tests (;!-Marker, dir-Support)
activeState.test.js ActiveState-Tests (Teaching, Stepping, Cursor-Persistenz)
driverClient.test.js WS-Client (Erfolg, Fehler, Timeout)
doc/
fileBrowser.md Browser-UI Ist-Zustand
commandsFromGCodeFile.md Senden-Modus Konzept + Implementierungsplan
draft_filehandeling.md Original-Konzept (historisch)
draft_filehandeling_API.md Original-API-Entwurf (historisch)
GCodeFiles/ Programm-Storage zur Laufzeit
Status
Produktiv einsetzbar. Offen: Upload via Browser, Inline-Editor, Live-Updates via SSE
(statt 5s-Polling). Siehe doc/fileBrowser.md.