Compare commits
6 Commits
v0.9.1-bet
...
v0.9.1-bet
| Author | SHA1 | Date | |
|---|---|---|---|
| 23756b82a9 | |||
| 3df73e89e3 | |||
| 4026fcc60c | |||
| 3687c28239 | |||
| 68b282d170 | |||
| f265a30994 |
132
CHANGELOG.md
Normal file
132
CHANGELOG.md
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [0.9.1-beta12] – 2026-04-25
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fehlermeldung bei falschen MQTT-Zugangsdaten ist jetzt verständlich: `Falsche MQTT-Zugangsdaten (falscher Benutzername, Passwort oder Device-ID)` statt kryptischem `CONNACK failed: 20020005`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta11] – 2026-04-25
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Drucker-IP wird automatisch bereinigt wenn der Nutzer versehentlich den Port miteingibt (z.B. `192.168.1.102:9883` → `192.168.1.102`)
|
||||||
|
- Settings-Modal: Hinweis erscheint wenn ein `:` in der IP erkannt wird
|
||||||
|
- `docker-compose.yml`: `.env` wird als Volume in den Container gemountet – Einstellungen bleiben nach `docker-compose restart` erhalten
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta10] – 2026-04-25
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- `start.sh` – startet die Bridge per Docker, baut das Image automatisch beim ersten Aufruf
|
||||||
|
- Tests: pytest-Suite (19 Tests) für API-State, Moonraker-Endpunkte, Settings; Installations-Smoke-Test (`test_install.sh`)
|
||||||
|
- Settings-Modal öffnet sich beim ersten Start automatisch wenn keine Zugangsdaten hinterlegt sind
|
||||||
|
|
||||||
|
### Geändert
|
||||||
|
- README (DE + EN): Schnellstart zeigt jetzt `./start.sh` statt manuellem `docker build`
|
||||||
|
- README: LAN-Modus korrekt als Drucker-Menüoption beschrieben (kein WLAN-Bezug)
|
||||||
|
- README: Versionsnummer wird ab jetzt automatisch bei jedem Release aktualisiert
|
||||||
|
- `extract_credentials`: kein `--write-env` mehr empfohlen – Werte im ⚙-Menü eintragen
|
||||||
|
- Dockerfile im Release-Repo: Pfade ohne `05_scripts/`-Präfix (direkt aus Repo-Root)
|
||||||
|
- `release.sh`: Dockerfile für Release-Repo automatisch per `sed` angepasst
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Restdruckzeit (`remain_time`) wird jetzt korrekt aus `print/report` übernommen und in der UI angezeigt
|
||||||
|
- Übersetzung: „Schrittweite" und „Ziel"-Placeholder in Temperatureingaben werden jetzt korrekt übersetzt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta9] – 2026-04-25
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- OrcaSlicer-Profil (`kobra_x_orcaslicer_preset.zip`) als Release-Asset
|
||||||
|
- `release.sh`: OrcaSlicer-Profil wird automatisch ins Release-Repo kopiert und hochgeladen
|
||||||
|
|
||||||
|
### Geändert
|
||||||
|
- README: `extract_credentials` ohne `--write-env`, Werte manuell ins ⚙-Menü eintragen
|
||||||
|
- README: Docker-Schnellstart vereinfacht (kein `.env` anlegen vor dem Start nötig)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta8] – 2026-04-25
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- Restdruckzeit-Anzeige in der UI (≈ Xh Ym verbleibend) aus `remain_time`-Feld des Druckers
|
||||||
|
- Settings-Modal: Verbindungseinstellungen und Self-Update direkt im Browser
|
||||||
|
- Self-Update: Bridge prüft Gitea-Release-API auf neue Versionen und aktualisiert sich selbst
|
||||||
|
|
||||||
|
### Geändert
|
||||||
|
- Bridge startet im Offline-Modus wenn Drucker nicht erreichbar (kein Absturz)
|
||||||
|
- Verbinden/Trennen-Button im Header
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta7] – 2026-04-22
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- Offline-Start: Bridge läuft auch ohne MQTT-Verbindung, verbindet automatisch sobald Drucker erreichbar
|
||||||
|
- Verbinden/Trennen-Button im Header
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta6] – 2026-04-20
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- Release-ZIPs: `kx-bridge-linux.zip`, `kx-bridge-windows.zip`, `anycubic-certs.zip` mit Zertifikaten
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- PyInstaller frozen-Binary: `__file__` durch `sys.executable`-Pfad ersetzt (Cert-Pfad-Fix)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta5] – 2026-04-19
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- `kx-bridge.exe` (Windows) wird automatisch via GitHub Actions gebaut
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta4] – 2026-04-18
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- `release.sh`: baut Linux-Binary und Windows-EXE, lädt alle Assets auf Gitea hoch
|
||||||
|
- Englische README (`README.en.md`)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- `progress` und `filename` werden bei `stoped`/`canceled` korrekt auf 0 zurückgesetzt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta3] – 2026-04-17
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- Print-Speed-Card (Leise / Normal / Sport)
|
||||||
|
- Übersetzungen (DE/EN) vervollständigt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta2] – 2026-04-17
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Temperatursteuerung während eines laufenden Drucks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.1-beta1] – 2026-04-17
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- UI-Komplettüberarbeitung: Settings-Modal, Self-Update, Dashboard, Responsive Design
|
||||||
|
- Neue Drucker-Zustände: `pausing`, `paused`, `resuming`, `resumed`, `stopping`
|
||||||
|
- `release.sh`: Version-Bump und Release-Sync Skript
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.9.0-beta1] – 2026-04-10
|
||||||
|
|
||||||
|
### Neu
|
||||||
|
- Erster öffentlicher Release
|
||||||
|
- Docker-Deployment, Linux-Binary, `extract_credentials`-Tool
|
||||||
|
- Moonraker-kompatible HTTP/WebSocket-Bridge für den Anycubic Kobra X
|
||||||
|
- AMS Einziehen/Ausziehen, Licht- und Lüftersteuerung
|
||||||
|
- Web-UI mit Dashboard, Temperaturkarten, Achsensteuerung
|
||||||
12
Dockerfile
12
Dockerfile
@@ -2,15 +2,15 @@ FROM python:3.11-slim
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY 05_scripts/requirements.txt .
|
COPY requirements.txt .
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg && rm -rf /var/lib/apt/lists/*
|
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg && rm -rf /var/lib/apt/lists/*
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
COPY 05_scripts/kobrax_moonraker_bridge.py .
|
COPY kobrax_moonraker_bridge.py .
|
||||||
COPY 05_scripts/env_loader.py .
|
COPY env_loader.py .
|
||||||
COPY 05_scripts/kobrax_client.py .
|
COPY kobrax_client.py .
|
||||||
COPY 05_scripts/anycubic_slicer.crt .
|
COPY anycubic_slicer.crt .
|
||||||
COPY 05_scripts/anycubic_slicer.key .
|
COPY anycubic_slicer.key .
|
||||||
|
|
||||||
EXPOSE 7125
|
EXPOSE 7125
|
||||||
|
|
||||||
|
|||||||
50
README.en.md
50
README.en.md
@@ -1,6 +1,6 @@
|
|||||||
# KX-Bridge – Anycubic Kobra X Moonraker Bridge
|
# KX-Bridge – Anycubic Kobra X Moonraker Bridge
|
||||||
|
|
||||||
**Version:** 0.9.1-beta5
|
**Version:** 0.9.1-beta10
|
||||||
**Status:** Public Beta – suitable for home users, feedback welcome
|
**Status:** Public Beta – suitable for home users, feedback welcome
|
||||||
|
|
||||||
KX-Bridge is a Moonraker-compatible HTTP/WebSocket bridge for the **Anycubic Kobra X** 3D printer. It allows you to control the printer through OrcaSlicer and other Moonraker-compatible software — no Klipper, no Raspberry Pi required.
|
KX-Bridge is a Moonraker-compatible HTTP/WebSocket bridge for the **Anycubic Kobra X** 3D printer. It allows you to control the printer through OrcaSlicer and other Moonraker-compatible software — no Klipper, no Raspberry Pi required.
|
||||||
@@ -24,7 +24,7 @@ KX-Bridge is a Moonraker-compatible HTTP/WebSocket bridge for the **Anycubic Kob
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Anycubic Kobra X on your local network (LAN, no Wi-Fi client isolation)
|
- Anycubic Kobra X on your local network, with **LAN mode enabled** (printer menu → enable LAN mode)
|
||||||
- Printer MQTT credentials (→ see [Extracting credentials](#extracting-credentials))
|
- Printer MQTT credentials (→ see [Extracting credentials](#extracting-credentials))
|
||||||
- Docker **or** Python 3.9+ **or** the pre-built Linux binary
|
- Docker **or** Python 3.9+ **or** the pre-built Linux binary
|
||||||
|
|
||||||
@@ -33,24 +33,28 @@ KX-Bridge is a Moonraker-compatible HTTP/WebSocket bridge for the **Anycubic Kob
|
|||||||
## Quick start – Docker (recommended)
|
## Quick start – Docker (recommended)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Create .env
|
# 1. Start the bridge
|
||||||
cp .env.example .env
|
./start.sh
|
||||||
# Fill in your printer data (→ extract_credentials)
|
```
|
||||||
|
|
||||||
# 2. Start the bridge
|
`start.sh` builds the Docker image automatically on first run and starts the bridge.
|
||||||
docker compose up -d
|
|
||||||
|
```
|
||||||
|
# 2. Open the web UI: http://BRIDGE-IP:7125
|
||||||
|
# → Settings (⚙) open automatically on first start
|
||||||
|
# → Enter your credentials (→ see Extracting credentials)
|
||||||
|
|
||||||
# 3. In OrcaSlicer: add printer → "Moonraker" → http://BRIDGE-IP:7125
|
# 3. In OrcaSlicer: add printer → "Moonraker" → http://BRIDGE-IP:7125
|
||||||
```
|
```
|
||||||
|
|
||||||
Check logs:
|
Check logs:
|
||||||
```bash
|
```bash
|
||||||
docker compose logs -f
|
docker-compose logs -f
|
||||||
```
|
```
|
||||||
|
|
||||||
Update:
|
Stop:
|
||||||
```bash
|
```bash
|
||||||
docker compose pull && docker compose up -d
|
docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -59,11 +63,11 @@ docker compose pull && docker compose up -d
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
chmod +x kx-bridge
|
chmod +x kx-bridge
|
||||||
./kx-bridge --printer-ip 192.168.x.x --username userXXXX --password XXXXX \
|
./kx-bridge
|
||||||
--device-id XXXXX --mode-id 20030
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Or place a `.env` file in the same directory — the bridge reads it automatically.
|
Open the web UI: `http://localhost:7125`
|
||||||
|
→ Settings (⚙) open automatically and guide you through the initial setup.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -71,32 +75,31 @@ Or place a `.env` file in the same directory — the bridge reads it automatical
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install aiohttp
|
pip install aiohttp
|
||||||
python kobrax_moonraker_bridge.py --printer-ip 192.168.x.x ...
|
|
||||||
# Or fill in .env and start without arguments
|
|
||||||
python kobrax_moonraker_bridge.py
|
python kobrax_moonraker_bridge.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Open the web UI: `http://localhost:7125`
|
||||||
|
→ Settings (⚙) open automatically on first start.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Extracting credentials
|
## Extracting credentials
|
||||||
|
|
||||||
The MQTT credentials are printer-specific and are generated on first connection with AnycubicSlicerNext. The `extract_credentials` tool reads them from the memory of the running slicer.
|
The MQTT credentials are printer-specific and are generated on first connection with AnycubicSlicerNext. The `extract_credentials` tool reads them from the memory of the running slicer.
|
||||||
|
|
||||||
**Requirement:** AnycubicSlicerNext must be running and connected to the printer.
|
**Requirement:** AnycubicSlicerNext must be running and connected to the printer (printer status is shown).
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
```
|
```
|
||||||
extract_credentials.exe --write-env
|
extract_credentials.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
Writes the found credentials directly to `.env`.
|
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
chmod +x extract_credentials
|
chmod +x extract_credentials
|
||||||
./extract_credentials --write-env
|
./extract_credentials
|
||||||
```
|
```
|
||||||
|
|
||||||
### Output
|
### Output
|
||||||
@@ -114,10 +117,13 @@ chmod +x extract_credentials
|
|||||||
Device-ID xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (hits: 3504)
|
Device-ID xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (hits: 3504)
|
||||||
Printer IP 192.168.x.x (hits: 3036)
|
Printer IP 192.168.x.x (hits: 3036)
|
||||||
=======================================================
|
=======================================================
|
||||||
|
|
||||||
Hint: pass --write-env to save credentials to '.env'.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Enter the displayed values in the bridge settings:
|
||||||
|
Open web UI → **⚙ Settings** → fill in the fields → **Save & Restart**
|
||||||
|
|
||||||
|
> If the result looks uncertain: `--verbose` shows all found candidates.
|
||||||
|
|
||||||
All credentials are **processed locally only** — nothing is sent to external servers.
|
All credentials are **processed locally only** — nothing is sent to external servers.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
265
README.md
265
README.md
@@ -1,25 +1,9 @@
|
|||||||
# KX-Bridge
|
# KX-Bridge – Anycubic Kobra X Moonraker Bridge
|
||||||
|
|
||||||
Verbindet den Anycubic Kobra X mit OrcaSlicer – ohne Klipper, ohne Raspberry Pi.
|
**Version:** 0.9.1-beta10
|
||||||
|
**Status:** Public Beta – für Heimanwender geeignet, Feedback willkommen
|
||||||
|
|
||||||
KX-Bridge läuft auf deinem PC oder NAS und stellt eine Moonraker-kompatible Schnittstelle bereit, über die OrcaSlicer den Drucker direkt steuern kann: Druckstart, Temperatur, Fortschritt, Pause/Fortsetzen/Abbrechen, AMS-Farbwechsel, Druckgeschwindigkeit und mehr.
|
KX-Bridge ist eine Moonraker-kompatible HTTP/WebSocket-Bridge für den **Anycubic Kobra X** 3D-Drucker. Sie ermöglicht die Steuerung des Druckers über OrcaSlicer und andere Moonraker-kompatible Software, ohne dass Klipper oder ein Raspberry Pi benötigt wird.
|
||||||
|
|
||||||
**Version:** 0.9.1-beta5
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Enthaltene Dateien
|
|
||||||
|
|
||||||
| Datei | Beschreibung |
|
|
||||||
|-------|-------------|
|
|
||||||
| `kobrax_moonraker_bridge.py` | Bridge-Hauptprogramm |
|
|
||||||
| `kx-bridge` | Vorkompilierte Linux-Binary |
|
|
||||||
| `extract_credentials.exe` | Zugangsdaten aus AnycubicSlicerNext auslesen (Windows) |
|
|
||||||
| `extract_credentials` | Zugangsdaten aus AnycubicSlicerNext auslesen (Linux) |
|
|
||||||
| `kobra_x_orcaslicer_preset.zip` | OrcaSlicer-Druckerprofil für den Kobra X |
|
|
||||||
| `bridge.sh` | Service-Manager für Linux |
|
|
||||||
| `Dockerfile` / `docker-compose.yml` | Docker-Deployment |
|
|
||||||
| `.env.example` | Konfigurationsvorlage |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -40,93 +24,135 @@ KX-Bridge läuft auf deinem PC oder NAS und stellt eine Moonraker-kompatible Sch
|
|||||||
|
|
||||||
## Voraussetzungen
|
## Voraussetzungen
|
||||||
|
|
||||||
- Anycubic Kobra X im LAN-Modus (Drucker muss über LAN erreichbar sein, nicht nur über Anycubic-Cloud)
|
- Anycubic Kobra X im lokalen Netzwerk, mit aktiviertem **LAN-Modus** (Drucker-Menü → LAN-Modus einschalten)
|
||||||
- PC, NAS oder Server im gleichen Netzwerk (Windows oder Linux)
|
- MQTT-Credentials des Druckers (→ siehe [Credentials extrahieren](#credentials-extrahieren))
|
||||||
- Docker oder Python 3.9+
|
- Docker **oder** Python 3.9+ **oder** direkt die Linux-Binary
|
||||||
- MQTT-Zugangsdaten des Druckers → [Schritt 1](#schritt-1-zugangsdaten-ermitteln)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Schnellstart
|
## Schnellstart – Docker (empfohlen)
|
||||||
|
|
||||||
### Schritt 1: Zugangsdaten ermitteln
|
|
||||||
|
|
||||||
Die Bridge benötigt druckerspezifische MQTT-Zugangsdaten.
|
|
||||||
|
|
||||||
> **Wichtig:** Der Drucker muss sich im LAN-Modus befinden. Nur wenn der Drucker direkt über LAN (nicht ausschließlich über die Anycubic-Cloud) erreichbar ist, können die Zugangsdaten ermittelt und die Bridge genutzt werden.
|
|
||||||
|
|
||||||
AnycubicSlicerNext starten und mit dem Drucker verbinden (bis der Drucker-Status angezeigt wird), dann:
|
|
||||||
|
|
||||||
**Windows:**
|
|
||||||
```
|
|
||||||
extract_credentials.exe --write-env
|
|
||||||
```
|
|
||||||
|
|
||||||
**Linux:**
|
|
||||||
```bash
|
|
||||||
chmod +x extract_credentials
|
|
||||||
./extract_credentials --write-env
|
|
||||||
```
|
|
||||||
|
|
||||||
Die Zugangsdaten werden automatisch in `.env` gespeichert.
|
|
||||||
|
|
||||||
> Falls das Ergebnis unsicher wirkt: `--verbose` zeigt alle gefundenen Kandidaten. Den richtigen Wert manuell in `.env` eintragen.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Schritt 2: Konfiguration prüfen
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
# 1. Bridge starten
|
||||||
# .env öffnen und Werte kontrollieren
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
`start.sh` baut das Docker-Image automatisch beim ersten Aufruf und startet die Bridge.
|
||||||
|
|
||||||
|
```
|
||||||
|
# 2. Web-UI öffnen: http://BRIDGE-IP:7125
|
||||||
|
# → Einstellungen (⚙) öffnen sich automatisch beim ersten Start
|
||||||
|
# → Zugangsdaten eintragen (→ siehe Credentials extrahieren)
|
||||||
|
|
||||||
|
# 3. In OrcaSlicer: Drucker → "Moonraker" → http://BRIDGE-IP:7125
|
||||||
|
```
|
||||||
|
|
||||||
|
Logs prüfen:
|
||||||
|
```bash
|
||||||
|
docker-compose logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Stoppen:
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Schritt 3: Bridge starten
|
## Schnellstart – Binary (Linux)
|
||||||
|
|
||||||
**Option A – Docker (empfohlen):**
|
|
||||||
```bash
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
Läuft im Hintergrund, startet automatisch nach Systemneustart.
|
|
||||||
|
|
||||||
**Option B – Linux Binary:**
|
|
||||||
```bash
|
```bash
|
||||||
chmod +x kx-bridge
|
chmod +x kx-bridge
|
||||||
./kx-bridge
|
./kx-bridge
|
||||||
# Oder mit Service-Manager:
|
|
||||||
./bridge.sh start
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Option C – Python direkt:**
|
Web-UI öffnen: `http://localhost:7125`
|
||||||
|
→ Einstellungen (⚙) öffnen sich automatisch und führen durch die Erstkonfiguration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schnellstart – Python direkt
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install aiohttp
|
pip install aiohttp
|
||||||
python kobrax_moonraker_bridge.py
|
python kobrax_moonraker_bridge.py
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
Web-UI öffnen: `http://localhost:7125`
|
||||||
|
→ Einstellungen (⚙) öffnen sich automatisch beim ersten Start.
|
||||||
### Schritt 4: OrcaSlicer-Profil installieren
|
|
||||||
|
|
||||||
1. `kobra_x_orcaslicer_preset.zip` in OrcaSlicer importieren:
|
|
||||||
Datei → Konfigurationen importieren → ZIP auswählen
|
|
||||||
2. Anycubic Kobra X als Drucker auswählen
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Schritt 5: OrcaSlicer verbinden
|
## Credentials extrahieren
|
||||||
|
|
||||||
1. Drucker-Einstellungen öffnen
|
Die MQTT-Zugangsdaten sind druckerspezifisch und werden beim ersten Verbindungsaufbau mit dem AnycubicSlicerNext generiert. Das Tool `extract_credentials` liest sie aus dem RAM des laufenden Slicers aus.
|
||||||
|
|
||||||
|
**Voraussetzung:** AnycubicSlicerNext muss gestartet und mit dem Drucker verbunden sein (Drucker-Status wird angezeigt).
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
```
|
||||||
|
extract_credentials.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x extract_credentials
|
||||||
|
./extract_credentials
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ausgabe
|
||||||
|
|
||||||
|
```
|
||||||
|
[*] Prozess gefunden: AnycubicSlicerNext.exe (PID 1234)
|
||||||
|
[*] 1986 Speichersegmente gelesen (738.8 MB)
|
||||||
|
[*] Analysiere ... 100% (739 MB)
|
||||||
|
|
||||||
|
=======================================================
|
||||||
|
ERGEBNISSE
|
||||||
|
=======================================================
|
||||||
|
Username userXXXXXXXXXX (Treffer: 47)
|
||||||
|
Password *************** (Treffer: 1046)
|
||||||
|
Device-ID xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (Treffer: 3504)
|
||||||
|
Drucker-IP 192.168.x.x (Treffer: 3036)
|
||||||
|
=======================================================
|
||||||
|
```
|
||||||
|
|
||||||
|
Die angezeigten Werte in die Bridge-Einstellungen übertragen:
|
||||||
|
Web-UI öffnen → **⚙ Einstellungen** → Felder ausfüllen → **Speichern & Neustart**
|
||||||
|
|
||||||
|
> Falls das Ergebnis unsicher wirkt: `--verbose` zeigt alle gefundenen Kandidaten.
|
||||||
|
|
||||||
|
Alle Credentials werden **ausschließlich lokal verarbeitet** — keine Übertragung an externe Server.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Konfiguration (.env)
|
||||||
|
|
||||||
|
```env
|
||||||
|
PRINTER_IP=192.168.x.x # IP des Druckers
|
||||||
|
MQTT_PORT=9883 # Standard, nicht ändern
|
||||||
|
MQTT_USERNAME=userXXXXXXXX # Beginnt mit "user"
|
||||||
|
MQTT_PASSWORD=XXXXXXXXXXXXXX # ~15 Zeichen, gemischt
|
||||||
|
DEVICE_ID=xxxxxxxx... # 32-stelliger Hex-String
|
||||||
|
MODE_ID=20030 # Kobra X Standard
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OrcaSlicer verbinden
|
||||||
|
|
||||||
|
1. Drucker hinzufügen → **Anycubic Kobra X** (oder generischer Klipper-Drucker)
|
||||||
2. Verbindungstyp: **Moonraker**
|
2. Verbindungstyp: **Moonraker**
|
||||||
3. Adresse: `http://IP-DES-BRIDGE-PC:7125` eintragen
|
3. IP: `http://BRIDGE-HOST:7125`
|
||||||
4. Auf „Test" klicken – bei erfolgreicher Verbindung erscheint eine Bestätigungsmeldung
|
4. Verbindung testen → sollte "Online" anzeigen
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Web-UI
|
## Web-UI
|
||||||
|
|
||||||
Die Bridge stellt unter `http://BRIDGE-IP:7125` eine Web-Oberfläche bereit:
|
Die Bridge stellt unter `http://BRIDGE-HOST:7125` eine Web-Oberfläche bereit:
|
||||||
|
|
||||||
| Bereich | Funktion |
|
| Bereich | Funktion |
|
||||||
|---------|----------|
|
|---------|----------|
|
||||||
@@ -136,55 +162,56 @@ Die Bridge stellt unter `http://BRIDGE-IP:7125` eine Web-Oberfläche bereit:
|
|||||||
| Druckgeschwindigkeit | Leise / Normal / Sport |
|
| Druckgeschwindigkeit | Leise / Normal / Sport |
|
||||||
| Lüfter / Licht | Lüfterdrehzahl und Drucklicht |
|
| Lüfter / Licht | Lüfterdrehzahl und Drucklicht |
|
||||||
| AMS | Filament einziehen / ausziehen |
|
| AMS | Filament einziehen / ausziehen |
|
||||||
| Kamera | Live-Vorschau (falls vom Drucker unterstützt) |
|
| Kamera | Live-Vorschau (falls Drucker unterstützt) |
|
||||||
| ⚙ Einstellungen | MQTT-Zugangsdaten, Poll-Intervall, Self-Update |
|
| ⚙ Einstellungen | MQTT-Zugangsdaten, Poll-Intervall, Self-Update |
|
||||||
|
|
||||||
### Self-Update
|
### Self-Update
|
||||||
|
|
||||||
Über das ⚙-Menü in der Web-UI kann die Bridge auf neue Versionen prüfen und sich selbst aktualisieren — ohne Neuinstallation. Nach dem Download startet sie automatisch neu.
|
Über das ⚙-Menü in der Web-UI kann die Bridge auf neue Versionen prüfen und sich selbst aktualisieren — ohne Neuinstallation. Nach dem Download startet die Bridge automatisch mit der neuen Version neu.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## bridge.sh – Service-Manager (Linux)
|
## bridge.sh (Linux Service-Manager)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bridge.sh start # Im Hintergrund starten
|
./bridge.sh start # Bridge im Hintergrund starten
|
||||||
./bridge.sh stop # Beenden
|
./bridge.sh stop # Bridge beenden
|
||||||
./bridge.sh restart # Neustarten
|
./bridge.sh restart # Neustarten
|
||||||
./bridge.sh status # Status anzeigen
|
./bridge.sh status # Status und Port prüfen
|
||||||
./bridge.sh log 50 # Letzte 50 Log-Zeilen
|
./bridge.sh log 50 # Letzte 50 Log-Zeilen
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Docker – Nützliche Befehle
|
## Druckerzustände
|
||||||
|
|
||||||
```bash
|
Die Bridge übersetzt die internen Kobra-Zustände in Moonraker-kompatible Zustände:
|
||||||
docker compose up -d # Starten
|
|
||||||
docker compose down # Stoppen
|
| Kobra-Zustand | Bedeutung |
|
||||||
docker compose logs -f # Logs verfolgen
|
|---------------|-----------|
|
||||||
docker compose pull && docker compose up -d # Update
|
| free | Bereit |
|
||||||
```
|
| printing / busy | Druckt |
|
||||||
|
| pausing / paused | Pausiert |
|
||||||
|
| resuming / resumed | Wird fortgesetzt |
|
||||||
|
| stopping / stoped | Wird gestoppt |
|
||||||
|
| finished | Abgeschlossen |
|
||||||
|
| canceled | Abgebrochen |
|
||||||
|
| failed | Fehler |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Fehlerbehebung
|
## Fehlerbehebung
|
||||||
|
|
||||||
**Port 7125 belegt:**
|
**Port 7125 bereits belegt:**
|
||||||
```bash
|
```bash
|
||||||
./bridge.sh stop
|
./bridge.sh stop # oder: fuser -k 7125/tcp
|
||||||
./bridge.sh start
|
./bridge.sh start
|
||||||
```
|
```
|
||||||
|
|
||||||
**Verbindungstest in OrcaSlicer schlägt fehl:**
|
**Credentials ungültig / Verbindung abgelehnt:**
|
||||||
- Firewall prüfen: Port 7125 muss erreichbar sein
|
- AnycubicSlicerNext starten, mit Drucker verbinden, `extract_credentials` erneut ausführen
|
||||||
- Bridge-Log prüfen: `./bridge.sh log` oder `docker compose logs`
|
- Falls das Ergebnis unsicher wirkt: `extract_credentials --verbose` zeigt alle Kandidaten an
|
||||||
- Drucker-IP in `.env` korrekt?
|
- Den richtigen Kandidaten manuell in `.env` eintragen und Bridge neu starten
|
||||||
|
|
||||||
**Zugangsdaten werden abgelehnt:**
|
|
||||||
- AnycubicSlicerNext starten, mit Drucker verbinden
|
|
||||||
- `extract_credentials --verbose` ausführen und alle Kandidaten prüfen
|
|
||||||
- Richtigen Wert manuell in `.env` eintragen, Bridge neu starten
|
|
||||||
|
|
||||||
**Temperaturänderungen werden ignoriert:**
|
**Temperaturänderungen werden ignoriert:**
|
||||||
- Während eines laufenden Drucks werden Temperaturänderungen über einen separaten Kanal gesendet — das ist normal und wird von der Bridge automatisch erkannt.
|
- Während eines laufenden Drucks werden Temperaturänderungen über einen separaten Kanal gesendet — das ist normal und wird von der Bridge automatisch erkannt.
|
||||||
@@ -192,21 +219,26 @@ docker compose pull && docker compose up -d # Update
|
|||||||
**Docker: Permission denied:**
|
**Docker: Permission denied:**
|
||||||
```bash
|
```bash
|
||||||
sudo usermod -aG docker $USER
|
sudo usermod -aG docker $USER
|
||||||
# Neu einloggen, dann erneut versuchen
|
# Neu einloggen
|
||||||
|
```
|
||||||
|
|
||||||
|
**Docker: .env nicht gefunden:**
|
||||||
|
```bash
|
||||||
|
# .env muss im gleichen Verzeichnis wie docker-compose.yml liegen
|
||||||
|
cp .env.example .env && nano .env
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Konfigurationsreferenz (.env)
|
## Logs
|
||||||
|
|
||||||
| Parameter | Beschreibung | Beispiel |
|
```bash
|
||||||
|-----------|-------------|---------|
|
# Docker
|
||||||
| `PRINTER_IP` | IP-Adresse des Druckers | `192.168.1.100` |
|
docker compose logs -f kx-bridge
|
||||||
| `MQTT_PORT` | MQTT-Port (nicht ändern) | `9883` |
|
|
||||||
| `MQTT_USERNAME` | Benutzername (beginnt mit „user") | `userXXXXXXXXXX` |
|
# Binary / Python
|
||||||
| `MQTT_PASSWORD` | Passwort (~15 Zeichen) | `***` |
|
tail -f /tmp/bridge.log # bei Nutzung von bridge.sh
|
||||||
| `DEVICE_ID` | Geräte-ID (32 Hex-Zeichen) | `xxxxxxxx...` |
|
```
|
||||||
| `MODE_ID` | Modell-ID (Kobra X Standard) | `20030` |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -214,14 +246,11 @@ sudo usermod -aG docker $USER
|
|||||||
|
|
||||||
- Die Bridge bindet standardmäßig auf `0.0.0.0:7125` — nur im lokalen Netzwerk nutzen
|
- Die Bridge bindet standardmäßig auf `0.0.0.0:7125` — nur im lokalen Netzwerk nutzen
|
||||||
- `.env` enthält Drucker-Credentials — nicht öffentlich teilen
|
- `.env` enthält Drucker-Credentials — nicht öffentlich teilen
|
||||||
- Alle Zugangsdaten werden ausschließlich lokal verarbeitet — keine Übertragung an externe Server
|
- Die Credentials sind druckerspezifisch und haben keinen Zugang zu Anycubic-Cloud-Diensten
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Hinweis zur Nutzung
|
## Lizenz & Rechtliches
|
||||||
|
|
||||||
Dieses Projekt dient der privaten Nutzung und der Herstellung von Interoperabilität zwischen dem Anycubic Kobra X und freier Software (OrcaSlicer).
|
Dieses Projekt entstand durch Interoperabilitätsforschung gem. §69e UrhG.
|
||||||
|
Ausschließlich für private, nicht-kommerzielle Nutzung.
|
||||||
`extract_credentials` liest ausschließlich den Arbeitsspeicher des auf deinem eigenen PC laufenden AnycubicSlicerNext-Prozesses. Es werden keine Daten übertragen oder gespeichert, außer in die lokale `.env`-Datei.
|
|
||||||
|
|
||||||
Das Projekt steht in keiner Verbindung zu Anycubic und wird nicht kommerziell betrieben.
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ services:
|
|||||||
image: kx-bridge:latest
|
image: kx-bridge:latest
|
||||||
build: .
|
build: .
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
volumes:
|
||||||
|
- ./.env:/app/.env
|
||||||
ports:
|
ports:
|
||||||
- "7125:7125"
|
- "7125:7125"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -863,6 +863,7 @@ nav.bottom-nav{display:none;position:fixed;bottom:0;left:0;right:0;
|
|||||||
<div class="modal-field">
|
<div class="modal-field">
|
||||||
<label id="lbl-printer-ip">Drucker-IP</label>
|
<label id="lbl-printer-ip">Drucker-IP</label>
|
||||||
<input type="text" id="s-printer-ip" placeholder="192.168.x.x">
|
<input type="text" id="s-printer-ip" placeholder="192.168.x.x">
|
||||||
|
<small id="lbl-ip-hint" style="color:#f80;display:none"></small>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-field">
|
<div class="modal-field">
|
||||||
<label id="lbl-mqtt-port">MQTT-Port</label>
|
<label id="lbl-mqtt-port">MQTT-Port</label>
|
||||||
@@ -1162,7 +1163,7 @@ var LANG_DE={
|
|||||||
confirm_cancel:'Druck wirklich abbrechen?',
|
confirm_cancel:'Druck wirklich abbrechen?',
|
||||||
settings_title:'Einstellungen',settings_connection:'Verbindung',settings_poll:'Poll-Intervall',settings_version:'Version',
|
settings_title:'Einstellungen',settings_connection:'Verbindung',settings_poll:'Poll-Intervall',settings_version:'Version',
|
||||||
settings_save:'Speichern & Neustart',settings_printer_ip:'Drucker-IP',settings_mqtt_port:'MQTT-Port',
|
settings_save:'Speichern & Neustart',settings_printer_ip:'Drucker-IP',settings_mqtt_port:'MQTT-Port',
|
||||||
settings_username:'MQTT-Benutzername',settings_password:'MQTT-Passwort',settings_device_id:'Device-ID',settings_mode_id:'Mode-ID',
|
settings_username:'MQTT-Benutzername',settings_password:'MQTT-Passwort',settings_device_id:'Device-ID',settings_mode_id:'Mode-ID',hint_ip_no_port:'Nur IP-Adresse, kein Port (z.B. 192.168.1.102)',
|
||||||
update_check:'Auf Updates prüfen',update_checking:'Prüfe...',update_available:'verfügbar',update_none:'Bereits aktuell',
|
update_check:'Auf Updates prüfen',update_checking:'Prüfe...',update_available:'verfügbar',update_none:'Bereits aktuell',
|
||||||
update_apply:'Jetzt installieren',update_applying:'Lade herunter...',update_restarting:'Starte neu...',update_error:'Fehler',
|
update_apply:'Jetzt installieren',update_applying:'Lade herunter...',update_restarting:'Starte neu...',update_error:'Fehler',
|
||||||
btn_connect:'⚡ Verbinden',btn_disconnect:'✕ Trennen'
|
btn_connect:'⚡ Verbinden',btn_disconnect:'✕ Trennen'
|
||||||
@@ -1188,7 +1189,7 @@ var LANG_EN={
|
|||||||
confirm_cancel:'Really cancel the print?',
|
confirm_cancel:'Really cancel the print?',
|
||||||
settings_title:'Settings',settings_connection:'Connection',settings_poll:'Poll Interval',settings_version:'Version',
|
settings_title:'Settings',settings_connection:'Connection',settings_poll:'Poll Interval',settings_version:'Version',
|
||||||
settings_save:'Save & Restart',settings_printer_ip:'Printer IP',settings_mqtt_port:'MQTT Port',
|
settings_save:'Save & Restart',settings_printer_ip:'Printer IP',settings_mqtt_port:'MQTT Port',
|
||||||
settings_username:'MQTT Username',settings_password:'MQTT Password',settings_device_id:'Device ID',settings_mode_id:'Mode ID',
|
settings_username:'MQTT Username',settings_password:'MQTT Password',settings_device_id:'Device ID',settings_mode_id:'Mode ID',hint_ip_no_port:'IP address only, no port (e.g. 192.168.1.102)',
|
||||||
update_check:'Check for Updates',update_checking:'Checking...',update_available:'available',update_none:'Already up to date',
|
update_check:'Check for Updates',update_checking:'Checking...',update_available:'available',update_none:'Already up to date',
|
||||||
update_apply:'Install Now',update_applying:'Downloading...',update_restarting:'Restarting...',update_error:'Error',
|
update_apply:'Install Now',update_applying:'Downloading...',update_restarting:'Restarting...',update_error:'Error',
|
||||||
btn_connect:'⚡ Connect',btn_disconnect:'✕ Disconnect'
|
btn_connect:'⚡ Connect',btn_disconnect:'✕ Disconnect'
|
||||||
@@ -1478,6 +1479,13 @@ function openSettings(){
|
|||||||
function closeSettings(){
|
function closeSettings(){
|
||||||
document.getElementById('settings-modal').classList.remove('open');
|
document.getElementById('settings-modal').classList.remove('open');
|
||||||
}
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded',function(){
|
||||||
|
document.getElementById('s-printer-ip').addEventListener('input',function(){
|
||||||
|
var hint=document.getElementById('lbl-ip-hint');
|
||||||
|
if(this.value.includes(':')){hint.textContent=T.hint_ip_no_port;hint.style.display='block';}
|
||||||
|
else{hint.style.display='none';}
|
||||||
|
});
|
||||||
|
});
|
||||||
function setPoll(ms){
|
function setPoll(ms){
|
||||||
document.querySelectorAll('.poll-btn').forEach(function(b){b.classList.remove('active')});
|
document.querySelectorAll('.poll-btn').forEach(function(b){b.classList.remove('active')});
|
||||||
var id='poll-'+Math.round(ms/1000);
|
var id='poll-'+Math.round(ms/1000);
|
||||||
@@ -2068,7 +2076,7 @@ function toggleCam(){if(camOn)camStop();else camStart()}
|
|||||||
lines.append(line)
|
lines.append(line)
|
||||||
# Werte aktualisieren
|
# Werte aktualisieren
|
||||||
mapping = {
|
mapping = {
|
||||||
"PRINTER_IP": str(data.get("printer_ip", existing.get("PRINTER_IP", ""))),
|
"PRINTER_IP": str(data.get("printer_ip", existing.get("PRINTER_IP", ""))).split(":")[0],
|
||||||
"MQTT_PORT": str(data.get("mqtt_port", existing.get("MQTT_PORT", "9883"))),
|
"MQTT_PORT": str(data.get("mqtt_port", existing.get("MQTT_PORT", "9883"))),
|
||||||
"MQTT_USERNAME": str(data.get("username", existing.get("MQTT_USERNAME",""))),
|
"MQTT_USERNAME": str(data.get("username", existing.get("MQTT_USERNAME",""))),
|
||||||
"MQTT_PASSWORD": str(data.get("password", existing.get("MQTT_PASSWORD",""))),
|
"MQTT_PASSWORD": str(data.get("password", existing.get("MQTT_PASSWORD",""))),
|
||||||
@@ -2357,7 +2365,7 @@ function toggleCam(){if(camOn)camStop();else camStart()}
|
|||||||
self._state["kobra_state"] = "free"
|
self._state["kobra_state"] = "free"
|
||||||
log.info("MQTT-Verbindung wiederhergestellt")
|
log.info("MQTT-Verbindung wiederhergestellt")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.warning(f"Verbindungsaufbau fehlgeschlagen: {e}")
|
log.warning(f"Verbindungsaufbau fehlgeschlagen: {_mqtt_error_msg(e)}")
|
||||||
stop_event.wait(_probe_interval)
|
stop_event.wait(_probe_interval)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -2400,6 +2408,13 @@ function toggleCam(){if(camOn)camStop();else camStart()}
|
|||||||
# App factory + main
|
# App factory + main
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def _mqtt_error_msg(exc: Exception) -> str:
|
||||||
|
msg = str(exc)
|
||||||
|
if "20020005" in msg:
|
||||||
|
return "Falsche MQTT-Zugangsdaten (falscher Benutzername, Passwort oder Device-ID)"
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
def build_app(bridge: KobraXBridge) -> web.Application:
|
def build_app(bridge: KobraXBridge) -> web.Application:
|
||||||
app = web.Application()
|
app = web.Application()
|
||||||
r = app.router
|
r = app.router
|
||||||
@@ -2480,7 +2495,7 @@ async def run_bridge(args):
|
|||||||
await loop.run_in_executor(None, client.connect)
|
await loop.run_in_executor(None, client.connect)
|
||||||
log.info("MQTT verbunden")
|
log.info("MQTT verbunden")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.warning(f"Drucker nicht erreichbar ({e}) – starte im Offline-Modus")
|
log.warning(f"Verbindung fehlgeschlagen: {_mqtt_error_msg(e)} – starte im Offline-Modus")
|
||||||
bridge._state["print_state"] = "error"
|
bridge._state["print_state"] = "error"
|
||||||
bridge._state["kobra_state"] = "offline"
|
bridge._state["kobra_state"] = "offline"
|
||||||
app = build_app(bridge)
|
app = build_app(bridge)
|
||||||
@@ -2526,6 +2541,8 @@ def main():
|
|||||||
parser.add_argument("--port", type=int, default=7125,
|
parser.add_argument("--port", type=int, default=7125,
|
||||||
help="HTTP/WS-Port (Moonraker-Standard: 7125)")
|
help="HTTP/WS-Port (Moonraker-Standard: 7125)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
if args.printer_ip and ":" in args.printer_ip:
|
||||||
|
args.printer_ip = args.printer_ip.split(":")[0]
|
||||||
|
|
||||||
asyncio.run(run_bridge(args))
|
asyncio.run(run_bridge(args))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user