What's new
VORON Design

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members!

Nevermore not firing in an if-block

Laserbea4k43

Well-known member
this block doesn't seem to turn my nevermore on:
Code:
{% if bedtemp > 95 %}     
        nvmOn                                                         
        TEMPERATURE_WAIT SENSOR="temperature_sensor chamber" MINIMUM={chambertemp}       ; wait for chamber temp
    {% endif %}

The macro works if I use it manually though
Code:
[gcode_macro nvmOn]
gcode:
    SET_FAN_SPEED FAN=nevermore SPEED=1

I've even tried using separate if statements, but no luck. Any ideas?
 
What if you replace
{% if bedtemp > 95 %}
with
{% if printer.heater_bed.temperature > 95 %}


Also, if the "if" statement is delayed, or maybe called from within a loop in the main macro, then you may have to move it to a separate helper macro and instead call that from the main macro.

Not sure if it applies to this situation, but in my somewhat unusual G32 macro I had to move some of the commands to a separate macro and then call that from the G32 macro to get it to work. Apparently because a macro is evaluated in full when invoked, and some changes are not updated during macro execution.


Perhaps something like this would work:
Code:
[gcode_macro THE_MAIN_MACRO]
gcode:
 stuff
 stuff
 _START_NEVERMORE_AT_TEMP
 stuff
 stuff

[gcode_macro _START_NEVERMORE_AT_TEMP]
gcode:
 {% if printer.heater_bed.temperature > 95 %}
  nvmOn
  TEMPERATURE_WAIT SENSOR="temperature_sensor chamber" MINIMUM={chambertemp}  ; wait for chamber temp
 {% endif %}


For reference, from https://www.klipper3d.org/Command_Templates.html#the-printer-variable
Important! Macros are first evaluated in entirety and only then are the resulting commands executed. If a macro issues a command that alters the state of the printer, the results of that state change will not be visible during the evaluation of the macro. This can also result in subtle behavior when a macro generates commands that call other macros, as the called macro is evaluated when it is invoked (which is after the entire evaluation of the calling macro).
 
For reference, from https://www.klipper3d.org/Command_Templates.html#the-printer-variable
Important! Macros are first evaluated in entirety and only then are the resulting commands executed. If a macro issues a command that alters the state of the printer, the results of that state change will not be visible during the evaluation of the macro. This can also result in subtle behavior when a macro generates commands that call other macros, as the called macro is evaluated when it is invoked (which is after the entire evaluation of the calling macro).
This statement makes me wonder if there's a debugger out there for klipper, so that I can see the results of my macros!

Thanks, I'll try your suggestion. quick question though, if my variables are declared in print_start (bedtemp in this case), would I have to move the declaration to the new macro?
Also, would my print_start in SuperSlicer need to change?

print_start:
Code:
[gcode_macro PRINT_START]
#   Use PRINT_START for the slicer starting script - please customise for your slicer of choice
gcode:
    # Parameters
    {% set bedtemp = params.BED|int %}
    {% set hotendtemp = params.HOTEND|int %}
    {% set chambertemp = params.CHAMBER|default(0)|int %}
   
    STATUS_HEATING
    M109 S140
    STATUS_HEATING
    M190 S{bedtemp}                                                           ; wait for bed temp
    {% if bedtemp > 95 %}  
    nvmOn                                                  
        TEMPERATURE_WAIT SENSOR="temperature_sensor chamber" MINIMUM={chambertemp}       ; wait for chamber temp
    {% endif %}
   
    #M109 S{hotendtemp}   <- willl need to build a scrubber for this                                                                ; wait for hotend temp
    STATUS_HOMING
    G28
    G1 Z+10 F600
    STATUS_CCLEANING
    clean_nozzle
    G32                                                                                  ; home all axes
    STATUS_MESHING
    #BED_MESH_CALIBRATE
    {% set FL_SIZE = params.SIZE|default("0_0_0_0")|string %}
    COMPUTE_MESH_PARAMETERS SIZE={FL_SIZE}
    ADAPTIVE_BED_MESH
    G1 X175 Y175 Z10 F3000                                                              
    #G28 Z                                                                           ; move nozzle away from bed
    STATUS_CLEANING
    clean_nozzle
    # STATUS_CALIBRATING_Z
    # CALIBRATE_Z
    STATUS_HEATING
    M109 S{hotendtemp}
    STATUS_CLEANING
    clean_nozzle
    STATUS_PRINTING

nevermore macro:
Code:
[gcode_macro nvmOn]
gcode:
    SET_FAN_SPEED FAN=nevermore SPEED=1

I guess my G32 would be useful:
Code:
[gcode_macro G32]
gcode:
    STATUS_HEATING
    M109 S140
    STATUS_CLEANING
    clean_nozzle
    BED_MESH_CLEAR
    G28
    STATUS_LEVELING
    QUAD_GANTRY_LEVEL
    G28
    G90
    ##  Uncomment for 350mm build
    G0 X175 Y175 Z30 F3600
    #--------------------------

SS Custom GCode(looking at this now, I don't see how it references anything, still not sure how/why this works):
Code:
;; If you are passing variables to PRINT_START, comment out above line and uncomment the last 3 lines instead.
;; Guide: https://github.com/AndrewEllis93/Print-Tuning-Guide/blob/main/articles/passing_slicer_variables.md
;; Make sure the variable names match (for example if you use "EXTRUDER" instead of "HOTEND")


M104 S0 ; Stops PS/SS from sending temp waits separately
M140 S0
PRINT_START BED=[first_layer_bed_temperature] HOTEND={first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} CHAMBER=[chamber_temperature]
 
I misunderstood, I thought "bedtemp" was supposed to be the measured temp of the bed and that you wanted to check the measured value after a delay, or now and then from a loop or similar.

But now that I can see the whole macro it looks like "bedtemp" is the requested bed temp "first_layer_bed_temperature", sent by the slicer.
"bedtemp" won't change during macro execution and my suggestion won't do any good.
It won't even do what you wanted since it's looking at the measured bed temp instead of the requested temp.

If you were to try my suggestion anyway and check the actual bed temp, then you wouldn't have to change print_start in SuperSlicer, or move the "bedtemp" declaration since "bedtemp" isn't used by the helper macro. But I don't really see why my suggestion should do any better than your current macro, where "bedtemp" is the requested bed temp and not a measured value.

I'm not very good at this, let's hope someone with actual coding skills will chime in.
 
I looked up debugging tools and ended up on the klipper docs page, but didn't find anything that seemed to show me what I was looking for. I could be wrong. I'll report back when i find something.
 
I would be surprised if there's a debugger for Klipper. When I am trying to debug an issue in Klipper (or other interpreted-on-the-fly languages), I resort to a whole pile of console message statements telling me where in the code it is and show the values of pertinent variables. It's a pain, but sometimes the only way. So in Klipper I spam M117, action_respond_info, or RESPOND commands until I get things working.
 
Top