Files
firmware/docker
Oleksandr ShyshatskyiandClaude Opus 5 827730761f Run FlashForge's stock slicer start G-code unmodified
Migration cost was a re-profiled slicer: every Mainsail print needed an
edited machine start G-code carrying START_PRINT BED=/TOOL=/NOZZLE=/
LAYER=, because the touchscreen app used to do the print preparation
itself and the stock block therefore assumes a prepared machine. Files
sliced with the stock profile printed ~3.2 mm low, or aborted outright.

Three things stood in the way, and each has a place to hook that the
stock block already provides:

  M191 S0     not a command in this fork -- the app intercepted it and
              there is no controllable chamber heater. Now an accepted
              no-op that says so once. M141 likewise.
  G1 Z5       arrives before anything has homed. Homing and the bed mesh
              move into the SDCARD_PRINT_FILE wrapper, which runs before
              the file's first line, so the move is legal.
  Z offset    M109 is the last command before the prime line and comes
              after T<n>, so by then every value is known: NOZZLE from
              its own S, BED from heater_bed.target (the file's M140),
              TOOL from its T. It applies the offset once per job.

No M104/M140 overrides: the targets are already in printer state, so
only M109 and the new M191/M141 are touched, all gated on _FF_JOB.mainsail
so touchscreen prints are untouched.

Layer height is the one value the stock block never states, and it turns
out barely to matter: TOOLCHANGE_SET_PRINT_OFFSET uses it only as a
threshold (-0.06 mm at or below 0.10 mm, nothing above), so at 0.12
through 0.25 the assumed 0.2 is exactly right. _FF_AUTOSTART.default_layer
covers thin-layer profiles, and the explicit START_PRINT block, kept as
machine-start-gcode-explicit.txt, still passes the real value along with
TOOLS=/TEMPS=/CLEAN=/LEVEL=. The two compose: START_PRINT sets
offset_done and the M109 hook stands down, so migration can be gradual
and nothing is applied twice.

test-macros.py parses every ff-*.cfg macro body as Jinja, since Klipper
renders these at runtime and a syntax error would otherwise surface on
the printer at the start of a print. jinja2 added to the build image so
it does not silently skip in CI. Suite is 30 passed, 0 failed.

NOT YET RUN ON HARDWARE: the printer is down on the c_helper.so
mismatch, so the Z-offset path here has not been exercised. First print
should be watched, with the first layer checked before it commits.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgNhSa1Qvwvxb2nQXT6b1Y
2026-08-23 18:25:08 +03:00
..