Automatically use the CFS when needed
As the title states, this is one method on how to use Creailty's CFS without having to use their stupid OrcaSlicer fork or their touchscreen UI.
The endgame of this for prints to be started directly from OrcaSlicer without worrying about “oh is that going to load the filament from the CFS or the manual spool?”.
We are going to abuse OrcaSlicer's Post Processing setting, this can be found on your process window under “Others” –> “Post-processing Scripts”, a simple bash script, and a little bit of editing on the printer's START_PRINT macro.
Like dead simple, it's just a single command.
#!/usr/bin/env bash
set -euo pipefail
# This is a string instead of a bool because Klipper's macro syntex doesn't like bools :(
useBox="False"
# extended grep, no messages.
# if it matches then the exit code will be 0
if grep -sE "^(T[[:digit:]]+)$" "${1}"; then
useBox="True"
fi
# We make a tmp file because envsubst doesn't inplace edit
# and i couldn't get sponge to work
tmpF=$(mktemp)
cp --attributes-only --preserve "${1}" "${tmpF}"
envsubst < "${1}" > "${tmpF}"
mv "${tmpF}" "${1}"
The gist of the script is to count how many tool changes will happen, afterwards replace a token in the GCode.
You can just save that script to a location on your computer and update the processes in OrcaSlicer, providing the full path of the file in the “Post-processing Scripts” window.
Macro Editing
OrcaSlicer Machine GCode
This is my current “Machine Start G-code” value.
SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]
; Replaced by pp script
SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=use_box VALUE=$useBox
SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=init_extruder VALUE=[initial_extruder]
START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single]
From this you can see that I have a bit more than the normal K1SE profile, mainly the calls to SET_GCODE_VARIABLE.
The first call is actually our token, $useBox. envsubst expects the tokens to be written like normal bash variables.
The second call is to ensure the correct filament is loaded before we start printing. [initial_extruder] will get replaced by OrcaSlicer with the index of the extruder (or filament slot).
Printer Macros
Now my START_PRINT macro is custom-ish, I really didn't like how Creailty did it so I tweaked it a bit. I'll try to provide only the bits needed for using this script.
This is my current START_PRINT macro.
[gcode_macro START_PRINT]
variable_prepare: 0
variable_init_extruder: 0
variable_use_box: False
gcode:
{% set bed_temp = printer.custom_macro.default_bed_temp %}
{% set extruder_temp = printer.custom_macro.default_extruder_temp %}
{% set firstExtruder = (printer["gcode_macro START_PRINT"].init_extruder | default(0)) | int %}
{% set use_box = printer["gcode_macro START_PRINT"].use_box %}
{% if use_box %}
BOX_START_PRINT
{% endif %}
G90
WAIT_TEMP_END
CLEAR_PAUSE
{% if 'BED_TEMP' in params|upper and (params.BED_TEMP|float) %}
{% set bed_temp = params.BED_TEMP %}
{% endif %}
{% if 'EXTRUDER_TEMP' in params|upper and (params.EXTRUDER_TEMP|float) %}
{% set extruder_temp = params.EXTRUDER_TEMP %}
{% endif %}
{% if printer['gcode_macro START_PRINT'].prepare|int == 0 %}
{action_respond_info("not prepare.\n")}
PRINT_PREPARE_CLEAR
CX_ROUGH_G28 EXTRUDER_TEMP={extruder_temp} BED_TEMP={bed_temp}
CX_NOZZLE_CLEAR
ACCURATE_G28
CX_PRINT_LEVELING_CALIBRATION
{% else %}
PRINT_PREPARE_CLEAR
{% endif %}
{% if use_box %}
T{firstExtruder}
{% endif %}
CX_NOZZLE_CLEAR
CX_PRINT_DRAW_ONE_LINE
Let me attempt to break this down.
We need to add two new variables to this macro variable_init_extruder and variable_use_box. You'll reference the part after variable_ when calling SET_GCODE_VARIABLE. This allows us to set the variables before entering the macro, this means the logic is cleaner.
Make sure to add the set parts before any code, otherwise you'll have a hard time getting the values of the variables :3
{% set firstExtruder = (printer["gcode_macro START_PRINT"].init_extruder | default(0)) | int %}
{% set use_box = printer["gcode_macro START_PRINT"].use_box %}
From my limited fuckingabout:tm: I have found that if you omit BOX_START_PRINT then the printer will just stright up ignore it, pulling instead from the manual spool.
So let's wrap that in a if:
{% if use_box %}
BOX_START_PRINT
{% endif %}
Further down you see a toolchange call, of course if we aren't using the box then we shouldn't attempt to load anything.
{% if use_box %}
T{firstExtruder}
{% endif %}
That's it really, the rest of the macro is either stock or just re-orginized for my sanity.
Sadly you'll have to figure out where to put these changes, the BOX_START_PRINT is called before anything else so that at the start is fine.
For the toolchange call, you'll have to figure that one out. I added it after all the leveling and nozzle cleaning so there's no chance for any plastic to interfere.