G-code Conditional Injector
Inject G-code macros at the right moment — fan boost, layer announcements, calibration
- plan
- gcode_text
- applied_json
- summary
Plain exported G-code is boring. Real prints want a fan kicked to full at layer 4, a M117 status line when the print starts, a temperature change halfway up. That's post-processing territory, and this node is the pack's post-processor: it takes exported G-code and injects your own commands at the start, at specific layer changes, or at the end, based on rules you write as JSON.
How it works
You feed it three things: the plan (used to look up layer and Z information so rules can match), the gcode_text to modify, and a rules_json list. Each rule says when to fire and what to inject:
[
{"label":"announce-start","when":"start","inject":"M117 START {mode}"},
{"label":"fan-boost","when":"layer_change","layer_min":2,"every_layers":2,"inject":"M106 S255"},
{"label":"announce-end","when":"end","inject":"M118 DONE {mode}"}
]
The default rule set does exactly this: announce the start on the LCD, kick the fan to full every two layers from layer 2 up, and announce the end. It's a perfect template - change the inject lines to your own macros and you're done.
Layer-change rules support filters beyond the example: layer, layer_min, layer_max, every_layers, z_min, z_max, and mode (the plan's mode string, like heightmap_plate). And the inject text is a template - {layer}, {z}, and {mode} get substituted at runtime. That's how you'd write a calibration tower that prints the current layer number to the display, or bump temperature based on Z height.
The one rule that bites
Layer-change rules only fire if the G-code actually contains layer marker comments. The injector scans for ; LAYER: markers as it walks the file; if there are none, it adds a warning to the output and silently skips every layer_change rule. The pack's README is blunt about the fix: keep include_comments enabled on MKRGCodeExport when you plan to inject anything later in the graph. Comments are how the plan and the text stay in sync - strip them and the conditional injector goes blind.
Outputs
gcode_text- the modified G-code with your injected blocks, ready to chain into the next post-processor or save.applied_json- a report of every rule that fired, with label, trigger, layer, and injected lines, plus warnings.summary- one line: how many events fired and whether anything went wrong.
Installing it
Part of the pack:
# ComfyUI Manager: search "MKRShift Nodes", install, restart.
# or:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
# restart ComfyUI
No extra dependencies.
Wiring and gotchas
The natural spot is after export, before saving: MKRGCodeExport → MKRGCodeConditionalInjector, then save the modified gcode_text yourself or let the injector pass it on. A couple of things worth knowing:
- The injector modifies text in memory; it doesn't write files. You wire the output
gcode_textonward to wherever your graph saves. - A rule with no matches isn't an error - it's just an empty
applied_jsonentry. Check that output if you expected a fan boost and the print ran without one. modein your templates is the plan's generator mode, so a shared rule set can behave differently for a vase vs. a heightmap plate without touching the rule list. That's the pack's design intent, and it works.
Also, the pack ships related G-code modifier siblings - MKRGCodeBedMeshCompensate and MKRGCodeCalibrationTower - if you need those specific jobs; this node is the general-purpose one.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| plan | MKR_GCODE_PLAN | — | |
| gcode_text | STRING | — | |
| rules_json | STRING | [{"label":"announce-start","when":"start","inject":"M117 START {mode}"},{"label":"fan-boost","when":"layer_change","layer_min":2,"every_layers":2,"inject":"M106 S255"},{"label":"announce-end","when":"end","inject":"M118 DONE {mode}"}] | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| gcode_text | STRING | — |
| applied_json | STRING | — |
| summary | STRING | — |