From 9ea3595ce19e2ad0217c56974842a7d6af1bcd8b Mon Sep 17 00:00:00 2001 From: solutionphil Date: Fri, 4 Sep 2026 11:27:19 +0200 Subject: [PATCH] Give the KAOS bridge the same E-mode treatment, and keep it current Verifying the alpha update on the dev printer turned up something the AddOn.cfg fix cannot reach: KAOS declares [gcode_macro PHROZEN_TOOLCHANGE] a second time in kaos-ams-bridge.cfg, and a later declaration wins per option. So on a printer with KAOS on, the macro that actually runs is this one -- and it had the defect twice over. The AMS branch was WORSE than the kit's. Its own comment says M83 goes first to close "the kit's standing G1 E-1 before M83 latent defect on this path", and it does -- but it never hands the mode back. A slicer running absolute E would have every extrusion after the first tool change reinterpreted as relative, for the rest of the print. That is a bigger fault than the one it fixes. Confirmed by grep: exactly one M83 in the whole bridge and nothing anywhere that restores the mode -- not ORCA_PURGE, not PRZ_SPITTING_END. The no-AMS branch had the original defect untouched, and its comment says why: "byte-identical to stock". It was, when it was written. The kit has since fixed that line, so the copy was stale and the claim no longer true. Both branches now read the mode once at the top and hand it back, the same shape as the kit macro. Rendered against Klipper's own jinja2 in all four combinations of ams and entry mode: absolute gives M83 then the retract then M82, relative gives M83 and the retract, and the retract is present in every case. AND IT HAD TO SURVIVE KAOS_ON / KAOS_OFF. Our bridge configs are copied into printer_data/config when KAOS is ACTIVATED and never again. $SELF_DIR/config is inside the kit clone, so a kit update refreshes the source and leaves the copies -- a printer that has had KAOS on since before an update keeps running the old ones. The same "the correction never reaches the printer" shape as the rest of this week. So the guard, which already reconciles the spit patch on every klipper start, now refreshes our bridge configs too. Keyed on the include line actually present in printer.cfg, exactly like sync_spit_patch: a file whose include is gone is never put back, so KAOS_OFF stays off. KAOS's own files come from the upstream cache and are not touched. Measured against a copy of the dev printer's config with an isolated KAOS_HOME: with the include present and the installed bridge stale it is refreshed and says so; a second run is silent; with the include removed and the file deleted, nothing is put back. With KAOS off the AddOn.cfg macro runs, and that one is already current through #@REVISE. Co-Authored-By: Claude Opus 5 --- unleashed-x-kaos/config/kaos-ams-bridge.cfg | 13 +++++++++- unleashed-x-kaos/scripts/kaos-guard.sh | 28 ++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/unleashed-x-kaos/config/kaos-ams-bridge.cfg b/unleashed-x-kaos/config/kaos-ams-bridge.cfg index bbb8a17..bf299f7 100644 --- a/unleashed-x-kaos/config/kaos-ams-bridge.cfg +++ b/unleashed-x-kaos/config/kaos-ams-bridge.cfg @@ -118,6 +118,10 @@ gcode: description: magic_ams tool-change entry - arms the ORCA_PURGE handoff and hands over to the spit tail gcode: {% set ams = printer.save_variables.variables.ams|default(0)|int %} + # Read the caller's extrusion mode once, before either branch touches it. Jinja renders the whole + # body before the first command runs, so this is the mode on entry -- which is what both branches + # need to hand back. + {% set was_abs_e = printer.gcode_move.absolute_extrude %} {% if ams == 1 %} # ALWAYS drop a stale handoff first. A leftover active=1 from a tool change that # never reached its spit tail would otherwise fire ORCA_PURGE at the wrong moment. @@ -149,6 +153,10 @@ gcode: # standing "G1 E-1 before M83" latent defect on this path. M83 G1 E-1 F3600 + # ...and hand the mode back. Setting M83 and keeping it would be worse than the defect it + # fixes: a slicer running absolute E would have every extrusion after the first tool change + # reinterpreted as relative, for the rest of the print. + {% if was_abs_e %}M82{% endif %} # --- Stage 3: hand the purge to ORCA_PURGE -------------------- # Refresh the fan/temp mirrors ORCA_PURGE restores at the end. Runs as a @@ -174,8 +182,11 @@ gcode: # is sticky per klippy session, so it MUST be re-sent on every change. P10 S2 {% else %} - # No AMS attached: the kit's manual-swap fallback (byte-identical to stock). + # No AMS attached: the kit's manual-swap fallback. It used to be byte-identical to stock, + # which is why it carried the bare retract; the kit has since fixed that, so this follows. + M83 G1 E-1 F3600 + {% if was_abs_e %}M82{% endif %} M118 No AMS -> manual filament change (M600: unload -> swap -> load -> purge -> resume) M600 {% endif %} diff --git a/unleashed-x-kaos/scripts/kaos-guard.sh b/unleashed-x-kaos/scripts/kaos-guard.sh index f82b034..f58106f 100755 --- a/unleashed-x-kaos/scripts/kaos-guard.sh +++ b/unleashed-x-kaos/scripts/kaos-guard.sh @@ -77,6 +77,28 @@ restore_stock_dev_py() { # printer.cfg, a Phrozen update replacing one file but not the other); the include line is # ground truth for which macro set is loading. This is what makes every half-state # self-heal on the next boot instead of persisting silently. +# Our own bridge configs are copied into printer_data/config when KAOS is ACTIVATED, and never +# again. A kit update refreshes $SELF_DIR/config (it is inside the kit clone) but not the copies, +# so a printer that has had KAOS on since before an update keeps running the old ones -- the same +# "the correction never reaches the printer" shape this project keeps meeting. Keyed on the include +# line actually present in printer.cfg, like sync_spit_patch above: a file whose include is gone is +# not put back, so KAOS_OFF stays off. KAOS's OWN files come from $CACHE and are not touched here. +sync_bridge_configs() { + [ -d "$SELF_DIR/config" ] && [ -f "$PRINTER_CFG" ] || return 0 + local src name + for src in "$SELF_DIR"/config/*.cfg; do + [ -f "$src" ] || continue + name="$(basename "$src")" + grep -qE "^[[:space:]]*\[include[[:space:]]+${name//./\.}\]" "$PRINTER_CFG" 2>/dev/null || continue + cmp -s "$src" "$CONFIG_DIR/$name" && continue + if cp -f "$src" "$CONFIG_DIR/$name"; then + log "refreshed $name from the kit — the installed copy was older than this kit" + else + log "WARNING - could not refresh $name" + fi + done +} + sync_spit_patch() { [ -f "$SPIT_PATCH" ] && [ -f "$PGM" ] && [ -f "$PRINTER_CFG" ] || return 0 local want r @@ -141,7 +163,11 @@ sync_home_hook() { # --------------------------------------------------------------------------- [ -d "$EXTRAS" ] || exit 0 # not an Arco / nothing to guard -# Both run on EVERY path, including the two early exits below. +# All three run on EVERY path, including the two early exits below. +# Refresh our own bridge configs BEFORE the spit patch reconciles: that patch renames a macro in +# printer_gcode_macro.cfg to match what the bridge declares, so the bridge has to be the current +# one first or the two describe different files. +sync_bridge_configs sync_spit_patch sync_home_hook