"Long press" button Macro

By default Kliper gcode_button supports only press and release actions,
This configuration allow to extend gcode_button to recognize how long it was pressed and from that can derive what kind of action it should do, this way we can get multiple different actions from single button.

Provided sample have following behavior:
if press and release of a button(trip a switch) in less than 2 sec - don’t do anything
if we press-release took more than 2 sec but less than 4 sec - call action 1
if we press-release took more than 4 sec but less than 10 sec - call action 2
if we press-release took more than 10 sec - call action 3

How it works:
When button is pressed - we are pushing current runtime of klipper to macro variable, when button will be released - we pool previously stored “press time” value from a macro variable and fetching current runtime then calculating duration and taking decision what to do.

If you will see that “release” action is called before “press” - just reverse pin configuration by removing “!”

Personally I think that existing gcode_button should extend it’s capabilities and should report not only state but also some timestamp of “last press” and “last release” so we could use it without additional workarounds.

P.S. currently this macro uses undocumented property to get runtime of a klipper, why this kind of property or usual “host time” it’s not available in system_stats or somewhere else I don’t know.

[gcode_button my_button_long_press]
description: sample "long press" button configuration
pin: !host:gpiochip0/gpio30
press_gcode:
  {% set current_timer = printer.toolhead.estimated_print_time %} 
  SET_GCODE_VARIABLE MACRO=my_button VARIABLE=last_press VALUE={current_timer}
  {action_respond_info("Press time: %.2f "% (current_timer))}

release_gcode:
  {% set duration = printer.toolhead.estimated_print_time - printer["gcode_macro my_button"].last_press|float %}
  {action_respond_info("duration: %.2f "% (duration))}
  {% if duration|float > 10.0 %}
      my_button_level3
  {% elif duration|float > 4.0 %}
      my_button_level2
  {% elif duration|float > 2.0 %}
      my_button
  {% else %}
      {action_respond_info("button didn't meet criteria it was too short press")}
  {% endif %}

[gcode_macro my_button]
description: This macro will be called if button pressed more than 2 sec
variable_last_press: 0.0
gcode:
  {action_respond_info("it was loong press of a button level 1")}

[gcode_macro my_button_level2]
description: This macro will be called if button pressed more than 4 sec
gcode:
  {action_respond_info("it was loong press of a button level 2")}

[gcode_macro my_button_level3]
description: This macro will be called if button pressed more than 10 sec
gcode:
  {action_respond_info("it was loong press of a button level 3")}
2 Likes