# Conditional changing of a variable inside a macro

**URL:** <https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161>\
**Category:** General Discussion\
**Created:** [October 2, 2024, 1:09pm UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161 "2024-10-02T13:09:13Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![rschiele](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rschiele/32/14401_2.png) [@rschiele](https://klipper.discourse.group/u/rschiele)\
**Post date:** [October 2, 2024, 1:09pm UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/1 "2024-10-02T13:09:13Z")

</div>

This is a generic question for understanding the behavior of the SET\_GCODE\_VARIABLE command, not related to a specific printer.

My goal was to have a variable that can be either initialized to a specific value or set to -1 to make the macro implementation set the actual value in an automated fashion.

In my simplified example below I wanted to create a variable that I initially set to -1. Whenever the macro detects that it is smaller than 0 it would be set automatically, in the simplified example to 0.

```auto
[gcode_macro foobar]
variable_myvar: -1
gcode:
   M118 BEFORE {myvar}
   {% if myvar < 0 %}
      M118 CATCH
      SET_GCODE_VARIABLE MACRO=foobar VARIABLE=myvar VALUE={0}
   {% endif %}
   M118 AFTER {myvar}

```

My expectation here was that the if condition is met, given that the variable has the value -1, just for the SET\_GCODE\_VARIABLE macro setting it to 0 then.  
The actual behavior though is that the BEFORE debug output produces -1 (as expected, the if condition obviously is met (as seen by the CATCH output, also expected), but then the AFTER debug output still produces -1, though I would have expected SET\_CGODE\_VARIABLE to change that value.  
Obviously, there is something I didn’t fully understand about the construct I am using. If someone could explain to me what I am doing wrong and optimally explain how to fix it, I would be grateful.

---

<div class="post-metadata">

**Author:** ![flowerysong](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/flowerysong/32/10214_2.png) [@flowerysong](https://klipper.discourse.group/u/flowerysong)\
**Post date:** [October 2, 2024, 3:12pm UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/2 "2024-10-02T15:12:01Z")

</div>

Templating happens before execution. When `myvar` is -1, this is the output of templating that macro:

```plaintext
M118 BEFORE -1
   M118 CATCH
   SET_GCODE_VARIABLE MACRO=foobar VARIABLE=myvar VALUE=0
M118 AFTER -1

```

Once this code runs the variable’s value will be updated, but execution can’t reach back in time and affect the templating.

Native Jinja variables are in some ways the opposite: modifying them only applies to the current template evaluation, not to future executions. You can combine the two to have a variable that updates as you go through the template, and is persisted using `SET_GCODE_VARIABLE` when the code runs.

```ini
[gcode_macro foobar]
variable_myvar: -1
gcode:
   {% set _myvar = myvar %}
   M118 BEFORE {_myvar}
   {% if _myvar < 0 %}
      {% set _myvar = 0 %}
      M118 CATCH
      SET_GCODE_VARIABLE MACRO=foobar VARIABLE=myvar VALUE={_myvar}
   {% endif %}
   M118 AFTER {_myvar}

```

---

<div class="post-metadata">

**Author:** ![flowerysong](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/flowerysong/32/10214_2.png) [@flowerysong](https://klipper.discourse.group/u/flowerysong)\
**Post date:** [October 2, 2024, 3:18pm UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/3 "2024-10-02T15:18:26Z")

</div>

Another option is to split the response into a separate macro, since _that_ macro will be templated before it’s executed. Something like this (but using your variable instead of the printer state):

```ini
[gcode_macro foobar]
gcode:
    _foobar_respond
    G1 X0 Y0 Z0 F10
    _foobar_respond

[gcode_macro _foobar_respond]
gcode:
    RESPOND PREFIX='info' MSG='toolhead: {printer.toolhead.position}'

```

---

<div class="post-metadata">

**Author:** ![rschiele](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rschiele/32/14401_2.png) [@rschiele](https://klipper.discourse.group/u/rschiele)\
**Post date:** [October 2, 2024, 5:16pm UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/4 "2024-10-02T17:16:28Z")

</div>

Thank you so much! I was not aware that those variables get expanded early but expected the behavior as you pointed out the native Jinja variables do. With that information, I am sure I can now proceed with my project.

---

<div class="post-metadata">

**Author:** ![3dcoded](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/3dcoded/32/20297_2.png) [@3dcoded](https://klipper.discourse.group/u/3dcoded)\
**Post date:** [October 2, 2024, 10:31pm UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/5 "2024-10-02T22:31:43Z")

</div>

You might want to check out [DynamicMacros](https://github.com/3DCoded/DynamicMacros). [Here](https://3dcoded.github.io/DynamicMacros/features/receivingvariables/) is the documentation page about dynamically updating variables throughout a macro’s execution.

---

<div class="post-metadata">

**Author:** ![rschiele](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rschiele/32/14401_2.png) [@rschiele](https://klipper.discourse.group/u/rschiele)\
**Post date:** [October 3, 2024, 6:23am UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/6 "2024-10-03T06:23:29Z")

</div>

Thanks, I will keep that implementation in mind. It would likely be overblown for my current purpose since the native variables recommended above perfectly fulfill my needs.  
Spontaneously, I see the main advantage of this DynamicMacros implementation during the development phase to update the macros without needing to reboot the machine and consequently home all axes after each change.

---

<div class="post-metadata">

**Author:** ![flowerysong](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/flowerysong/32/10214_2.png) [@flowerysong](https://klipper.discourse.group/u/flowerysong)\
**Post date:** [October 3, 2024, 4:03pm UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/7 "2024-10-03T16:03:45Z")

</div>

> [@3dcoded](#):
>
> You might want to check out [DynamicMacros](https://github.com/3DCoded/DynamicMacros)

I really wish you wouldn’t recommend that to people. It’s better to teach people how to use the existing features correctly than to encourage them to make questionable modifications to their Klipper install which will make it harder for them to get support.

---

<div class="post-metadata">

**Author:** ![rschiele](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rschiele/32/14401_2.png) [@rschiele](https://klipper.discourse.group/u/rschiele)\
**Post date:** [October 3, 2024, 5:10pm UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/8 "2024-10-03T17:10:15Z")

</div>

Just to close the loop: With the explanation of the different types of variables (which was the gap in my knowledge) I could not complete the implementation you can find here: [allow more configuration for bucket selections by schiele · Pull Request #1057 · VoronDesign/VoronUsers · GitHub](https://github.com/VoronDesign/VoronUsers/pull/1057)

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/free1/uploads/klipper/original/1X/64419bf2aac6639e6ef5cef200dcd456b0a01ac3.png) [@system](https://klipper.discourse.group/u/system)\
**Post date:** [November 3, 2024, 3:11am UTC](https://klipper.discourse.group/t/conditional-changing-of-a-variable-inside-a-macro/19161/9 "2024-11-03T03:11:04Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
