Claude API
This commit is contained in:
111
doc/API.md
Normal file
111
doc/API.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# API-Referenz
|
||||
|
||||
Der Driver stellt zwei Schnittstellen bereit:
|
||||
|
||||
| Schnittstelle | Zweck | Port (Container) | Port (Host, docker-compose) |
|
||||
|---------------|-------|------------------|------------------------------|
|
||||
| **Input WebSocket** | Steuerbefehle empfangen, Status-Antworten senden | `2095` (`PORT`) | `2096` |
|
||||
| **Info-/Status-Server (HTTPS)** | Statusübersicht + statische Web-UI | `2098` | `2098` |
|
||||
|
||||
---
|
||||
|
||||
## 1. Input WebSocket (`wss://…:2095`)
|
||||
|
||||
Implementiert in `server/InputWS.js`. Eingehende Nachrichten sind **Plain-Text-Strings**.
|
||||
Die Antwortlogik unterscheidet bewusst zwischen **gezielten Antworten** (nur an den
|
||||
Anfrager) und **Broadcasts** (an alle verbundenen Clients).
|
||||
|
||||
### Antwort-Routing
|
||||
|
||||
| Eingabe | Verarbeitung | Antwort | Empfänger |
|
||||
|---------|--------------|---------|-----------|
|
||||
| `Ping` | Heartbeat, wird geloggt | `Ping` | **nur Anfrager** (gezielt) |
|
||||
| `M114` | Statusabfrage | Positions-JSON (siehe unten) | **nur Anfrager** (gezielt) |
|
||||
| G-Code (`G1`, `G90`, `G91`, `G28`, `M1`, `M92`, …) | Bewegung/Zustandsänderung | aktuelles Positions-JSON | **alle Clients** (Broadcast) |
|
||||
| Datei-Befehle (`FShow`, `FList`, `FPoint`, `FPlus`, `FMinus`, `FLoad`, `FSave`, `FClear`, `M20/23/28/29`) | Datei-/Log-Verwaltung | Befehlsergebnis | **alle Clients** (Broadcast) |
|
||||
| alles andere | – | Fehler-Envelope | **nur Anfrager** (gezielt) |
|
||||
|
||||
**Begründung der Trennung:** Eine Bewegung ändert die Roboterposition — das ist ein
|
||||
Status-Update, das jeder Client (z. B. die Simulation) sehen soll → Broadcast. Eine
|
||||
reine Abfrage (`Ping`, `M114`) ist eine direkte Antwort an den Anfrager → gezielt.
|
||||
|
||||
> **Hinweis:** Feinere Zielsteuerung der Datei-Befehle (z. B. `FShow` als
|
||||
> Anfrager-only-Antwort) sowie `FFirst`/`FLast` gehören zur Datei-Verwaltung in
|
||||
> **ToDo 4** und bleiben hier bewusst unverändert.
|
||||
|
||||
### Positions-JSON (`M114` / Broadcast nach Bewegung)
|
||||
|
||||
```json
|
||||
{
|
||||
"position": { "x": 0, "y": 30, "z": 0, "a": 0, "b": 0, "c": 0 },
|
||||
"motorCounts":{ "x": 0, "y": 0, "z": 0, "a": 0, "b": 0, "c": 0, "e": 0 }
|
||||
}
|
||||
```
|
||||
|
||||
- `position` — kartesische Pose + Orientierung (`a`/`b`/`c` = ϕ/ϴ/Ψ in rad).
|
||||
- `motorCounts` — aktuelle Motor-/Achswerte.
|
||||
|
||||
### Fehler-Envelope (maschinenlesbar)
|
||||
|
||||
Bei unbekannter Eingabe oder Verarbeitungsfehler erhält **nur der Anfrager**:
|
||||
|
||||
```json
|
||||
{ "type": "error", "code": "UNKNOWN_COMMAND", "message": "Unrecognized input", "input": "<original>" }
|
||||
```
|
||||
|
||||
| `code` | Bedeutung |
|
||||
|--------|-----------|
|
||||
| `UNKNOWN_COMMAND` | Eingabe passt auf keinen bekannten Befehl |
|
||||
| `GCODE_ERROR` | Fehler beim Parsen/Ausführen eines G-Code-Befehls |
|
||||
| `FILE_ERROR` | Fehler bei einem Datei-Befehl |
|
||||
|
||||
Erfolgs-Antworten (`Ping`, Positions-JSON) bleiben aus Kompatibilitätsgründen im
|
||||
bisherigen Rohformat; das Envelope gilt nur für Fehler.
|
||||
|
||||
---
|
||||
|
||||
## 2. Info-/Status-Server (`https://…:2098`)
|
||||
|
||||
Implementiert in `server/InfoServer.js`. Selbstsigniertes Zertifikat.
|
||||
|
||||
### Statische Web-UI
|
||||
`GET /` · `GET /app.js` · `GET /style.css` · `GET /allApps.css`
|
||||
|
||||
### `GET /api/status`
|
||||
|
||||
Liefert Verbindungs- und Health-Informationen als JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"generatedAt": "2026-06-08T12:00:00.000Z",
|
||||
"health": { "ok": false, "connectedSenders": 1, "totalSenders": 3 },
|
||||
"clients": ["127.0.0.1"],
|
||||
"senders": [
|
||||
{
|
||||
"name": "Base",
|
||||
"state": "connected",
|
||||
"url": "fluidNcBase.local",
|
||||
"isTestMode": false,
|
||||
"error": null,
|
||||
"reconnectAttempt": 0,
|
||||
"reconnectTimer": false,
|
||||
"health": "ok",
|
||||
"reason": null
|
||||
}
|
||||
],
|
||||
"lastCommands": ["2026-06-08T…: G1 X10 Y10"],
|
||||
"lastPings": ["2026-06-08T… 127.0.0.1 : Ping"]
|
||||
}
|
||||
```
|
||||
|
||||
- `health.ok` — `true`, wenn **alle** Sender verbunden sind.
|
||||
- pro Sender: `state` ∈ `connected | connecting | reconnecting | disconnected`;
|
||||
`health` ∈ `ok | warning | disconnected`.
|
||||
|
||||
### `GET /api/position`
|
||||
|
||||
Liefert die aktuelle Roboterposition (gleiches Positions-JSON wie oben),
|
||||
**unabhängig** von laufenden Senderverbindungen.
|
||||
|
||||
### Sonstige Pfade
|
||||
`404 Not found`.
|
||||
@@ -6,16 +6,31 @@ Die Schnittstellen sollen klar und vorhersagbar antworten. Steuerbefehle brauche
|
||||
|
||||
## Aufgaben
|
||||
|
||||
- [ ] WebSocket-Antwortlogik strukturieren
|
||||
- [x] WebSocket-Antwortlogik strukturieren
|
||||
- Steuerbefehle erhalten gezielte Responses
|
||||
- `Ping`, `M114`, Statusabfragen und Fehlermeldungen getrennt behandeln
|
||||
- [ ] Broadcasts nur dort verwenden, wo sie sinnvoll sind
|
||||
- → `server/InputWS.js` als klarer Router; `Ping`/`M114` antworten gezielt an den Anfrager
|
||||
- [x] Broadcasts nur dort verwenden, wo sie sinnvoll sind
|
||||
- Broadcasts für Status-Updates, nicht für direkte Steuerantworten
|
||||
- [ ] `InfoServer` um detaillierte Statusinformationen erweitern
|
||||
- Senderverbindungen
|
||||
- Health-Checks
|
||||
- letzte Befehle / Pings
|
||||
- [ ] API-Endpunkte klar dokumentieren
|
||||
- `/api/status`
|
||||
- `/api/position`
|
||||
- [ ] Fehlermeldungen konsistent und maschinenlesbar machen
|
||||
- → Bewegung (G-Code) broadcastet die neue Position; `Ping`/`M114` sind gezielt
|
||||
- [x] `InfoServer` um detaillierte Statusinformationen erweitern
|
||||
- Senderverbindungen · Health-Checks · letzte Befehle / Pings
|
||||
- → bereits in ToDo 2 angelegt; ergänzt um Top-Level `health`-Summary + `generatedAt`
|
||||
- [x] API-Endpunkte klar dokumentieren
|
||||
- `/api/status` · `/api/position`
|
||||
- → `doc/API.md`
|
||||
- [x] Fehlermeldungen konsistent und maschinenlesbar machen
|
||||
- → einheitliches Fehler-Envelope `{ type, code, message, input }`
|
||||
(`UNKNOWN_COMMAND` / `GCODE_ERROR` / `FILE_ERROR`)
|
||||
|
||||
## Tests
|
||||
|
||||
- `test/InputWS.api.test.js` — gezielte vs. Broadcast-Antworten, Fehler-Envelope
|
||||
- `test/InfoServer.test.js` — Health-Summary + `generatedAt`
|
||||
|
||||
## Bewusst nicht in diesem ToDo
|
||||
|
||||
- Feinere Zielsteuerung der Datei-Befehle (z. B. `FShow` nur an Anfrager) und
|
||||
`FFirst`/`FLast` → gehören zur Datei-Verwaltung in **ToDo 4**.
|
||||
- Erfolgs-Payloads (`Ping`, Positions-JSON) bleiben aus Rückwärtskompatibilität im
|
||||
Rohformat (externe Clients: Simulation/Gamepad); nur Fehler nutzen das Envelope.
|
||||
@@ -6,7 +6,10 @@ Konkrete, im Code identifizierte Fehler beheben — unabhängig von den Architek
|
||||
|
||||
---
|
||||
|
||||
## Bug 1: `TelnetSenderGRBL` — `close`-Event verliert `this`-Kontext
|
||||
## Bug 1: `TelnetSenderGRBL` — `close`-Event verliert `this`-Kontext ✅ ERLEDIGT
|
||||
|
||||
> Behoben im ToDo-2-Refactoring: Der `close`-Handler nutzt jetzt eine Arrow-Function
|
||||
> (`robot/TelnetSenderGRBL.js`), `this` zeigt korrekt auf die Sender-Instanz.
|
||||
|
||||
**Datei:** `robot/TelnetSenderGRBL.js`, Zeile 54–57
|
||||
|
||||
@@ -48,7 +51,11 @@ this.tSocket.on("close", () => {
|
||||
|
||||
---
|
||||
|
||||
## Bug 4: `logs/`-Verzeichnis wird nicht sichergestellt
|
||||
## Bug 4: `logs/`-Verzeichnis wird nicht sichergestellt ✅ ERLEDIGT
|
||||
|
||||
> Behoben: `initInputWS()` ruft `ensureLogDir()` (`fs.mkdirSync('./logs', { recursive: true })`)
|
||||
> beim Start auf. `ensureLogDir` ist exportiert und idempotent.
|
||||
> Test: `test/InputWS.logDir.test.js`.
|
||||
|
||||
**Datei:** `server/InputWS.js`, Zeilen 66–67 und 77–78
|
||||
|
||||
@@ -70,7 +77,11 @@ Der Check prüft `mNew.y` statt `mNew.x`. Wenn `mNew.x` `NaN` oder `Infinity` w
|
||||
|
||||
---
|
||||
|
||||
## Bug 6: `containsMCode` matcht zu breit
|
||||
## Bug 6: `containsMCode` matcht zu breit ✅ ERLEDIGT
|
||||
|
||||
> Behoben: `containsMCode` nutzt jetzt `s === 'M1' || s.startsWith('M1 ')`.
|
||||
> Test: `test/GCode.containsMCode.test.js`.
|
||||
> (Hinweis bleibt: Methode wird im Produktivcode noch nicht aufgerufen.)
|
||||
|
||||
**Datei:** `robot/GCode.js`, Zeile 12
|
||||
|
||||
|
||||
Reference in New Issue
Block a user