[gcode_macro SMART_PARK]
description: Parks your printhead near the print area for pre-print hotend heating.
gcode:

    {% set kamp_settings = printer["gcode_macro _KAMP_Settings"] %}                                                                 # Pull all variables from _KAMP_Settings
    {% set z_height = kamp_settings.smart_park_height | float %}                                                                    # Set Z height variable
    {% set purge_margin = kamp_settings.purge_margin | float %}                                                                     # Set purge margin variable
    {% set verbose_enable = kamp_settings.verbose_enable | abs %}                                                                   # Set verbosity
    {% set center_x = printer.toolhead.axis_maximum.x / 2 | float %}                                                                # Create center point of x for fallback
    {% set center_y = printer.toolhead.axis_maximum.y / 2 | float %}                                                                # Create center point of y for fallback
    {% set axis_minimum_x = printer.toolhead.axis_minimum.x | float %}
    {% set axis_minimum_y = printer.toolhead.axis_minimum.y | float %}
    {% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %}                                # Gather all object points
    {% set x_min = all_points | map(attribute=0) | min | default(center_x) %}                                                       # Set x_min from smallest object x point
    {% set y_min = all_points | map(attribute=1) | min | default(center_y) %}                                                       # Set y_min from smallest object y point
    {% set travel_speed = (printer.toolhead.max_velocity) * 60 | float %}                                                           # Set travel speed from config

    {% if purge_margin > 0 and x_min != center_x and y_min != center_y %}                                                           # If objects are detected and purge margin 
        {% set x_min = [ x_min - purge_margin , x_min ] | min %}                                                                    # value is greater than 0, move
        {% set y_min = [ y_min - purge_margin , y_min ] | min %}                                                                    # to purge location + margin
        {% set x_min = [ x_min , axis_minimum_x ] | max %}
        {% set y_min = [ y_min , axis_minimum_y ] | max %}
    {% endif %}

    {% if verbose_enable == True %}                                                                                                 # Verbose park location

    { action_respond_info("Smart Park location: {},{}.".format(
        (x_min),
        (y_min),
    )) }

    {% endif %}

    {% if printer.toolhead.position.z < z_height %}
        G0 Z{z_height}                                                                                                              # Move Z to park height if current Z position is lower than z_height
    {% endif %}
    G0 X{x_min} Y{y_min} F{travel_speed}                                                                                            # Move near object area
    G0 Z{z_height}                                                                                                                  # Move Z to park height