Slice-Watch mit Ordnern/Filtern, Orca-Nachbearbeitung, Cockpit-Verlauf mit ED, Zeitzone im Browser. Tasten-Grenze und README-API angeglichen, toter Code entfernt, Requirements gepinnt.
83 lines
6.9 KiB
Markdown
83 lines
6.9 KiB
Markdown
# Grotti: Senden und Start dauert
|
||
|
||
Stand **15.10.2026** (Stack-Quellen und Task-Hygiene in [Anycubic-Stack](Anycubic-Stack)). Spulen kommen vom Ziel-Drucker zur Startzeit (`ace_map` + eingelegte Rolle), nicht aus einem freien Dropdown. `sends` speichert `ace_map` und Bettnetz für „Nochmal“.
|
||
|
||
## Warum Sekunden / Minuten
|
||
|
||
Über Grotti-App (`Dateien` → Starten) läuft der Aufruf nicht nur lokal: die Datei wird als **ein synchroner Multipart-POST** an Moonraker hochgeladen (`/server/files/upload`), danach startet `/printer/print/start`. Der HTTP-Request endet erst, wenn Moonraker die Datei geschrieben und oft Metadaten/MMU-Preprocess angeschoben hat — bis dahin wirkt die Queue „still“.
|
||
|
||
Messung 12.10.2026, `tulip pla.gcode` (~**50,4 MB** in `data/eingang`, typisch daneben ~2 MB): Upload auf `da26` (`10.10.1.60`) **~67 s** laut Moonraker-Log (`201 POST … 67106 ms`), plus kurze `.acm`-Sidecar (~87 ms) und Start. Gesamter Queue-Job ~**96 s**. Kleine Dateien bleiben im Sekundenbereich.
|
||
|
||
13.10.2026: Die lange Pause bei „50/50 MB“ ist Rinkhals `mmu_ace_metadata.py`. Der liest die ganze Datei auf der Kobra, bevor der Upload-HTTP antwortet, und schreibt sie bei gefundenen Werkzeugen noch einmal um. Grotti setzt vorher die Kopfzeile `; processed by MmuAcePatcher`. Bei Prusa, Super, Orca, Bambu oder AnycubicSlicerNext und Werkzeugen (`T0`, `MMU_CHANGE_TOOL`) hängt sie `; referenced_tools = …` an — dieselbe Zeile, die der Drucker sonst selbst schreibt. Danach überspringt er diesen Durchlauf. Stehen die Bytes, wechselt die Anzeige auf „liest die Datei…“. Grotti neu starten (`use_reloader=False`).
|
||
|
||
Vorher prüft Grotti Online-Status und ob schon gedruckt wird — laufende Drucke werden nicht abgebrochen. Die Rinkhals-Touch-UI können wir nicht umbauen; Fortschritt betrifft Grotti unter `:8770`.
|
||
|
||
## Queue (Grotti)
|
||
|
||
Ab 12.10.2026: Start legt Hintergrund-Aufträge an (`pending` → `running` → `done`/`error`). Pro gewähltem Drucker ein Queue-Job; mehrere Worker. UI pollt ~500 ms. Beim Hochladen zeigt die Queue jetzt **MB-Fortschritt** (urllib liest den Body gestreamt); Timeout skaliert mit Dateigröße (ca. 180–600 s). Bestätigung „Druck wirklich starten“ bleibt Pflicht. Nach Python-Änderung Grotti neu starten (`use_reloader=False`).
|
||
|
||
## Slice-Ordner / Upload
|
||
|
||
Slice-Ordner unter **Einstellungen** (persistiert als `watch_dir`). Ohne Ordner geht Hochladen über die Dateien-Seite trotzdem.
|
||
|
||
**Dateinamen:** Moonraker-Multipart nutzt nur noch einen ASCII-`filename` (`moonraker.safe_upload_name`). Früher standen Nicht-ASCII-Zeichen in `filename*=UTF-8''…`, während `filename=` Unterstriche bekam — gklib speicherte A, Start suchte B → **10115 not found**.
|
||
|
||
## ACE / `.acm`
|
||
|
||
Drucker mit ACE/MMU-Plätzen (`mmu.gate_color` / `gate_material`, Grotti-`slots`) brauchen vor `print/start` eine Sidecar-Datei `*.gcode.acm`. In der UI unter Optionen → ACE-Zuordnung (Datei-Farbe → Platz). Ohne passende `.acm` lehnt der Drucker oft mit „cannot parse the file“ ab — Details hier, nicht als Banner in der App:
|
||
|
||
```json
|
||
{"use_ams":true,"ams_box_mapping":[{"paint_index":0,"paint_color":[r,g,b],"material_type":"PLA","ams_index":1,"ams_color":[r,g,b]}]}
|
||
```
|
||
|
||
`paint_index` = Farbe in der Slice-Datei (0-basiert), `ams_index` = ACE-Platz 0-basiert. Externe Spule / keine Slots: kein `.acm`. Keine Community-Makros (`ACE_SET_SLOT` / `G9111`).
|
||
|
||
AnycubicSlicerNext schreibt die Farben oft als `; paint_info: [{...}]` statt `filament_type` — Grotti liest das seit 12.10.2026 mit.
|
||
|
||
## Bettnetz / auto_leveling beim Start (12.10.2026)
|
||
|
||
Rinkhals `kobra.py` `mqtt_print_file` baut den Anycubic-MQTT-Start so (Topic `…/slicer/printer/{modelId}/{deviceId}/print`, lokal `127.0.0.1:2883`):
|
||
|
||
```json
|
||
{
|
||
"type": "print",
|
||
"action": "start",
|
||
"msgid": "<uuid>",
|
||
"timestamp": 1660201929871,
|
||
"data": {
|
||
"filename": "job.gcode",
|
||
"filepath": "/",
|
||
"taskid": "123456",
|
||
"task_mode": 1,
|
||
"filetype": 1,
|
||
"task_settings": {
|
||
"auto_leveling": 1,
|
||
"vibration_compensation": 0,
|
||
"flow_calibration": 0
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
`auto_leveling` ist **0/1** (Integer). `1` löst die Anycubic-Nivellierfolge beim Jobstart aus (LeviQ / Netz messen) — nicht über G-code `LEVIQ_*` / `BED_MESH_CALIBRATE` / `SAVE_CONFIG` von Grotti. Ohne Grotti-Flag kommt der Wert aus der **globalen** App-Property `40-moonraker` → `mqtt_print_auto_leveling` (Default `False`). Extra-Felder an Moonraker `POST /printer/print/start` werden ignoriert. App-Property setzen geht nur per SSH (`set_app_property 40-moonraker mqtt_print_auto_leveling True`), keine HTTP-API.
|
||
|
||
### Grotti-Verhalten
|
||
|
||
| Checkbox / ACE | Startweg |
|
||
| --- | --- |
|
||
| kein Bettnetz, keine ACE-Map | Upload + Moonraker `print/start` → Rinkhals MQTT (globale `auto_leveling`, oft 0) |
|
||
| ACE-Map gesetzt | Upload + `.acm` (Basename + Stamm-Variante) + **Grotti-MQTT** mit `ams_settings` aus der Map; `auto_leveling` nur 1 wenn Bettnetz an |
|
||
| Bettnetz an | wie ACE-Map-Pfad, `auto_leveling:1` |
|
||
|
||
Credentials holt Grotti ohne SSH: `GET :18910/info` → signiertes `POST :18910/ctrl` → AES-Decrypt (Username/Password/`deviceId`). Port **2883** ist vom PC zu; **9883** (TLS, Cert-Check aus) ist offen. Mit Grotti-MQTT liegt `ams_box_mapping` explizit in der Payload (kein Moonraker-Identity-Fallback). Ohne `; referenced_tools`-Trailer: Warnung in UI/Queue, kein Fake-Trailer.
|
||
|
||
**Abbruch:** Grotti `abbrechen` = Moonraker `/printer/print/cancel` **plus** MQTT `action: stop` / `taskid: "-1"` (gleicher Topic wie Start). Nur Moonraker-cancel lässt den Anycubic-Task stehen → nächster MQTT-Start mit **10101**. 13.10.2026: Gridfinity auf da26 so hängen geblieben, per MQTT-stop freigemacht (`data.state: free`).
|
||
|
||
### Task-Hygiene vor dem Start (15.10.2026)
|
||
|
||
Vor jedem Start (MQTT und reiner Moonraker-Pfad) räumt Grotti einen hängenden gkapi-Task best-effort — **Kobra 3 und S1**: `print_info` → ggf. MQTT-stop → poll. Kommt trotzdem **10101**, einmal cancel + 1,5 s + Retry (wie Rinkhals). Ist gkapi kurz unerreichbar, läuft der Moonraker-Start trotzdem (negativer Cache ~45 s). Live zeigt die Wand `anycubic_task` aus demselben `info/query` (Cache ~10 s). Details: [Anycubic-Stack](Anycubic-Stack) Abschnitt Task-Hygiene.
|
||
|
||
**Start-Report verspätet:** 13.10.2026 ~21:35, A2 (`10.10.1.59`), Ablauf 2/5 direkt nach der Bettnetz-Prüfung. Innerhalb von 30 s kam kein `print/report`, der Druck lief trotzdem an. `info/query` (Topic `…/slicer/printer/{modelId}/{deviceId}/info`, Antwort auf `…/info/report`) zeigte `project.task_id` = Grotti-`taskid`, `state: auto_leveling`. Moonraker meldet in dieser Phase noch `print_stats.state: complete` vom Vorauftrag. Grotti prüft deshalb bei einem Start-Timeout bis zu dreimal `info/query`. Steht dort die eigene `taskid`, gilt der Start als erfolgreich (`anycubic_lan.print_info`).
|
||
|
||
Fallback ohne MQTT: global in Rinkhals Touch → Manage apps → 40-moonraker → Auto leveling (gilt dann für alle Moonraker-Starts inkl. Mainsail/Orca).
|