Compare commits
40 Commits
master
...
nightly-0.
| Author | SHA1 | Date | |
|---|---|---|---|
| 40f85b1eb6 | |||
| 54ce101f99 | |||
| 3531cad0ef | |||
| f192a9943d | |||
| eb7fd44f68 | |||
| e5b2a19192 | |||
| 2f59a2b02b | |||
| bc9bfb58ea | |||
| ac309d5d3d | |||
| 38d98666c4 | |||
| e7c978a067 | |||
| d7c2dccef5 | |||
| e59550b5a0 | |||
| 5871e851da | |||
| be110fd766 | |||
| 77fce988d7 | |||
| fe1815c76f | |||
| 29a4262a2a | |||
| e753bcdb03 | |||
| 73ecb1e618 | |||
| 08d9a7ab0f | |||
| 93f72f0be9 | |||
| 812936d90d | |||
| 326453e2fd | |||
| ffd8ed09d5 | |||
| dc7e92688b | |||
| 3e1ba9df4b | |||
| 41f4700b24 | |||
| 216b2de2c0 | |||
| 394b0e69ab | |||
| 877cddb1ba | |||
| c9043e9630 | |||
| 6165a7f62a | |||
| fa8e0c1491 | |||
| 282c02ae0a | |||
| 72f77d92af | |||
| 3595cf839c | |||
| 2b39cc1a78 | |||
| d20308cf2c | |||
| 710c4831c2 |
31
.claude/agents/changelog.md
Normal file
31
.claude/agents/changelog.md
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: KX-Bridge Changelog
|
||||
description: Generiert einen CHANGELOG.md Eintrag aus Git-Commits seit dem letzten Tag.
|
||||
tools:
|
||||
- run_command
|
||||
- read_file
|
||||
- write_file
|
||||
---
|
||||
|
||||
Du generierst CHANGELOG.md Einträge für KX-Bridge.
|
||||
|
||||
Vorgehen:
|
||||
1. Führe aus: `git log $(git describe --tags --abbrev=0)..HEAD --oneline`
|
||||
2. Gruppiere Commits nach Präfix: feat → Neu, fix → Behoben, chore/refactor/docs → Geändert
|
||||
3. Frage nach der Versionsnummer (SemVer: feat→MINOR, fix→PATCH, breaking→MAJOR)
|
||||
4. Schreibe den Abschnitt im Format:
|
||||
|
||||
```
|
||||
## [VERSION] - DATUM
|
||||
|
||||
### Neu
|
||||
- ...
|
||||
|
||||
### Behoben
|
||||
- ...
|
||||
|
||||
### Geändert
|
||||
- ...
|
||||
```
|
||||
|
||||
5. Füge den Abschnitt am Anfang der bestehenden CHANGELOG.md ein, ohne vorhandene Einträge zu ändern.
|
||||
32
.claude/agents/docker-check.md
Normal file
32
.claude/agents/docker-check.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: KX-Bridge Docker Check
|
||||
description: Prüft Dockerfile, docker-compose und das gebaute Image auf häufige Probleme.
|
||||
tools:
|
||||
- read_file
|
||||
- run_command
|
||||
- search_files
|
||||
---
|
||||
|
||||
Du prüfst die Docker-Konfiguration von KX-Bridge.
|
||||
|
||||
**Dockerfile:**
|
||||
- Base-Image aktuell? (`python:3.11-slim` oder neuer)
|
||||
- `.dockerignore` vorhanden und vollständig?
|
||||
- Keine Secrets oder Zertifikate im Image (`anycubic_slicer.crt/.key` darf NICHT eingebettet sein)
|
||||
- Healthcheck vorhanden?
|
||||
- Kein `COPY . .` ohne `.dockerignore`
|
||||
|
||||
**docker-compose.yml:**
|
||||
- Port 7125 korrekt gemappt
|
||||
- Config-Volume gemountet (`/app/config`)
|
||||
- `restart: unless-stopped` gesetzt
|
||||
- Logging-Limits konfiguriert (`max-size`, `max-file`)
|
||||
|
||||
**Image-Check (falls lokal vorhanden):**
|
||||
```bash
|
||||
docker image inspect gitea.it-drui.de/viewit/kx-bridge:nightly
|
||||
```
|
||||
- Image-Größe sinnvoll (< 500MB)?
|
||||
- Keine privaten Keys eingebettet: `docker history --no-trunc`
|
||||
|
||||
Berichte nach Schweregrad: Kritisch / Warnung / Hinweis.
|
||||
23
.claude/agents/moonraker-debug.md
Normal file
23
.claude/agents/moonraker-debug.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
name: KX-Bridge Moonraker Debug
|
||||
description: Analysiert Moonraker/Klipper Logs und KX-Bridge Ausgaben auf Fehlerursachen.
|
||||
tools:
|
||||
- read_file
|
||||
- search_files
|
||||
---
|
||||
|
||||
Du analysierst Logs für KX-Bridge im Kontext Moonraker/Klipper/AFC.
|
||||
|
||||
**Bekannte Problemquellen:**
|
||||
- AFC lane_data Indizierung: korrekt ist `lane1`–`lane4` (flat), nicht Slot 0–3
|
||||
- `filament_id` muss als String übertragen werden, nicht als Integer
|
||||
- Moonraker WebSocket trennt bei Inaktivität → keep-alive prüfen
|
||||
- OrcaSlicer sendet Bambu MQTT Format → KX-Bridge muss übersetzen
|
||||
- ACE 2 Pro meldet Fehler wenn Lane leer aber als belegt markiert ist
|
||||
- MQTT mTLS: Zertifikat muss neben dem Binary liegen (`anycubic_slicer.crt/.key`)
|
||||
|
||||
**Bei einem Log:**
|
||||
1. Identifiziere den **ersten** Fehler (nicht den letzten Symptom)
|
||||
2. Zeige den relevanten Log-Kontext (±10 Zeilen um den Fehler)
|
||||
3. Nenne die wahrscheinliche Ursache
|
||||
4. Schlage einen konkreten Fix vor (Datei + Funktion wenn möglich)
|
||||
25
.claude/agents/nightly-prep.md
Normal file
25
.claude/agents/nightly-prep.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: KX-Bridge Nightly Prep
|
||||
description: Bereitet den PR von nightly nach main vor. Prüft ob alle Voraussetzungen für ein Stable Release erfüllt sind.
|
||||
tools:
|
||||
- run_command
|
||||
- read_file
|
||||
---
|
||||
|
||||
Du bereitest einen nightly → main Merge für KX-Bridge vor.
|
||||
|
||||
Führe folgende Checks aus und berichte:
|
||||
|
||||
1. `git log main..nightly --oneline` → alle Commits die noch nicht in main sind
|
||||
2. `git diff main..nightly -- CHANGELOG.md` → ist CHANGELOG.md für alle Änderungen aktualisiert?
|
||||
3. Prüfe ob `tests/` alle geänderten Module abdeckt
|
||||
4. Prüfe ob Dockerfile ein aktuelles Base-Image verwendet
|
||||
5. Schlage eine SemVer-Versionsnummer vor:
|
||||
- `feat:` Commits → MINOR erhöhen
|
||||
- `fix:` Commits → PATCH erhöhen
|
||||
- Breaking Change im Commit-Body → MAJOR erhöhen
|
||||
|
||||
Abschlussbericht:
|
||||
- ✅ Bereit für Release
|
||||
- ⚠️ Offen: [Liste]
|
||||
- ❌ Blockiert durch: [Grund]
|
||||
24
.claude/agents/reviewer.md
Normal file
24
.claude/agents/reviewer.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: KX-Bridge Reviewer
|
||||
description: Reviewt geänderte Dateien vor einem PR auf nightly. Prüft Logik, Fehlerbehandlung, Moonraker-Kompatibilität und Stil.
|
||||
tools:
|
||||
- read_file
|
||||
- list_directory
|
||||
- search_files
|
||||
---
|
||||
|
||||
Du bist Code-Reviewer für KX-Bridge — eine Python-Bridge zwischen OrcaSlicer und Moonraker/Klipper für den Anycubic Kobra X.
|
||||
|
||||
Beim Review prüfst du:
|
||||
- Korrekte Fehlerbehandlung bei Moonraker HTTP/MQTT Calls (keine unbehandelten Exceptions)
|
||||
- Keine hardcodierten IPs oder Ports (müssen aus config.ini kommen)
|
||||
- Thread-Sicherheit bei parallelen Moonraker-Abfragen (asyncio korrekt verwendet)
|
||||
- AFC lane_data Struktur: flache Indizierung lane1–lane4, kein Slot-Mapping 0–3
|
||||
- Kein `print()` statt `logging` (außer in CLI-Hilfsfunktionen)
|
||||
- Typ-Annotationen vorhanden, Python 3.8+ kompatibel (kein `X | Y` Syntax)
|
||||
- Tests für neue öffentliche Funktionen vorhanden
|
||||
|
||||
Ausgabeformat:
|
||||
1. **Kritische Fehler** — blockieren den Merge
|
||||
2. **Warnungen** — sollten vor Merge behoben werden
|
||||
3. **Hinweise** — optional, für zukünftige Verbesserungen
|
||||
26
.claude/agents/test-writer.md
Normal file
26
.claude/agents/test-writer.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: KX-Bridge Test Writer
|
||||
description: Leitet pytest-Tests aus geänderten oder neuen Python-Dateien ab.
|
||||
tools:
|
||||
- read_file
|
||||
- write_file
|
||||
- list_directory
|
||||
- search_files
|
||||
---
|
||||
|
||||
Du schreibst pytest-Tests für KX-Bridge.
|
||||
|
||||
Kontext:
|
||||
- Moonraker API läuft auf Port 7125 (HTTP + WebSocket)
|
||||
- AFC lane_data: flache Indizierung lane1–lane4
|
||||
- Externe HTTP-Calls zu Moonraker werden mit `unittest.mock` gemockt
|
||||
- Python 3.8+ Kompatibilität (kein `X | Y` Union-Syntax)
|
||||
|
||||
Für jede zu testende Funktion schreibst du:
|
||||
1. Happy Path (Normalfall mit validen Eingaben)
|
||||
2. Fehlerfall (Moonraker nicht erreichbar, Timeout, falsche Antwort)
|
||||
3. Grenzwerte (leere lane_data, ungültige filament_id, None-Werte)
|
||||
|
||||
Dateiname: `tests/test_<modulname>.py`
|
||||
Verwende pytest-Fixtures für Moonraker-Mock-Responses.
|
||||
Keine echten Netzwerkaufrufe in Tests.
|
||||
12
.claude/settings.json
Normal file
12
.claude/settings.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"project": "KX-Bridge",
|
||||
"language": "de",
|
||||
"defaultAgent": "reviewer",
|
||||
"context": {
|
||||
"repoBase": "gitea.it-drui.de/viewit/KX-Bridge-Release",
|
||||
"defaultBranch": "nightly",
|
||||
"stableBranch": "main",
|
||||
"registry": "gitea.it-drui.de/viewit/kx-bridge",
|
||||
"moonrakerPort": 7125
|
||||
}
|
||||
}
|
||||
29
.gitea/ISSUE_TEMPLATE/bug_report.md
Normal file
29
.gitea/ISSUE_TEMPLATE/bug_report.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug in KX-Bridge
|
||||
labels: bug
|
||||
---
|
||||
|
||||
## Description
|
||||
<!-- What is happening? -->
|
||||
|
||||
## Steps to Reproduce
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
## Environment
|
||||
- KX-Bridge Version:
|
||||
- OrcaSlicer Version:
|
||||
- Moonraker/Klipper Version:
|
||||
- Operating System:
|
||||
- Installation: Docker / Binary
|
||||
|
||||
## Logs
|
||||
```
|
||||
<!-- docker logs kx-bridge --tail 50 -->
|
||||
```
|
||||
14
.gitea/ISSUE_TEMPLATE/feature_request.md
Normal file
14
.gitea/ISSUE_TEMPLATE/feature_request.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest a new feature or improvement
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
## Description
|
||||
<!-- What should be added or improved? -->
|
||||
|
||||
## Motivation
|
||||
<!-- Why is this useful? What problem does it solve? -->
|
||||
|
||||
## Proposed Implementation
|
||||
<!-- Optional: How could this be implemented technically? -->
|
||||
21
.gitea/pull_request_template.md
Normal file
21
.gitea/pull_request_template.md
Normal file
@@ -0,0 +1,21 @@
|
||||
## Description
|
||||
<!-- What does this PR change? -->
|
||||
|
||||
## Related Issue
|
||||
Closes #
|
||||
|
||||
## Type
|
||||
- [ ] Bug fix
|
||||
- [ ] Feature
|
||||
- [ ] Documentation
|
||||
- [ ] Refactoring
|
||||
|
||||
## Tested with
|
||||
- OrcaSlicer Version:
|
||||
- Printer:
|
||||
- Moonraker/Klipper Version:
|
||||
|
||||
## Checklist
|
||||
- [ ] Tests added/updated
|
||||
- [ ] CHANGELOG.md updated
|
||||
- [ ] No debug code included
|
||||
132
.gitea/workflows/nightly.yml
Normal file
132
.gitea/workflows/nightly.yml
Normal file
@@ -0,0 +1,132 @@
|
||||
name: Nightly Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- nightly
|
||||
paths:
|
||||
- '**.py'
|
||||
- 'Dockerfile'
|
||||
- 'requirements.txt'
|
||||
- 'web/**'
|
||||
- 'data/**'
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: server-runner
|
||||
steps:
|
||||
- name: Checkout
|
||||
run: |
|
||||
if [ -d .git ]; then
|
||||
git fetch origin nightly
|
||||
git reset --hard origin/nightly
|
||||
git clean -fd
|
||||
else
|
||||
git clone --depth=1 --branch nightly https://gitea.it-drui.de/viewit/KX-Bridge-Release.git .
|
||||
fi
|
||||
|
||||
- name: Install Docker CLI
|
||||
run: |
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
DARCH="x86_64"
|
||||
BARCH="amd64"
|
||||
else
|
||||
DARCH="aarch64"
|
||||
BARCH="arm64"
|
||||
fi
|
||||
wget -qO- "https://download.docker.com/linux/static/stable/${DARCH}/docker-27.5.1.tgz" \
|
||||
| tar xz --strip-components=1 -C /usr/local/bin docker/docker
|
||||
chmod +x /usr/local/bin/docker
|
||||
mkdir -p /usr/local/lib/docker/cli-plugins
|
||||
wget -qO /usr/local/lib/docker/cli-plugins/docker-buildx \
|
||||
"https://github.com/docker/buildx/releases/download/v0.23.0/buildx-v0.23.0.linux-${BARCH}"
|
||||
chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx
|
||||
fi
|
||||
docker version --format '{{.Client.Version}}'
|
||||
|
||||
- name: Set up QEMU
|
||||
run: |
|
||||
docker run --rm --privileged tonistiigi/binfmt:latest --install all
|
||||
|
||||
- name: Set up buildx
|
||||
run: |
|
||||
docker buildx inspect kxbuilder 2>/dev/null || \
|
||||
docker buildx create --name kxbuilder --use
|
||||
docker buildx use kxbuilder
|
||||
|
||||
- name: Login to Gitea registry
|
||||
run: |
|
||||
echo "${{ secrets.REGISTRY_TOKEN }}" | \
|
||||
docker login gitea.it-drui.de -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||
|
||||
- name: Build & push (amd64 + arm64)
|
||||
run: |
|
||||
VERSION=$(cat VERSION)
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--provenance=false \
|
||||
--no-cache \
|
||||
-t "gitea.it-drui.de/viewit/kx-bridge:nightly" \
|
||||
-t "gitea.it-drui.de/viewit/kx-bridge:nightly-${VERSION}" \
|
||||
.
|
||||
|
||||
- name: Create Gitea Nightly Release
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
VERSION=$(cat VERSION)
|
||||
TAG="nightly-${VERSION}"
|
||||
git config user.name "gitea-actions"
|
||||
git config user.email "actions@it-drui.de"
|
||||
|
||||
# Changelog aus CHANGES.md lesen (wird von release.sh aus dem Dev-Repo generiert)
|
||||
BODY_FILE=$(mktemp)
|
||||
if [ -f CHANGES.md ]; then
|
||||
cat CHANGES.md > "$BODY_FILE"
|
||||
else
|
||||
# Fallback falls CHANGES.md fehlt
|
||||
printf '## KX-Bridge %s -- Nightly Build\n\n' "$VERSION" > "$BODY_FILE"
|
||||
printf '[experimentell] Ungetestete Features, nur fuer Tester geeignet.\n\n' >> "$BODY_FILE"
|
||||
printf '- Automatischer Nightly-Build\n\n---\n\n' >> "$BODY_FILE"
|
||||
printf '### Docker-Image aktualisieren\n\n```bash\ndocker compose pull && docker compose up -d\n```\n\n' >> "$BODY_FILE"
|
||||
printf 'Image-Tag: `gitea.it-drui.de/viewit/kx-bridge:nightly`\n' >> "$BODY_FILE"
|
||||
fi
|
||||
|
||||
# Tag setzen
|
||||
git tag -f "$TAG"
|
||||
git push https://gitea-actions:${GITEA_TOKEN}@gitea.it-drui.de/viewit/KX-Bridge-Release.git "$TAG" --force
|
||||
|
||||
# curl installieren (BusyBox wget kann kein DELETE/POST mit Headers)
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
if ! apk add --no-cache curl 2>/dev/null; then
|
||||
wget -qO /usr/local/bin/curl \
|
||||
"https://github.com/moparisthebest/static-curl/releases/download/v8.6.0/curl-amd64"
|
||||
chmod +x /usr/local/bin/curl
|
||||
fi
|
||||
fi
|
||||
|
||||
# Altes Release loeschen falls vorhanden
|
||||
curl -s -X DELETE \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"https://gitea.it-drui.de/api/v1/repos/viewit/KX-Bridge-Release/releases/tags/${TAG}" \
|
||||
2>/dev/null || true
|
||||
|
||||
# Release erstellen (JSON-Body via awk escapen)
|
||||
BODY_JSON=$(awk '{
|
||||
gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); gsub(/\t/, "\\t");
|
||||
printf "%s\\n", $0
|
||||
}' "$BODY_FILE" | awk 'BEGIN{printf "\""} {printf "%s", $0} END{printf "\""}')
|
||||
JSON_PAYLOAD="{\"tag_name\":\"${TAG}\",\"name\":\"KX-Bridge ${VERSION} Nightly\",\"body\":${BODY_JSON},\"draft\":false,\"prerelease\":true}"
|
||||
printf '%s' "$JSON_PAYLOAD" > /tmp/release_body.json
|
||||
curl -s -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @/tmp/release_body.json \
|
||||
"https://gitea.it-drui.de/api/v1/repos/viewit/KX-Bridge-Release/releases"
|
||||
rm -f "$BODY_FILE" /tmp/release_body.json
|
||||
34
.gitea/workflows/pr-check.yml
Normal file
34
.gitea/workflows/pr-check.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
name: PR Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- nightly
|
||||
|
||||
jobs:
|
||||
lint-and-test:
|
||||
runs-on: server-runner
|
||||
steps:
|
||||
- name: Checkout
|
||||
run: |
|
||||
if [ -d .git ]; then
|
||||
git fetch origin
|
||||
git reset --hard origin/nightly
|
||||
git clean -fd
|
||||
else
|
||||
git clone --depth=1 --branch nightly https://gitea.it-drui.de/viewit/KX-Bridge-Release.git .
|
||||
fi
|
||||
|
||||
- name: Dependencies installieren
|
||||
run: pip3 install -r requirements.txt
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
pip3 install flake8
|
||||
flake8 *.py --max-line-length=120 --extend-ignore=E501
|
||||
|
||||
- name: Tests
|
||||
run: |
|
||||
pip3 install pytest
|
||||
pytest tests/ -v
|
||||
if: ${{ hashFiles('tests/') != '' }}
|
||||
87
.gitea/workflows/release.yml
Normal file
87
.gitea/workflows/release.yml
Normal file
@@ -0,0 +1,87 @@
|
||||
name: Stable Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: server-runner
|
||||
steps:
|
||||
- name: Checkout
|
||||
run: |
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
if [ -d .git ]; then
|
||||
git fetch --tags origin
|
||||
git checkout "$TAG"
|
||||
git clean -fd
|
||||
else
|
||||
git clone --depth=1 --branch "$TAG" https://gitea.it-drui.de/viewit/KX-Bridge-Release.git .
|
||||
fi
|
||||
|
||||
- name: Install Docker CLI
|
||||
run: |
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
DARCH="x86_64"
|
||||
BARCH="amd64"
|
||||
else
|
||||
DARCH="aarch64"
|
||||
BARCH="arm64"
|
||||
fi
|
||||
wget -qO- "https://download.docker.com/linux/static/stable/${DARCH}/docker-27.5.1.tgz" \
|
||||
| tar xz --strip-components=1 -C /usr/local/bin docker/docker
|
||||
chmod +x /usr/local/bin/docker
|
||||
mkdir -p /usr/local/lib/docker/cli-plugins
|
||||
wget -qO /usr/local/lib/docker/cli-plugins/docker-buildx \
|
||||
"https://github.com/docker/buildx/releases/download/v0.23.0/buildx-v0.23.0.linux-${BARCH}"
|
||||
chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx
|
||||
fi
|
||||
docker version --format '{{.Client.Version}}'
|
||||
|
||||
- name: Set up QEMU
|
||||
run: |
|
||||
docker run --rm --privileged tonistiigi/binfmt:latest --install all
|
||||
|
||||
- name: Set up buildx
|
||||
run: |
|
||||
docker buildx inspect kxbuilder 2>/dev/null || \
|
||||
docker buildx create --name kxbuilder --use
|
||||
docker buildx use kxbuilder
|
||||
|
||||
- name: Login to Gitea registry
|
||||
run: |
|
||||
echo "${{ secrets.REGISTRY_TOKEN }}" | \
|
||||
docker login gitea.it-drui.de -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||
|
||||
- name: Build & push (amd64 + arm64)
|
||||
run: |
|
||||
VERSION="${GITHUB_REF#refs/tags/}"
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--provenance=false \
|
||||
--no-cache \
|
||||
-t "gitea.it-drui.de/viewit/kx-bridge:latest" \
|
||||
-t "gitea.it-drui.de/viewit/kx-bridge:${VERSION}" \
|
||||
.
|
||||
|
||||
- name: Create Gitea Release
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
VERSION="${GITHUB_REF#refs/tags/}"
|
||||
CHANGELOG=$(awk "/^## \[${VERSION}\]/{found=1; next} found && /^## \[/{exit} found{print}" CHANGELOG.md || echo "")
|
||||
curl -s -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://gitea.it-drui.de/api/v1/repos/viewit/KX-Bridge-Release/releases" \
|
||||
-d "{
|
||||
\"tag_name\": \"${VERSION}\",
|
||||
\"name\": \"KX-Bridge ${VERSION}\",
|
||||
\"body\": $(echo "$CHANGELOG" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))'),
|
||||
\"draft\": false,
|
||||
\"prerelease\": false
|
||||
}"
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,3 +17,4 @@ config/*.ini
|
||||
data/
|
||||
|
||||
!data/orca_filaments.json
|
||||
.runner-token
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
GITEA_RUNNER_TOKEN=YF9I7H3BI5ovPnMC7iU2I86Hga8dcWUakqH9qT85
|
||||
271
CHANGES.md
Normal file
271
CHANGES.md
Normal file
@@ -0,0 +1,271 @@
|
||||
## KX-Bridge 0.9.27-nightly8 — Nightly Build
|
||||
|
||||
[experimentell] Ungetestete Features, nur für Tester geeignet.
|
||||
|
||||
### Änderungen seit `v0.9.13`
|
||||
|
||||
- chore: CHANGES.md mit echtem Changelog aus Dev-Repo ins Release-Repo schreiben
|
||||
- fix(spoolman): SPOOLMAN_* env-Cache bei Restart leeren, Status-Dot nach Save aktualisieren
|
||||
- chore: README.es.md + CONTRIBUTING.md in release.sh-Sync aufnehmen
|
||||
- docs: Nightly-Sektion, Wartungshinweis + CONTRIBUTING.md, FR/IT-Sprachen, Downloads-Badge
|
||||
- fix(update): Nightly-Vergleich auf Versions-String umstellen (statt Datum)
|
||||
- feat(update): Nightly-Track vom Stable-Track trennen
|
||||
- fix(release): nightly immer auf nightly-Branch pushen, kein master-Push
|
||||
- fix(camera): exponentielles Backoff bei ffmpeg-Fehler + /api/camera/reset + ↺-Button
|
||||
- fix(release): Nightly-Release vom nightly-Branch erlauben
|
||||
- feat(i18n): fehlende UI-Übersetzungen ergänzt + Keys alphabetisch sortiert (PR #70 @fenopy)
|
||||
- fix: config/config.ini.example beim Release-Sync mitübertragen (Issue #72)
|
||||
- feat(ui): Integrationen-Tab in Settings (Spoolman + Obico-Hinweis)
|
||||
- feat(stack): KobraX Full Stack Compose für Portainer (KX-Bridge + Obico + Spoolman)
|
||||
- feat(release): Nightly/Stable Release-Workflow mit eigenem Docker-Tag
|
||||
- feat(spoolman): optionale Spoolman-Filamentverbrauch-Integration (PR #65, @p2l)
|
||||
- fix(release): Artifact-Download per HTTP statt lokalem Dateipfad
|
||||
- feat(ui): PR #60 — Print-Workflow + Skip-Dialog Fixes (@gangoke)
|
||||
- Revert "feat(ui): PR #60 — Print-Workflow + Skip-Dialog Fixes (@gangoke)"
|
||||
- feat(ui): PR #60 — Print-Workflow + Skip-Dialog Fixes (@gangoke)
|
||||
- fix(release): PyInstaller-Cache zwischen Builds via extra_git_cmds leeren
|
||||
- fix(upload): File-Browser nur GCode zulassen (Issue #59)
|
||||
- fix(mqtt): TLS-Socket Read/Write-Race — Segfault in libcrypto (Issue #53)
|
||||
- feat(ui): Slot-Mapper Skip-Parität + konkrete Profilnamen (Issue #57)
|
||||
- feat(print): Auto-Open-Druckdialog + Per-Print-Auto-Leveling + Skip-Fix (PR #56)
|
||||
- feat(ui): Idle-Buttons im Progress-Card + fix(moonraker): Mobileraker-Kompatibilität (Issue #48, #55)
|
||||
- feat(filament): Vendor-Visibility-Filter für Profil-Dropdown (Issue #41)
|
||||
- feat(ui): Settings als Master-Detail-Panel mit Kategorie-Sidebar
|
||||
- chore: CodeBuilder-URL auf 192.168.178.204 gesetzt
|
||||
- docs(changelog): 0.9.21 — Android-Kamera, IPv4, Debian-Bookworm, Mobileraker-Fix
|
||||
- fix(ui): Kamera-Stream auf Android via Snapshot-Polling
|
||||
- fix(docker): python:3.11-slim-bookworm pinnen (glibc 2.41 GPF auf älteren Kerneln, Issue #53)
|
||||
- fix(moonraker): configfile extruder-Stub um sensor_type + filament_diameter erweitert (Mobileraker #48)
|
||||
- fix(release): Artifact-Pfad /app/ → Host-Pfad umschreiben
|
||||
- docs(changelog): 0.9.20 — French, Z-height, camera fixes, light bug
|
||||
- fix(docker): ffmpeg ins Image aufnehmen
|
||||
- chore(i18n): Log-Meldungen auf Englisch umgestellt
|
||||
- chore(security): 04_configs/decrypted/ zu .gitignore hinzugefügt
|
||||
- fix(camera): Kamera-Autostart ignoriert Setting nach Bridge-Restart (#50)
|
||||
- feat(i18n): Französisch hinzugefügt (PR #45, @Nathacks)
|
||||
- merge: PR #49 — Z-Höhe in der Print-UI anzeigen (@Nathacks)
|
||||
- Revert "fix(ace): ACE-Slot-Offset um 1 korrigiert (Issue #47)"
|
||||
- fix(ace): ACE-Slot-Offset um 1 korrigiert (Issue #47)
|
||||
- fix(compat): configfile-Stub + absolute Webcam-URLs für Mobileraker/Obico
|
||||
- docs(claude): CLAUDE.md auf aktuellen Stand 0.9.19.1
|
||||
- docs(changelog): translate 0.9.19.1 entry to English (CHANGELOG.md was German by mistake)
|
||||
- fix(spec): VERSION-Datei ins Onefile einbetten — beseitigt vunknown in standalone Binaries
|
||||
- chore: CHANGELOG 0.9.19.1 + VERSION zurueck fuer release.sh-Bump
|
||||
- feat(filaments): nur Kobra-X-sichtbare Profile (209 statt 399)
|
||||
- fix(mqtt): klare Meldung wenn anycubic_slicer.crt/.key fehlen (statt Errno 2)
|
||||
- chore(gitignore): ignore lokale Build-/Test-/TODO-Pfade
|
||||
- fix(spec): VERSION-Datei ins Onefile einbetten — beseitigt vunknown in standalone Binaries
|
||||
- docs(changelog): 0.9.19.1 hotfix entry
|
||||
- docs(changelog): remove internal test-profile name 'Bert - PLA'
|
||||
- docs: README — Features für 0.9.17/18/19 + OrcaSlicer-KX-PR-Liste + Kobra S1/S1Max-Hinweis
|
||||
- chore: 0.9.19 — filament sync matches real presets, custom profile import
|
||||
- fix(profile-import): User-Profile mit Inherits-Kette parsen
|
||||
- fix(ui): Slot-Card direkt nach Speichern neu rendern
|
||||
- fix(filament-sync): Default ist Generic <Typ> statt Anycubic <Typ>
|
||||
- fix(filament-sync): Phantom-Profile raus, Default-Lookup aus JSON
|
||||
- feat(filament-sync): gate_filament_name im HH-MMU-Objekt befüllen
|
||||
- feat(filament-sync): sende name + vendor_name pro Lane (PR #13719-kompatibel)
|
||||
- fix(ace-dryer): setDry fire-and-forget (PR #42 von @gangoke)
|
||||
- feat(filament): Custom-Profile-Import via Bridge-UI Upload (Issue #41)
|
||||
- fix(filament): Kobra-X-kompatible IDs in orca_filaments.json + Defaults
|
||||
- chore: 0.9.18 — Filament set from bridge works, Obico Z-height, slot profile picker fixes
|
||||
- feat(ui): Slot-Profil-Dropdown auf (vendor,name) + Pause/Resume-Toggle + Vendor-Badge auf Slot-Karte
|
||||
- feat(bridge): Slot-Profil-Roundtrip + Z-Höhe für Obico + multiColorBox/setInfo via web/printer (Issue #39)
|
||||
- feat(filament): (vendor,name)-Selector statt filament_id im config-Schema
|
||||
- feat(i18n): sync Spanish translation refactor from KX-Bridge-Release PR #40
|
||||
- fix(mqtt): persistenter Reconnect — Bridge erkennt Drucker-Reboot (Issue #33)
|
||||
- chore: 0.9.17 — Obico (experimental), multi-language UI, filament-profile sync, H.264 stream
|
||||
- fix(i18n): GCode-Browser nach Sprachwechsel neu rendern
|
||||
- fix(upload): trennt Connect-/Send-/Read-Timeout für große GCode-Uploads
|
||||
- feat(bridge): CameraCache + Translations-Route + h264-Endpoint
|
||||
- feat(i18n): sync translation refactor from KX-Bridge-Release PR #37
|
||||
- fix(temp): tempature/set über web/printer-Topic mit type-Feld
|
||||
- fix(obico): Klipper-SET_HEATER_TEMPERATURE + korrekter MQTT-Pfad für Temp-Set
|
||||
- fix(filament-list): erweiterte Vendor-Profile + Dropdown-Refresh bei Material-Wechsel
|
||||
- feat(ams-sync): User-Override pro Slot für konkrete OrcaSlicer-Filament-Marke
|
||||
- refactor(release): alle 3 kx-bridge-Targets via CodeBuilder-API
|
||||
- feat(obico): Layer-aligned Time-Lapse + First-Layer-Scan Pseudo-Macros
|
||||
- fix(obico): start_time/end_time als Unix-Timestamp (float) statt ISO-String
|
||||
- feat(obico): Moonraker-Kompatibilität für moonraker-obico-Plugin
|
||||
- feat: GCode Web-Upload + Download + Verify-Dialog (PR #32 von @gangoke)
|
||||
- docs: OrcaSlicer-KX (gepatchter Slicer) im README verlinken
|
||||
- docs: CHANGELOG 0.9.16 — Filament-Sync-Fix ergänzt
|
||||
- fix: Filament-Sync positionstreu + Happy-Hare-Farbformat (OrcaSlicer)
|
||||
- docs: CHANGELOG 0.9.16
|
||||
- fix: i18n-Lücken im ACE-Dry-Dialog (DE-Übersetzungen + fehlender Key)
|
||||
- fix: Slicer-Zeit + Thumbnail nach Reload / bei OrcaSlicer-Druck anzeigen
|
||||
- feat: Settings-Option "Kamera bei Druckstart einschalten"
|
||||
- feat: Log-Verbesserungen (Dedup-Zähler, Level-Filter, Fehler-Toast, mehr Infos)
|
||||
- fix: einfarbiger Druck blockiert durch leeren AMS-Slot (OrcaSlicer)
|
||||
- fix: release.sh resynct Windows-Agent hart vor dem Build
|
||||
- docs: CHANGELOG 0.9.15 (Issue #29 OrcaSlicer-Webview-Fixes)
|
||||
- fix: Print-Banner + UI im OrcaSlicer-Webview (Issue #29)
|
||||
- fix: Upload-Banner nach Druckende ausblenden (Issue #29)
|
||||
- docs: CHANGELOG 0.9.14 (Theme-System #27, API-Restart #28)
|
||||
- feat: POST /api/restart Endpoint (PR #28 von @gangoke)
|
||||
- fix: release.sh stellt kx-bridge.spec im Release-Repo sicher (Windows-Theme-Build)
|
||||
- chore: kx-bridge.spec von *.spec-ignore ausnehmen
|
||||
- build: kx-bridge.spec ins Repo aufnehmen (war durch *.spec geignored)
|
||||
- build: einheitlicher PyInstaller-Spec für Linux + Windows (Theme-Einbettung)
|
||||
- feat: Theme-System (PR #27 von hirnwunde/Olli)
|
||||
- docs: klare Update-Warnung (EXE/Docker) im 0.9.13-CHANGELOG
|
||||
- docs: CHANGELOG 0.9.13 (Self-Update-Fix)
|
||||
- fix: Self-Update lädt alle Bridge-Module (nicht nur Hauptdatei)
|
||||
- docs: CHANGELOG 0.9.12
|
||||
- docs: Downloads-Badge in READMEs (800+ App-Downloads)
|
||||
- docs: Home-Assistant-Integration (Community) verlinken (Issue #24)
|
||||
- revert: Moonraker-UI-Integration entfernen (Mainsail/Fluidd/Mobileraker)
|
||||
- fix: Mainsail Live-Werte + Pause-State (Issue #25)
|
||||
- feat: Moonraker-Kompatibilität für Mainsail/Fluidd/Mobileraker (Issue #25)
|
||||
- refactor: Frontend aus kobrax_moonraker_bridge.py auslagern
|
||||
- docs: CHANGELOG 0.9.11 (ACE Pro 2 experimentell) + Version-Bump
|
||||
- feat: ACE Pro 2 Support (PR #26 von gangoke)
|
||||
- release: LICENSE + NOTICE.md ins Release-Repo syncen
|
||||
- docs: GPLv3-Lizenz + NOTICE für Anycubic-Drittmaterial
|
||||
- release: PyBuilder statt GitHub Actions fuer Windows-Build
|
||||
- release: Versions-Marker-Check entfernt (Binary enthaelt VERSION nicht)
|
||||
- release: verify_binary nutzt kobrax_moonraker_bridge + VERSION als Marker
|
||||
- docs: CHANGELOG fuer 0.9.10 + Fokus-Hinweis Stabilisierung
|
||||
- release: release.sh haerten – Sanity-Checks + Build-Verifikation
|
||||
- feat: Part-Skip (Exclude Object) – pre-print + mid-print
|
||||
- release: rohe kx-bridge + kx-bridge.exe Binaries als Release-Assets hochladen
|
||||
- docs: CHANGELOG für 0.9.9 (bridge_url + Windows config_loader)
|
||||
- fix: bridge_url leer im Single-Printer-Modus → relative Pfade (Issue #21)
|
||||
- fix: release.sh kopiert config_loader.py ins Windows-Build-Repo
|
||||
- docs: README EN/DE getrennt — README.md englisch, README.de.md deutsch (neues Design); release.sh kopiert beide ins Release-Repo
|
||||
- docs: CHANGELOG für 0.9.8
|
||||
- feat: Standalone-Tauglichkeit + Drucker add/remove + leerer Zustand
|
||||
- feat: Multi-Printer in einer Bridge-Instanz
|
||||
- feat: T14 Suche/Filter/Sortierung im Browser-Tab + T17 GCode-Filamente
|
||||
- feat: Drucker-Name editierbar in Settings
|
||||
- fix: Settings und Update-Check zeigen aktiven Drucker (via _apiUrl)
|
||||
- fix: i18n für Drucker-Tab (DE/EN)
|
||||
- feat: Drucker-Tab mit Live-Status aller Instanzen
|
||||
- feat: Print-History im Browser-Tab (T10)
|
||||
- fix: CORS-Middleware für alle Endpunkte + bridge_url via request.host
|
||||
- feat: Slot-Auswahl auch im Upload-Banner (3. Button)
|
||||
- feat: Filament-Slot-Dialog + POST /kx/print (T06+T08)
|
||||
- feat: Multi-Printer WebUI + Routing (T05)
|
||||
- feat: Multi-Printer Config-Format (T04)
|
||||
- feat: i18n für Browser-Tab (DE/EN)
|
||||
- chore: Browser-Tab umbenennen (Store → Browser)
|
||||
- feat: GCode Store Tab in WebUI (T03)
|
||||
- feat: GCode Store — SQLite-Persistenz, /kx/ API, Thumbnail-Extraktion (T01+T02)
|
||||
- feat: Happy Hare MMU-Emulation für OrcaSlicer Filament-Sync
|
||||
- chore: Changelog für 0.9.7 ergänzt
|
||||
- fix: Upload großer GCode-Dateien (client_max_size 256MB, Socket-Timeout 120s)
|
||||
- docs: CHANGELOG 0.9.6 nachgetragen (Licht-Sync, Zeit-Cards, Status-Strings, Fixes)
|
||||
- build: fetch_credentials in release.sh ergänzt, build.sh auf Linux-only bereinigt
|
||||
- build: sudo durch rm+cp ersetzt für Windows EXE-Copy (Docker root-owned)
|
||||
- build: fetch_credentials Linux + Windows Binary in build.sh ergänzt
|
||||
- docs: fetch_credentials als primärer Setup-Weg, Ko-fi Button ergänzt
|
||||
- feat: fetch_credentials --write-config ersetzt extract_credentials Workflow
|
||||
- feat: fetch_credentials.py aus PR #19 übernommen
|
||||
- fix: YouTube Thumbnail auf hqdefault (maxresdefault nicht verfügbar)
|
||||
- feat: Licht-Status live vom Drucker synchronisieren, Video Tutorial in README
|
||||
- fix: Zeiten (verstrichen/rest/slicer) werden bei Stopp/Abbruch zurückgesetzt
|
||||
- fix: file_ready-Banner nach Stopp/Abbruch wird nicht mehr angezeigt
|
||||
- feat: Progress-Card mit Zeit-Minicards und Layer-Badge, Slicer-Zeit aus GCode-Ende (OrcaSlicer)
|
||||
- fix: start.sh erstellt config/ und kopiert config.ini.example automatisch (Issue #15)
|
||||
- feat: Upload-Banner mit Start/Abbrechen, Thumbnail bei Nur-hochladen, Auto-Print-Fix, Log-Scroll-Fix
|
||||
- fix: auto_print-Reset nach Multipart-Loop entfernt, Log-Scroll-Position bei deaktiviertem Auto-Scroll erhalten
|
||||
- feat: file_ready Banner – nach Upload-only Druck-Start-Button anzeigen
|
||||
- fix: Upload-only vs. Upload+Print korrekt unterscheiden
|
||||
- fix: release.sh – Release-Name einheitlich als 'v0.9.x' (wie bisherige Releases)
|
||||
- fix: release.sh – CHANGELOG-Body automatisch in Gitea-Release schreiben
|
||||
- fix: release.sh – stabile Releases nicht als Pre-Release markieren
|
||||
- fix: i18n – Kamera-Placeholder und Log-Dir-Button übersetzt
|
||||
- feat: AMS-Slot-Dialog vollständig i18n (DE/EN)
|
||||
- fix: AMS-Slot onclick – JSON.stringify im HTML-Attribut vermeiden
|
||||
- feat: AMS-Slot-Editor – Farbe und Material per Klick ändern
|
||||
- feat: Log-Tab erweitert – volle Payload + TX/RX/Topic-Filter
|
||||
- docs: CHANGELOG und README auf v0.9.3 aktualisiert
|
||||
- fix: Update-Check liefert stable statt Dev, VERSION im Dockerfile, Version im Header (#14)
|
||||
- docs: README.de.md hinzugefügt, README.en.md entfernt – einheitliche Benennung
|
||||
- docs: CHANGELOG.de.md – deutsche Version des Changelogs
|
||||
- chore: README und CHANGELOG auf Englisch, UI-Fehlertexte englisch, i18n für connection_error Banner
|
||||
- chore: 0.9.2 CHANGELOG, toter Code in config_loader entfernt
|
||||
- chore: Dev-Version auf 0.9.1-dev+1a8ee2a gesetzt
|
||||
- chore: Release-Binaries und Logs aus Git-Index entfernen, .gitignore erweitert
|
||||
- fix: Verbindungsfehler in Web-UI als Banner anzeigen (#11); README: OrcaSlicer-URL und extract_credentials-Link präzisiert (#12/#13)
|
||||
- feat: config.ini statt .env – persistente Settings über docker-compose restart
|
||||
- docs: CHANGELOG dev – Slicer-Schätzzeit und Update-Dialog Changelog ergänzt
|
||||
- chore: Dev-Version auf 0.9.1-dev+14cfb27 gesetzt
|
||||
- feat: Slicer-Schätzzeit im Fortschritts-Panel anzeigen
|
||||
- revert: Obico-Integration entfernt
|
||||
- feat(obico): Kamera-Snapshots aktiv zu Obico hochladen
|
||||
- fix(obico): BRIDGE_URL für Docker-Netzwerk-Kompatibilität
|
||||
- feat(obico): Layer-Fortschritt in Obico anzeigen
|
||||
- fix(obico): Snapshot-Endpoint und Layer-Anzeige
|
||||
- feat(obico): Obico Selfhosted Integration vollständig
|
||||
- chore: Dev-Version auf 0.9.1-dev+ea587fc gesetzt
|
||||
- feat: Obico Verbindungsstatus – Badge im Header, connected-Tracking in ObicoAgent
|
||||
- chore: Dev-Version auf 0.9.1-dev+aca91a5 gesetzt
|
||||
- feat: Obico Selfhosted Integration – ObicoAgent, Snapshot-Endpoint, Settings-Modal
|
||||
- chore: Dev-Version auf 0.9.1-dev+5ddfa13 gesetzt
|
||||
- feat: Changelog aus Gitea-Release im Update-Dialog anzeigen
|
||||
- chore: Dev-Version auf 0.9.1-dev+60d4287 gesetzt
|
||||
- docs: CHANGELOG für dev-Branch ergänzt
|
||||
- chore: Dev-Version auf 0.9.1-dev+374af9e gesetzt
|
||||
- chore: Log-Buffer auf 500 Einträge vereinheitlicht (Server + Browser)
|
||||
- chore: Dev-Version auf 0.9.1-dev+1aa8a75 gesetzt
|
||||
- feat: Log-Tab – Auto-Scroll toggle, Textfilter, Error-Badge im Nav-Tab
|
||||
- chore: Dev-Version auf 0.9.1-dev+da0bf51 gesetzt
|
||||
- feat: Server-Log live in Browser-Console (SSE) + Download-Button
|
||||
- chore: Dev-Version auf 0.9.1-dev+a52f76f gesetzt
|
||||
- feat: MQTT-Logging – strukturiertes TX/RX-Log mit Duplikat-Filter
|
||||
- chore: Dev-Version auf 0.9.1-dev+1828eec gesetzt
|
||||
- feat: Dev-Infrastruktur – Versionsschema 0.9.1-dev+hash, separater Update-Kanal, README.dev.md
|
||||
- feat: AMS Slot-Auswahl und Auto-Leveling-Option im Settings-Modal (Issue #6)
|
||||
- chore: _archive/releases Binaries aus Git-Tracking entfernt
|
||||
- chore: knlogo.png aus Dev-Repo entfernt (nur Release-Repo)
|
||||
- fix: Bridge zeigt beim Start lokale IP statt 0.0.0.0; README-Hinweis verbessert
|
||||
- chore: release.sh aktualisiert Version in Release-Repo-READMEs und kopiert Logo
|
||||
- feat: Logo ins englische README hinzugefügt
|
||||
- feat: Logo ins README und Projektverzeichnis hinzugefügt
|
||||
- fix: AMS leere Slots in UI grau darstellen (Issue #5)
|
||||
- fix: use_ams nur true wenn belegte Slots vorhanden
|
||||
- fix: leere AMS-Slots beim Druckstart filtern (status!=5), material_type-Feld korrigiert
|
||||
- fix: apt ffmpeg entfernt, imageio-ffmpeg übernimmt
|
||||
- fix: Home X/Y entfernt, homeAxis durch homeZ/homeXY ersetzt
|
||||
- feat: beta14 – imageio-ffmpeg, Z-Buttons fix, Home XY/All, Motors Off
|
||||
- feat: beta13 – Windows-Fixes, Projektstruktur-Reorganisation
|
||||
- refactor: Projektstruktur überarbeitet
|
||||
- feat: Changelog, Tests, start.sh und Dockerfile-Fixes hinzufügen
|
||||
- docs: Version auf 0.9.1-beta10 korrigieren
|
||||
- docs: LAN-Modus korrekt beschreiben (Drucker-Menüoption)
|
||||
- feat: Offline-Start + Verbinden/Trennen-Button im Header
|
||||
- feat: Release-ZIPs mit Zertifikaten (linux/windows/certs-only)
|
||||
- fix: PyInstaller frozen-Binary – __file__ durch sys.executable-Pfad ersetzen
|
||||
- feat: Windows kx-bridge.exe via GitHub Actions bauen
|
||||
- fix: release.sh kopiert READMEs nicht mehr (Release-Repo hat eigene)
|
||||
- docs: README.md aktualisiert, README.en.md hinzugefügt, release.sh kopiert READMEs
|
||||
- docs: Benutzerdoku aktualisiert (v0.9.1-beta4) + englische Version hinzugefügt
|
||||
- fix: progress und filename auf 0 zurücksetzen bei stoped/canceled
|
||||
- feat: neue Drucker-Zustände – pausing/paused/resuming/resumed/stopping/stoped
|
||||
- fix: release.sh – rm Fehler nach Docker-Build abfangen
|
||||
- fix: release.sh – Windows-EXE Build korrigiert (leeres Workdir, richtiger dist-Pfad)
|
||||
- feat: release.sh – Binaries bauen + als Gitea-Assets hochladen
|
||||
- feat: Print-Speed-Card, Übersetzungen vervollständigt
|
||||
- fix: Temperatursteuerung während des Drucks
|
||||
- chore: release.sh – Version-Bump und Release-Sync Skript
|
||||
- feat: UI-Komplettüberarbeitung – Settings, Self-Update, Dashboard, Responsive
|
||||
- feat: UI-Überarbeitung – KX-Bridge Titel, ViewIT Footer, Kobra-State-Anzeige, Dashboard-Erweiterung
|
||||
- feat: UI Titel KX-Bridge, Footer ViewIT 2026
|
||||
- fix: README Fehlerbehebung – Credential-Rotation entfernt, --verbose Hinweis ergänzt
|
||||
- fix: sensible Credentials aus README entfernt (Beispielausgabe anonymisiert)
|
||||
- docs: CLAUDE.md Projektstruktur + Deployment-Status aktualisiert
|
||||
- feat: Public Beta 0.9.0-beta1 – Docker, Binaries, README, Build-Prozess
|
||||
- feat: extract_credentials.py + Bridge Tip-Forming & lane_data Endpoint
|
||||
- feat: AMS Einziehen/Ausziehen UI + feedFilament-Protokoll dokumentiert
|
||||
- Initial commit: KX-Bridge + Protokoll-Dokumentation
|
||||
|
||||
---
|
||||
|
||||
### Docker-Image aktualisieren
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
Image-Tag: `gitea.it-drui.de/viewit/kx-bridge:nightly`
|
||||
102
CONTRIBUTING.md
Normal file
102
CONTRIBUTING.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Contributing to KX-Bridge
|
||||
|
||||
Thanks for taking the time to contribute! Here's everything you need to know.
|
||||
|
||||
---
|
||||
|
||||
## How to report a bug or request a feature
|
||||
|
||||
Use the issue tracker:
|
||||
|
||||
- **Bug:** [New Bug Report](https://gitea.it-drui.de/viewit/KX-Bridge-Release/issues/new?template=bug_report.md)
|
||||
- **Feature:** [New Feature Request](https://gitea.it-drui.de/viewit/KX-Bridge-Release/issues/new?template=feature_request.md)
|
||||
|
||||
Please fill in the template — especially the **KX-Bridge version** and **logs**.
|
||||
Issues without version info are hard to debug.
|
||||
|
||||
---
|
||||
|
||||
## How to submit a Pull Request
|
||||
|
||||
### 1. Fork the repository
|
||||
|
||||
Click **Fork** at the top of this page.
|
||||
You now have your own copy at `gitea.it-drui.de/your-username/KX-Bridge-Release`.
|
||||
|
||||
### 2. Clone your fork
|
||||
|
||||
```bash
|
||||
git clone https://gitea.it-drui.de/your-username/KX-Bridge-Release.git
|
||||
cd KX-Bridge-Release
|
||||
```
|
||||
|
||||
### 3. Create a branch
|
||||
|
||||
Always branch off `nightly`:
|
||||
|
||||
```bash
|
||||
git checkout nightly
|
||||
git checkout -b feature/my-feature # or fix/my-fix
|
||||
```
|
||||
|
||||
### 4. Make your changes
|
||||
|
||||
- Test your changes locally with Docker:
|
||||
```bash
|
||||
docker build -t kx-bridge:dev .
|
||||
docker run -p 7125:7125 -v ./config:/app/config kx-bridge:dev
|
||||
```
|
||||
- No debug `print()` statements — use `logging`
|
||||
- Keep commits focused; one thing per commit
|
||||
|
||||
### 5. Push and open a PR
|
||||
|
||||
```bash
|
||||
git push origin feature/my-feature
|
||||
```
|
||||
|
||||
Gitea will show a banner — click **"Create Pull Request"**.
|
||||
The PR template will be pre-filled. Set the target branch to **`nightly`**.
|
||||
|
||||
---
|
||||
|
||||
## Branch model
|
||||
|
||||
```
|
||||
master ← stable releases only (merged by maintainer)
|
||||
nightly ← integration branch — PRs go here
|
||||
feature/* ← your feature branch (in your fork)
|
||||
fix/* ← your bugfix branch (in your fork)
|
||||
```
|
||||
|
||||
Your PR always targets `nightly`. The maintainer periodically merges `nightly → master` for a new stable release.
|
||||
|
||||
---
|
||||
|
||||
## Commit style
|
||||
|
||||
Use conventional commit prefixes:
|
||||
|
||||
| Prefix | When |
|
||||
|---|---|
|
||||
| `feat:` | new feature |
|
||||
| `fix:` | bug fix |
|
||||
| `docs:` | documentation only |
|
||||
| `chore:` | maintenance, dependencies |
|
||||
| `refactor:` | code change without new feature or fix |
|
||||
|
||||
Example: `fix: prevent crash when printer is offline during startup`
|
||||
|
||||
---
|
||||
|
||||
## Language
|
||||
|
||||
- **Code and comments:** English
|
||||
- **Issue comments:** match the language of the issue (if someone writes in German, reply in German)
|
||||
- **Commit messages:** English
|
||||
|
||||
---
|
||||
|
||||
## Questions?
|
||||
|
||||
Open a [Discussion](https://gitea.it-drui.de/viewit/KX-Bridge-Release/issues) or leave a comment on the relevant issue.
|
||||
27
README.de.md
27
README.de.md
@@ -21,7 +21,7 @@ Feedback willkommen.</sub>
|
||||
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
|
||||
[](https://www.youtube.com/watch?v=1Ql4wfH27fM)
|
||||
|
||||
@@ -29,6 +29,11 @@ Feedback willkommen.</sub>
|
||||
|
||||
</div>
|
||||
|
||||
> [!CAUTION]
|
||||
> **Laufende Wartungsarbeiten** — Wir strukturieren das Repository um (Branch-Modell, CI-Workflows, Beitragsprozess). Es kann zu Änderungen bei Branch-Namen, PR-Templates und der Art der Veröffentlichungen kommen. Wir entschuldigen uns für etwaige Unannehmlichkeiten. Handhabung, Workflow und langfristige Wartbarkeit werden dadurch deutlich verbessert.
|
||||
>
|
||||
> 👉 Möchtest du beitragen? Bitte zuerst [CONTRIBUTING.md](CONTRIBUTING.md) lesen.
|
||||
|
||||
---
|
||||
|
||||
## ✨ Was kann KX-Bridge?
|
||||
@@ -45,7 +50,7 @@ Feedback willkommen.</sub>
|
||||
| 🧩 | **Multi-Printer** — mehrere Drucker in **einer** Bridge-Instanz, Umschalten per Dropdown |
|
||||
| ➕ | **Drucker hinzufügen per Klick** — nur die IP eingeben, Zugangsdaten werden automatisch importiert |
|
||||
| 🔁 | **Robuster MQTT-Reconnect** — Bridge überlebt nächtlichen Drucker-Reboot ohne manuellen Neustart |
|
||||
| 🌐 | **Mehrsprachiges UI** — DE / EN / ES / 中文, Browser-Sprache automatisch erkannt |
|
||||
| 🌐 | **Mehrsprachiges UI** — DE / EN / ES / FR / IT / 中文, Browser-Sprache automatisch erkannt |
|
||||
| 🔄 | **Self-Update** — neue Versionen direkt im Browser installieren |
|
||||
| 🧠 | **OrcaSlicer** — volles Moonraker-Protokoll (HTTP + WebSocket); für korrekten Vendor-Match pro Slot den [OrcaSlicer-KX-Build](#-empfohlener-slicer) nutzen |
|
||||
|
||||
@@ -184,6 +189,24 @@ docker compose up -d --build # lokal selber bauen (statt zu pullen)
|
||||
|
||||
---
|
||||
|
||||
## 🌙 Nightly-Builds
|
||||
|
||||
Nightly-Builds enthalten die neuesten unveröffentlichten Features und werden automatisch bei jedem Entwicklungs-Push gebaut.
|
||||
Sie können instabil sein — für Tests oder frühen Zugriff auf neue Funktionen geeignet.
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yml -f docker-compose.nightly.yml pull
|
||||
docker compose -f docker-compose.yml -f docker-compose.nightly.yml up -d
|
||||
```
|
||||
|
||||
Zurück zum stabilen Release:
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🩹 Troubleshooting
|
||||
|
||||
<details>
|
||||
|
||||
61
README.es.md
61
README.es.md
@@ -20,7 +20,7 @@ ninguna está oficialmente probada ni soportada. Se agradece el feedback.</sub>
|
||||
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
|
||||
[](https://www.youtube.com/watch?v=1Ql4wfH27fM)
|
||||
|
||||
@@ -28,6 +28,11 @@ ninguna está oficialmente probada ni soportada. Se agradece el feedback.</sub>
|
||||
|
||||
</div>
|
||||
|
||||
> [!CAUTION]
|
||||
> **Trabajos de mantenimiento en curso** — Estamos reestructurando el repositorio (modelo de ramas, flujos CI, proceso de contribución). Es posible que notes cambios en los nombres de ramas, plantillas de PR y la forma en que se publican las versiones. Pedimos disculpas por las molestias. El manejo, el flujo de trabajo y la mantenibilidad a largo plazo mejorarán considerablemente.
|
||||
>
|
||||
> 👉 ¿Quieres contribuir? Por favor lee [CONTRIBUTING.md](CONTRIBUTING.md) primero.
|
||||
|
||||
---
|
||||
|
||||
## ✨ Características
|
||||
@@ -44,7 +49,7 @@ ninguna está oficialmente probada ni soportada. Se agradece el feedback.</sub>
|
||||
| 🧩 | **Multi-impresora** — múltiples impresoras en **una** instancia del puente, cambia mediante un menú desplegable |
|
||||
| ➕ | **Añade una impresora con un clic** — solo introduce la IP, las credenciales se importan automáticamente |
|
||||
| 🔁 | **Reconexión MQTT robusta** — el puente sobrevive a reinicios nocturnos de la impresora sin reinicio manual |
|
||||
| 🌐 | **Interfaz multilingüe** — DE / EN / ES / 中文, detecta automáticamente el idioma del navegador |
|
||||
| 🌐 | **Interfaz multilingüe** — DE / EN / ES / FR / IT / 中文, detecta automáticamente el idioma del navegador |
|
||||
| 🔄 | **Actualización automática** — instala nuevas versiones directamente desde el navegador |
|
||||
| 🧠 | **OrcaSlicer** — protocolo Moonraker completo (HTTP + WebSocket); usa el [build OrcaSlicer-KX](#-slicer-recomendado) para emparejamiento correcto de vendor por ranura |
|
||||
|
||||
@@ -66,43 +71,17 @@ docker compose up -d
|
||||
|
||||
**Binario Linux (sin Docker):**
|
||||
```bash
|
||||
chmod +x kx-bridge-linux-amd64 && ./kx-bridge-linux-amd64
|
||||
chmod +x kx-bridge && ./kx-bridge
|
||||
```
|
||||
|
||||
**EXE Windows (sin Docker):**
|
||||
```
|
||||
kx-bridge.exe
|
||||
```
|
||||
> `config\` y `data\` se crean junto al EXE — instalación portátil.
|
||||
|
||||
> ⚠️ **Certificados TLS necesarios para el binario standalone**
|
||||
>
|
||||
> El bridge habla con el MQTT de la impresora vía mTLS y necesita dos
|
||||
> ficheros de certificado **junto al binario**:
|
||||
>
|
||||
> - `anycubic_slicer.crt`
|
||||
> - `anycubic_slicer.key`
|
||||
>
|
||||
> Ambos vienen en **`anycubic-certs.zip`** en la misma página de release.
|
||||
> Descárgalo y extrae los dos ficheros en el mismo directorio que
|
||||
> `kx-bridge-linux-amd64` o `kx-bridge.exe`. Sin ellos verás
|
||||
> `Verbindung fehlgeschlagen: TLS-Zertifikate fehlen …` (0.9.19.1+) o
|
||||
> `[Errno 2] No such file or directory` (versiones anteriores).
|
||||
>
|
||||
> Estructura correcta:
|
||||
> ```
|
||||
> ~/kx-bridge/
|
||||
> ├── kx-bridge-linux-amd64 (o kx-bridge.exe)
|
||||
> ├── anycubic_slicer.crt ← de anycubic-certs.zip
|
||||
> ├── anycubic_slicer.key ← de anycubic-certs.zip
|
||||
> └── config/ (se crea en el primer arranque)
|
||||
> ```
|
||||
>
|
||||
> Los usuarios de Docker no necesitan hacer esto — los certificados
|
||||
> están incluidos en la imagen.
|
||||
|
||||
> Con los binarios de Linux y Windows, `config/` y `data/` (configuración,
|
||||
> SQLite, almacén de GCode) viven junto al programa. Copia toda la carpeta
|
||||
> para mover la instalación.
|
||||
> Con los binarios de Linux y Windows, `config/` y `data/` (configuración, SQLite, almacén de GCode)
|
||||
> viven junto al programa. Copia toda la carpeta para mover la instalación.
|
||||
|
||||
**Python directamente:**
|
||||
```bash
|
||||
@@ -208,6 +187,24 @@ docker compose up -d --build # recompilar localmente (en lugar de desc
|
||||
|
||||
---
|
||||
|
||||
## 🌙 Builds nocturnos (Nightly)
|
||||
|
||||
Los builds nocturnos contienen las últimas funciones no publicadas y se generan automáticamente en cada push de desarrollo.
|
||||
Pueden ser inestables — úsalos para pruebas o acceso anticipado a nuevas funciones.
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yml -f docker-compose.nightly.yml pull
|
||||
docker compose -f docker-compose.yml -f docker-compose.nightly.yml up -d
|
||||
```
|
||||
|
||||
Volver a la versión estable:
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🩹 Solución de problemas
|
||||
|
||||
<details>
|
||||
|
||||
27
README.md
27
README.md
@@ -20,7 +20,7 @@ officially tested or supported. Feedback welcome.</sub>
|
||||
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
[](https://gitea.it-drui.de/viewit/KX-Bridge-Release/releases)
|
||||
|
||||
[](https://www.youtube.com/watch?v=1Ql4wfH27fM)
|
||||
|
||||
@@ -28,6 +28,11 @@ officially tested or supported. Feedback welcome.</sub>
|
||||
|
||||
</div>
|
||||
|
||||
> [!CAUTION]
|
||||
> **Ongoing maintenance work** — We are restructuring the repository (branch model, CI workflows, contribution process). You may notice changes to branch names, PR templates, and how releases are published. We apologise for any inconvenience. Handling, workflow, and long-term maintainability will be significantly improved as a result.
|
||||
>
|
||||
> 👉 Want to contribute? Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
|
||||
|
||||
---
|
||||
|
||||
## ✨ Features
|
||||
@@ -44,7 +49,7 @@ officially tested or supported. Feedback welcome.</sub>
|
||||
| 🧩 | **Multi-printer** — multiple printers in **one** bridge instance, switch via dropdown |
|
||||
| ➕ | **Add a printer with one click** — just enter the IP, credentials are imported automatically |
|
||||
| 🔁 | **Robust MQTT reconnect** — bridge survives overnight printer reboots without manual restart |
|
||||
| 🌐 | **Multi-language UI** — DE / EN / ES / 中文, auto-detect browser locale |
|
||||
| 🌐 | **Multi-language UI** — DE / EN / ES / FR / IT / 中文, auto-detect browser locale |
|
||||
| 🔄 | **Self-update** — install new versions directly in the browser |
|
||||
| 🧠 | **OrcaSlicer** — full Moonraker protocol (HTTP + WebSocket); pair with the [OrcaSlicer-KX build](#-recommended-slicer) for proper per-slot vendor matching |
|
||||
|
||||
@@ -182,6 +187,24 @@ docker compose up -d --build # rebuild locally (instead of pulling)
|
||||
|
||||
---
|
||||
|
||||
## 🌙 Nightly Builds
|
||||
|
||||
Nightly builds contain the latest unreleased features and are built automatically on every development push.
|
||||
They may be unstable — use them for testing or early access to new functionality.
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yml -f docker-compose.nightly.yml pull
|
||||
docker compose -f docker-compose.yml -f docker-compose.nightly.yml up -d
|
||||
```
|
||||
|
||||
To go back to the stable release:
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🩹 Troubleshooting
|
||||
|
||||
<details>
|
||||
|
||||
31
agents.md
Normal file
31
agents.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# KX-Bridge Claude Agents
|
||||
|
||||
## Available Agents
|
||||
|
||||
| Agent | File | When to use |
|
||||
|---|---|---|
|
||||
| Reviewer | `.claude/agents/reviewer.md` | Before every PR — checks logic, error handling, Moonraker compatibility |
|
||||
| Changelog | `.claude/agents/changelog.md` | After merge to nightly — generates CHANGELOG.md entry from commits |
|
||||
| Test Writer | `.claude/agents/test-writer.md` | When adding new functions — derives pytest tests |
|
||||
| Nightly Prep | `.claude/agents/nightly-prep.md` | Before a release — checks readiness of nightly → main merge |
|
||||
| Docker Check | `.claude/agents/docker-check.md` | Before image push — validates Dockerfile and compose config |
|
||||
| Moonraker Debug | `.claude/agents/moonraker-debug.md` | On runtime errors — analyzes Moonraker/Klipper logs |
|
||||
|
||||
## Usage
|
||||
|
||||
In VS Code with Claude Code extension:
|
||||
```
|
||||
@reviewer → code review of current changes
|
||||
@changelog → generate CHANGELOG entry
|
||||
@test-writer → write tests for changed files
|
||||
@nightly-prep → check release readiness
|
||||
@docker-check → validate Docker config
|
||||
@moonraker-debug → analyze logs
|
||||
```
|
||||
|
||||
## Context
|
||||
|
||||
- Moonraker API: Port 7125
|
||||
- AFC lane_data: flat indexing lane1–lane4
|
||||
- Registry: `gitea.it-drui.de/viewit/kx-bridge`
|
||||
- Default PR target: `nightly`
|
||||
210
docker-compose-KX.yml
Normal file
210
docker-compose-KX.yml
Normal file
@@ -0,0 +1,210 @@
|
||||
# KobraX Full Stack — KX-Bridge + Obico Self-Hosted + Spoolman
|
||||
#
|
||||
# Für Portainer: Stack → Add Stack → Upload → diese Datei wählen
|
||||
#
|
||||
# Voraussetzung: Obico-Images einmalig in Gitea-Registry pushen:
|
||||
# docker tag obico-server-web:latest gitea.it-drui.de/viewit/obico-web:latest
|
||||
# docker tag obico-server-ml_api:latest gitea.it-drui.de/viewit/obico-ml:latest
|
||||
# docker tag obico-server-tasks:latest gitea.it-drui.de/viewit/obico-tasks:latest
|
||||
# docker push gitea.it-drui.de/viewit/obico-web:latest
|
||||
# docker push gitea.it-drui.de/viewit/obico-ml:latest
|
||||
# docker push gitea.it-drui.de/viewit/obico-tasks:latest
|
||||
#
|
||||
# Persistente Daten: /mnt/dockerdata/KobraXStack/<service>/
|
||||
#
|
||||
# Ports:
|
||||
# 7125 — KX-Bridge (Moonraker-API)
|
||||
# 3334 — Obico (Web-UI)
|
||||
# 7912 — Spoolman (Web-UI)
|
||||
#
|
||||
# Obico Admin-Account nach dem ersten Start:
|
||||
# docker exec obico-web python manage.py createsuperuser
|
||||
|
||||
x-obico-base: &obico-base
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/dockerdata/KobraXStack/obico/data:/data
|
||||
- /mnt/dockerdata/KobraXStack/obico/frontend:/frontend
|
||||
depends_on:
|
||||
- obico-redis
|
||||
environment:
|
||||
DEBUG: "False"
|
||||
REDIS_URL: "redis://obico-redis:6379"
|
||||
DATABASE_URL: "sqlite:////data/db.sqlite3"
|
||||
INTERNAL_MEDIA_HOST: "http://obico-web:3334"
|
||||
ML_API_HOST: "http://obico-ml:3333"
|
||||
ACCOUNT_ALLOW_SIGN_UP: "False"
|
||||
SITE_USES_HTTPS: "False"
|
||||
SITE_IS_PUBLIC: "False"
|
||||
DJANGO_SECRET_KEY: "change-me-to-a-random-secret-key-before-use"
|
||||
WEBPACK_LOADER_ENABLED: "False"
|
||||
networks:
|
||||
- kobrax-stack
|
||||
|
||||
services:
|
||||
|
||||
# ── KX-Bridge ───────────────────────────────────────────────
|
||||
kx-bridge:
|
||||
image: gitea.it-drui.de/viewit/kx-bridge:latest
|
||||
container_name: kx-bridge
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "7125:7125"
|
||||
volumes:
|
||||
- /mnt/dockerdata/KobraXStack/kx-bridge/config:/app/config
|
||||
- /mnt/dockerdata/KobraXStack/kx-bridge/data:/app/data
|
||||
networks:
|
||||
- kobrax-stack
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ── Spoolman ────────────────────────────────────────────────
|
||||
spoolman:
|
||||
image: ghcr.io/donkie/spoolman:latest
|
||||
container_name: spoolman
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "7912:8000"
|
||||
volumes:
|
||||
- /mnt/dockerdata/KobraXStack/spoolman:/home/app/.local/share/spoolman
|
||||
networks:
|
||||
- kobrax-stack
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ── Obico Redis ─────────────────────────────────────────────
|
||||
obico-redis:
|
||||
image: redis:7.2-alpine
|
||||
container_name: obico-redis
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/dockerdata/KobraXStack/obico/redis:/data
|
||||
networks:
|
||||
- kobrax-stack
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
start_period: 10s
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "5m"
|
||||
max-file: "2"
|
||||
|
||||
# ── Obico ML API ────────────────────────────────────────────
|
||||
obico-ml:
|
||||
image: gitea.it-drui.de/viewit/obico-ml:latest
|
||||
container_name: obico-ml
|
||||
restart: unless-stopped
|
||||
command: bash -c "gunicorn --bind 0.0.0.0:3333 --workers 1 wsgi"
|
||||
working_dir: /app
|
||||
environment:
|
||||
DEBUG: "False"
|
||||
FLASK_APP: "server.py"
|
||||
networks:
|
||||
- kobrax-stack
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:3333/hc/ || exit 1"]
|
||||
start_period: 30s
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ── Obico Web ───────────────────────────────────────────────
|
||||
obico-web:
|
||||
<<: *obico-base
|
||||
image: gitea.it-drui.de/viewit/obico-web:latest
|
||||
container_name: obico-web
|
||||
ports:
|
||||
- "3334:3334"
|
||||
depends_on:
|
||||
- obico-ml
|
||||
- obico-redis
|
||||
command: >
|
||||
sh -c 'python manage.py migrate &&
|
||||
python manage.py shell -c "from django.contrib.sites.models import Site; s=Site.objects.first(); s.domain=\"192.168.178.204:3334\"; s.name=\"Obico\"; s.save()" &&
|
||||
python manage.py collectstatic --noinput &&
|
||||
daphne -b 0.0.0.0 -p 3334 config.routing:application'
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:3334/hc/ || exit 1"]
|
||||
start_period: 60s
|
||||
interval: 90s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ── Obico Tasks (Celery) ────────────────────────────────────
|
||||
obico-tasks:
|
||||
<<: *obico-base
|
||||
image: gitea.it-drui.de/viewit/obico-tasks:latest
|
||||
container_name: obico-tasks
|
||||
command: sh -c "celery -A config worker --beat -l info -c 2 -Q realtime,celery"
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ── moonraker-obico Plugin ──────────────────────────────────
|
||||
# Verbindet KX-Bridge mit dem Obico-Server (Spaghetti-Detektion, Remote-UI)
|
||||
# Voraussetzung: /mnt/dockerdata/KobraXStack/moonraker-obico/moonraker-obico.cfg
|
||||
# muss existieren und einen gültigen auth_token enthalten.
|
||||
#
|
||||
# Token holen (nach erstem obico-web Start):
|
||||
# docker exec obico-web python manage.py shell -c "
|
||||
# from app.models import OneTimeVerificationCode, User
|
||||
# from django.utils import timezone; from datetime import timedelta; import random
|
||||
# u = User.objects.first()
|
||||
# c = OneTimeVerificationCode.objects.create(user=u, code='%06d' % random.randint(100000,999999), expired_at=timezone.now()+timedelta(hours=2))
|
||||
# print('CODE:', c.code)"
|
||||
# curl -X POST 'http://localhost:3334/api/v1/octo/verify/?code=<CODE>'
|
||||
# → printer.auth_token aus der Antwort in die cfg eintragen
|
||||
moonraker-obico:
|
||||
image: gitea.it-drui.de/viewit/moonraker-obico:latest
|
||||
container_name: moonraker-obico
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /mnt/dockerdata/KobraXStack/moonraker-obico:/opt/printer_data/config
|
||||
- /mnt/dockerdata/KobraXStack/moonraker-obico/logs:/opt/printer_data/logs
|
||||
command: ["-c", "/opt/printer_data/config/moonraker-obico.cfg"]
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
networks:
|
||||
kobrax-stack:
|
||||
driver: bridge
|
||||
|
||||
# Verzeichnisse müssen auf dem Host existieren:
|
||||
# mkdir -p /mnt/dockerdata/KobraXStack/kx-bridge/config \
|
||||
# /mnt/dockerdata/KobraXStack/kx-bridge/data \
|
||||
# /mnt/dockerdata/KobraXStack/spoolman \
|
||||
# /mnt/dockerdata/KobraXStack/obico/data \
|
||||
# /mnt/dockerdata/KobraXStack/obico/frontend \
|
||||
# /mnt/dockerdata/KobraXStack/obico/redis \
|
||||
# /mnt/dockerdata/KobraXStack/moonraker-obico/logs
|
||||
# Spoolman benötigt UID/GID 1000:
|
||||
# sudo chown -R 1000:1000 /mnt/dockerdata/KobraXStack/spoolman
|
||||
#
|
||||
# moonraker-obico Config anlegen (auth_token nach Obico-Setup eintragen):
|
||||
# cp /path/to/moonraker-obico.cfg.example /mnt/dockerdata/KobraXStack/moonraker-obico/moonraker-obico.cfg
|
||||
3
docker-compose.nightly.yml
Normal file
3
docker-compose.nightly.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
services:
|
||||
kx-bridge:
|
||||
image: gitea.it-drui.de/viewit/kx-bridge:nightly
|
||||
25
docker-compose.portainer-nightly.yml
Normal file
25
docker-compose.portainer-nightly.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
# KX-Bridge Nightly — Portainer Stack
|
||||
#
|
||||
# Paste this into Portainer → Stacks → Add stack → Web editor
|
||||
#
|
||||
# Uses the nightly build — may be unstable, for testing new features early.
|
||||
# For production use, see docker-compose.portainer.yml (:latest).
|
||||
|
||||
services:
|
||||
kx-bridge:
|
||||
image: gitea.it-drui.de/viewit/kx-bridge:nightly
|
||||
volumes:
|
||||
- /mnt/dockerdata/kx-nightly/config:/app/config
|
||||
- /mnt/dockerdata/kx-nightly/data:/app/data
|
||||
ports:
|
||||
# Port 7125 = first printer. Add 7126, 7127, … for each additional printer.
|
||||
- "7125:7125"
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Verzeichnisse müssen auf dem Host existieren:
|
||||
# mkdir -p /mnt/dockerdata/kx-nightly/config /mnt/dockerdata/kx-nightly/data
|
||||
@@ -4488,7 +4488,8 @@ class KobraXBridge:
|
||||
for _k in ("PRINTER_IP", "MQTT_PORT", "MQTT_USERNAME", "MQTT_PASSWORD",
|
||||
"MODE_ID", "DEVICE_ID", "DEFAULT_AMS_SLOT", "AUTO_LEVELING",
|
||||
"CAMERA_ON_PRINT", "WEB_UPLOAD_WARNING", "PRINT_START_DIALOG",
|
||||
"FILE_READY_DIALOG", "BRIDGE_PRINTER_NAME"):
|
||||
"FILE_READY_DIALOG", "BRIDGE_PRINTER_NAME",
|
||||
"SPOOLMAN_SERVER", "SPOOLMAN_SYNC_RATE"):
|
||||
os.environ.pop(_k, None)
|
||||
|
||||
in_docker = os.path.exists("/.dockerenv") or os.environ.get("KX_IN_DOCKER")
|
||||
@@ -4524,9 +4525,10 @@ class KobraXBridge:
|
||||
|
||||
# ─── Update ──────────────────────────────────────────────────────────────
|
||||
|
||||
STABLE_RELEASE_API = "https://gitea.it-drui.de/api/v1/repos/viewit/KX-Bridge-Release/releases?limit=1"
|
||||
DEV_RELEASE_API = "https://gitea.it-drui.de/api/v1/repos/viewit/KX-Bridge-Release/releases?limit=10&pre-release=true"
|
||||
GITEA_RAW_BASE = "https://gitea.it-drui.de/viewit/KX-Bridge-Release/raw/tag"
|
||||
STABLE_RELEASE_API = "https://gitea.it-drui.de/api/v1/repos/viewit/KX-Bridge-Release/releases?limit=1"
|
||||
NIGHTLY_RELEASE_API = "https://gitea.it-drui.de/api/v1/repos/viewit/KX-Bridge-Release/releases?limit=5&pre-release=true"
|
||||
DEV_RELEASE_API = "https://gitea.it-drui.de/api/v1/repos/viewit/KX-Bridge-Release/releases?limit=10&pre-release=true"
|
||||
GITEA_RAW_BASE = "https://gitea.it-drui.de/viewit/KX-Bridge-Release/raw/tag"
|
||||
|
||||
def _read_version(self) -> str:
|
||||
# PyInstaller-Onefile entpackt VERSION (per kx-bridge.spec datas) nach
|
||||
@@ -4601,8 +4603,14 @@ class KobraXBridge:
|
||||
|
||||
async def handle_api_update_check(self, request):
|
||||
current = self._read_version()
|
||||
is_nightly = "nightly" in current
|
||||
is_dev = "-dev+" in current
|
||||
api_url = self.DEV_RELEASE_API if is_dev else self.STABLE_RELEASE_API
|
||||
if is_nightly:
|
||||
api_url = self.NIGHTLY_RELEASE_API
|
||||
elif is_dev:
|
||||
api_url = self.DEV_RELEASE_API
|
||||
else:
|
||||
api_url = self.STABLE_RELEASE_API
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(api_url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
|
||||
@@ -4611,14 +4619,37 @@ class KobraXBridge:
|
||||
releases = await resp.json(content_type=None)
|
||||
if not releases:
|
||||
return web.json_response({"error": "Keine Releases gefunden"}, status=404)
|
||||
# Dev: neuestes Release mit "-dev+" im Tag suchen
|
||||
if is_dev:
|
||||
|
||||
if is_nightly:
|
||||
# Neuestes Prerelease mit nightly-Tag suchen
|
||||
nightly_releases = [r for r in releases if r.get("prerelease") and "nightly" in r.get("tag_name", "")]
|
||||
if not nightly_releases:
|
||||
return web.json_response({"error": "Keine Nightly-Releases gefunden"}, status=404)
|
||||
data = nightly_releases[0]
|
||||
tag = data.get("tag_name", "")
|
||||
# Tag-Format: "nightly-0.9.27-nightly4", current: "0.9.27-nightly4"
|
||||
tag_version = tag[len("nightly-"):] if tag.startswith("nightly-") else tag
|
||||
update_available = tag_version != current
|
||||
latest = tag
|
||||
return web.json_response({
|
||||
"current": current,
|
||||
"latest": latest,
|
||||
"update_available": update_available,
|
||||
"tag": tag,
|
||||
"docker_only": True,
|
||||
"changelog": data.get("body", ""),
|
||||
})
|
||||
elif is_dev:
|
||||
dev_releases = [r for r in releases if "-dev+" in r.get("tag_name", "")]
|
||||
if not dev_releases:
|
||||
return web.json_response({"error": "Keine Dev-Releases gefunden"}, status=404)
|
||||
data = dev_releases[0]
|
||||
else:
|
||||
data = releases[0]
|
||||
# Stable: nur non-prerelease nehmen
|
||||
stable_releases = [r for r in releases if not r.get("prerelease")]
|
||||
if not stable_releases:
|
||||
return web.json_response({"error": "Keine Stable-Releases gefunden"}, status=404)
|
||||
data = stable_releases[0]
|
||||
tag = data.get("tag_name", "")
|
||||
latest = tag.lstrip("v")
|
||||
if is_dev:
|
||||
@@ -4632,6 +4663,7 @@ class KobraXBridge:
|
||||
"update_available": update_available,
|
||||
"tag": tag,
|
||||
"download_url": download_url,
|
||||
"docker_only": False,
|
||||
"changelog": data.get("body", ""),
|
||||
})
|
||||
except Exception as e:
|
||||
@@ -4652,6 +4684,10 @@ class KobraXBridge:
|
||||
async def handle_api_update_apply(self, request):
|
||||
data = await request.json()
|
||||
new_tag = data.get("tag", "")
|
||||
if "nightly" in self._read_version():
|
||||
return web.json_response(
|
||||
{"error": "Nightly-Updates laufen über Docker: "
|
||||
"docker compose pull && docker compose up -d"}, status=400)
|
||||
if getattr(sys, "frozen", False):
|
||||
return web.json_response(
|
||||
{"error": "Self-Update wird im Binary-Modus nicht unterstützt – "
|
||||
|
||||
18
moonraker-obico.cfg.example
Normal file
18
moonraker-obico.cfg.example
Normal file
@@ -0,0 +1,18 @@
|
||||
[server]
|
||||
url = http://127.0.0.1:3334
|
||||
auth_token = REPLACE_ME
|
||||
sentry_opt = out
|
||||
|
||||
[moonraker]
|
||||
host = 127.0.0.1
|
||||
port = 7125
|
||||
|
||||
[webcam]
|
||||
disable_video_streaming = False
|
||||
snapshot_url = http://127.0.0.1:7125/api/camera/snapshot
|
||||
stream_url = http://127.0.0.1:7125/api/camera/stream
|
||||
target_fps = 5
|
||||
|
||||
[logging]
|
||||
path = /opt/printer_data/logs/moonraker-obico.log
|
||||
level = INFO
|
||||
21
pull_request_template.md
Normal file
21
pull_request_template.md
Normal file
@@ -0,0 +1,21 @@
|
||||
## Description
|
||||
<!-- What does this PR change? -->
|
||||
|
||||
## Related Issue
|
||||
Closes #
|
||||
|
||||
## Type
|
||||
- [ ] Bug fix
|
||||
- [ ] Feature
|
||||
- [ ] Documentation
|
||||
- [ ] Refactoring
|
||||
|
||||
## Tested with
|
||||
- OrcaSlicer Version:
|
||||
- Printer:
|
||||
- Moonraker/Klipper Version:
|
||||
|
||||
## Checklist
|
||||
- [ ] Tests added/updated
|
||||
- [ ] CHANGELOG.md updated
|
||||
- [ ] No debug code included
|
||||
@@ -1654,6 +1654,7 @@ function saveSettings(){
|
||||
btn.disabled=false;
|
||||
setText('btn-save-settings',T.settings_save);
|
||||
closeSettings();
|
||||
_loadSpoolmanStatus();
|
||||
poll();
|
||||
},4000);
|
||||
}).catch(function(e){
|
||||
@@ -1661,21 +1662,33 @@ function saveSettings(){
|
||||
clog('Settings-Fehler: '+e,'msg-err');
|
||||
});
|
||||
}
|
||||
var _updateDockerOnly=false;
|
||||
function checkUpdate(){
|
||||
var sb=document.getElementById('update-status');
|
||||
sb.textContent=T.update_checking;
|
||||
document.getElementById('btn-update-apply').style.display='none';
|
||||
_updateTag='';_updateUrl='';
|
||||
_updateTag='';_updateUrl='';_updateDockerOnly=false;
|
||||
fetch(_apiUrl('/api/update/check')).then(function(r){return r.json()}).then(function(d){
|
||||
if(d.error){sb.textContent=T.update_error+': '+d.error;return;}
|
||||
var cl=document.getElementById('update-changelog');
|
||||
if(d.changelog&&d.changelog.trim()){cl.textContent=d.changelog;cl.style.display='block';}
|
||||
else{cl.style.display='none';}
|
||||
if(d.changelog&&d.changelog.trim()){
|
||||
// Changelog als Markdown-Text (pre-formatiert) anzeigen
|
||||
cl.textContent=d.changelog;cl.style.display='block';
|
||||
} else {cl.style.display='none';}
|
||||
_updateDockerOnly=!!d.docker_only;
|
||||
if(d.update_available){
|
||||
sb.textContent='v'+d.latest+' '+T.update_available;
|
||||
sb.textContent=d.latest+' '+T.update_available;
|
||||
sb.style.color='var(--ok)';
|
||||
_updateTag=d.tag;_updateUrl=d.download_url;
|
||||
document.getElementById('btn-update-apply').style.display='inline-block';
|
||||
_updateTag=d.tag;_updateUrl=d.download_url||'';
|
||||
var btn=document.getElementById('btn-update-apply');
|
||||
if(_updateDockerOnly){
|
||||
btn.textContent=T.update_docker||'docker compose pull';
|
||||
btn.title='docker compose pull && docker compose up -d';
|
||||
} else {
|
||||
btn.textContent=T.update_apply;
|
||||
btn.title='';
|
||||
}
|
||||
btn.style.display='inline-block';
|
||||
} else {
|
||||
sb.textContent=T.update_none;
|
||||
sb.style.color='var(--txt2)';
|
||||
@@ -1683,9 +1696,21 @@ function checkUpdate(){
|
||||
}).catch(function(e){sb.textContent=T.update_error+': '+e;});
|
||||
}
|
||||
function applyUpdate(){
|
||||
if(!_updateUrl)return;
|
||||
var sb=document.getElementById('update-status');
|
||||
var btn=document.getElementById('btn-update-apply');
|
||||
if(_updateDockerOnly){
|
||||
// Nightly: kein Self-Update, Docker-Befehl in Zwischenablage kopieren
|
||||
var cmd='docker compose pull && docker compose up -d';
|
||||
if(navigator.clipboard){
|
||||
navigator.clipboard.writeText(cmd).then(function(){
|
||||
sb.textContent=T.update_docker_copied||'Befehl kopiert: '+cmd;
|
||||
});
|
||||
} else {
|
||||
sb.textContent=cmd;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!_updateUrl)return;
|
||||
btn.disabled=true;sb.textContent=T.update_applying;
|
||||
post('/api/update/apply',{download_url:_updateUrl,tag:_updateTag}).then(function(){
|
||||
sb.textContent=T.update_restarting;
|
||||
|
||||
@@ -321,6 +321,8 @@
|
||||
"update_available": "verfügbar",
|
||||
"update_check": "Auf Updates prüfen",
|
||||
"update_checking": "Prüfe...",
|
||||
"update_docker": "Befehl kopieren",
|
||||
"update_docker_copied": "Kopiert! Ausführen: docker compose pull && docker compose up -d",
|
||||
"update_error": "Fehler",
|
||||
"update_none": "Bereits aktuell",
|
||||
"update_restarting": "Starte neu..."
|
||||
|
||||
@@ -321,6 +321,8 @@
|
||||
"update_available": "available",
|
||||
"update_check": "Check for Updates",
|
||||
"update_checking": "Checking...",
|
||||
"update_docker": "Copy Command",
|
||||
"update_docker_copied": "Copied! Run: docker compose pull && docker compose up -d",
|
||||
"update_error": "Error",
|
||||
"update_none": "Already up to date",
|
||||
"update_restarting": "Restarting..."
|
||||
|
||||
@@ -321,6 +321,8 @@
|
||||
"update_available": "disponible",
|
||||
"update_check": "Buscar actualizaciones",
|
||||
"update_checking": "Comprobando...",
|
||||
"update_docker": "Copiar comando",
|
||||
"update_docker_copied": "Copiado. Ejecutar: docker compose pull && docker compose up -d",
|
||||
"update_error": "Error",
|
||||
"update_none": "Ya actualizado",
|
||||
"update_restarting": "Reiniciando..."
|
||||
|
||||
@@ -321,6 +321,8 @@
|
||||
"update_available": "disponible",
|
||||
"update_check": "Vérifier les mises à jour",
|
||||
"update_checking": "Vérification…",
|
||||
"update_docker": "Copier la commande",
|
||||
"update_docker_copied": "Copié ! Exécuter : docker compose pull && docker compose up -d",
|
||||
"update_error": "Erreur",
|
||||
"update_none": "Déjà à jour",
|
||||
"update_restarting": "Redémarrage…"
|
||||
|
||||
@@ -321,6 +321,8 @@
|
||||
"update_available": "disponibile",
|
||||
"update_check": "Controlla aggiornamenti",
|
||||
"update_checking": "Verifica in corso...",
|
||||
"update_docker": "Copia comando",
|
||||
"update_docker_copied": "Copiato! Eseguire: docker compose pull && docker compose up -d",
|
||||
"update_error": "Errore",
|
||||
"update_none": "Già aggiornato",
|
||||
"update_restarting": "Riavvio in corso..."
|
||||
|
||||
@@ -321,6 +321,8 @@
|
||||
"update_available": "可用",
|
||||
"update_check": "检查更新",
|
||||
"update_checking": "检查中...",
|
||||
"update_docker": "复制命令",
|
||||
"update_docker_copied": "已复制!执行:docker compose pull && docker compose up -d",
|
||||
"update_error": "错误",
|
||||
"update_none": "已是最新版本",
|
||||
"update_restarting": "重启中..."
|
||||
|
||||
Reference in New Issue
Block a user