feat: Integrationen-Tab + KobraX Full Stack Compose + CI-Workflow

- Settings-Tab "Integrationen": Spoolman URL/Sync-Rate konfigurierbar,
  Obico Read-only Hinweis auf moonraker-obico.cfg
- docker-compose-KX.yml: Portainer-kompatibler Full Stack (KX-Bridge +
  Obico Self-Hosted + Spoolman + moonraker-obico Plugin)
- moonraker-obico.cfg.example: Verbindungsvorlage für Obico-Integration
- .gitea/workflows/docker-publish.yml: Push auf nightly → :nightly Image,
  v*-Tag → :latest + :<VERSION>
This commit is contained in:
2026-06-24 12:58:46 +02:00
parent 3595cf839c
commit 72f77d92af
12 changed files with 388 additions and 12 deletions

View File

@ -4218,6 +4218,8 @@ class KobraXBridge:
"filament_profiles": {str(k): v for k, v in self._filament_profiles.items()},
"visible_vendors": self._visible_vendors,
"ace_dry_presets": self._ace_dry_presets,
"spoolman_server": getattr(self._args, "spoolman_server", "") or "",
"spoolman_sync_rate": getattr(self._args, "spoolman_sync_rate", 0),
})
async def handle_api_settings_post(self, request):
@ -4232,7 +4234,7 @@ class KobraXBridge:
cfg.read(config_path, encoding="utf-8")
# Sections sicherstellen
for section in ("connection", "print", "bridge", "ace_dry_presets"):
for section in ("connection", "print", "bridge", "ace_dry_presets", "spoolman"):
if not cfg.has_section(section):
cfg.add_section(section)
@ -4262,6 +4264,16 @@ class KobraXBridge:
elif cfg.has_option("bridge", "printer_name"):
cfg.remove_option("bridge", "printer_name")
# Spoolman
if "spoolman_server" in data:
cfg.set("spoolman", "server", str(data["spoolman_server"]).strip())
if "spoolman_sync_rate" in data:
try:
sr = max(0, int(data["spoolman_sync_rate"]))
except (TypeError, ValueError):
sr = 30
cfg.set("spoolman", "sync_rate", str(sr))
incoming_presets = data.get("ace_dry_presets") if isinstance(data, dict) else None
presets = self._sanitize_ace_dry_presets(incoming_presets if isinstance(incoming_presets, dict) else self._ace_dry_presets)
for key, val in presets.items():