[gcode_macro PRINT_START]
gcode:
    {% set BED_TEMP = params.BED|default(60)|float %}
    {% set EXTRUDER_TEMP = params.EXTRUDER|default(190)|float %}
    {% set STANDBY_TEMP = params.STANDBY|default(190)|float %}
    {% set CHAMBER_TEMP = params.CHAMBER|default(55)|float %}
    G90 ; ensure absolute positioning
    STATUS_HOMING
    G92 E0 ; Reset Extruder
    SMARTHOME ; Home all axes
    STATUS_HEATING
    ;TEMPERATURE_WAIT SENSOR=heater_bed MINIMUM={STANDBY_TEMP} ; Start heating up the nozzle most of the way
    M190 S{BED_TEMP} ; Start heating the bed, wait until target temperature reached
    M4 P120000 ; Wait 2 minutes
    ;TEMPERATURE_WAIT SENSOR="temperature_sensor chamber_temp" MINIMUM={CHAMBER_TEMP} ; Wait for chamber temp
    M140 S0 ; turn off power to the bed, interference with probe?
    G28 Z ; Heatsoaked, validate that z
    QUAD_GANTRY_LEVEL
    STATUS_MESHING
    BED_MESH_CALIBRATE
    M190 S{BED_TEMP} ; Start heating the bed, wait until target temperature reached
    M109 S{EXTRUDER_TEMP} ; Finish heating the nozzle
    CLEAN_NOZZLE
    G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed
    G1 X0.1 Y20 Z0.3 F5000.0 ; Move to start position
    G1 X0.1 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line
    G1 X0.4 Y200.0 Z0.3 F5000.0 ; Move to side a little
    G1 X0.4 Y20 Z0.3 F1500.0 E30 ; Draw the second line
    G92 E0 ; Reset Extruder
    G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed
    G1 X5 Y20 Z0.3 F5000.0 ; Move over to prevent blob squish
    CLEAN_NOZZLE ; doing this again is probably gonna make it work!
    SKEW_PROFILE LOAD=calilantern_skew_profile
    STATUS_PRINTING

#   Use PRINT_END for the slicer ending script - please customise for your slicer of choice
[gcode_macro PRINT_END]
gcode:
    # safe anti-stringing move coords
    {% set th = printer.toolhead %}
    {% set x_safe = th.position.x + 20 * (1 if th.axis_maximum.x - th.position.x > 20 else -1) %}
    {% set y_safe = th.position.y + 20 * (1 if th.axis_maximum.y - th.position.y > 20 else -1) %}
    {% set z_safe = [th.position.z + 2, th.axis_maximum.z]|min %}
    SET_SKEW CLEAR=1

    SAVE_GCODE_STATE NAME=STATE_PRINT_END
    
    M400                           ; wait for buffer to clear
    G92 E0                         ; zero the extruder
    G1 E-5.0 F1800                 ; retract filament
    
    TURN_OFF_HEATERS
    
    G90                                      ; absolute positioning
    G0 X{x_safe} Y{y_safe} Z{z_safe} F20000  ; move nozzle to remove stringing
    G0 X{th.axis_maximum.x//2} Y25 F3600  ; park nozzle at rear but avoid the drag chain
    M107                                     ; turn off fan
    
    RESTORE_GCODE_STATE NAME=STATE_PRINT_END
    BACKUP_CFG ;backup the config in case anything changed since last print.

[gcode_macro G32]
gcode:
    SAVE_GCODE_STATE NAME=STATE_G32
    G90
    G28
    QUAD_GANTRY_LEVEL
    G28
    G0 X175 Y175 Z30 F3600
    #--------------------------------------------------------------------
    RESTORE_GCODE_STATE NAME=STATE_G32

[gcode_macro POWER_ON_SETUP]
gcode:
    STATUS_HOMING
    SMARTHOME
    CLEAN_NOZZLE
    G1 X298 Y330
    G28 Z ; Hopefully the nozzle is empty now
    STATUS_LEVELING

[gcode_macro ABS_PREHEAT]
gcode:
    M190 S115

[gcode_macro SMARTHOME]
gcode:
    {% if printer.toolhead.homed_axes == "xyz" %}
        M118 Printer is already homed
    {% else %}
        M118 Printer needs homing...
        G28
    {% endif %}

[gcode_macro M355]
gcode:
  {% set S = params.S|default(1)|float %}
  #default_parameter_S=1
  SET_PIN PIN=caselight VALUE={S}

[gcode_macro CLEAN_NOZZLE]
variable_start_x: 101
variable_start_y: 355
variable_start_z: 0
variable_wipe_dist: -40
variable_wipe_qty: 5
variable_wipe_spd: 200
variable_raise_distance: 30

gcode:
 {% if "xyz" not in printer.toolhead.homed_axes %}
   G28
 {% endif %}
 
 G90                                            ; absolute positioning
 ## Move nozzle to start position
 G1 X{start_x} Y{start_y} F6000
 G1 Z{start_z} F1500

 ## Wipe nozzle
 {% for wipes in range(1, (wipe_qty + 1)) %}
   G1 X{start_x + wipe_dist} F{wipe_spd * 60}
   G1 X{start_x} F{wipe_spd * 60}
 {% endfor %}

 ## Raise nozzle
 G1 Z{raise_distance}

[gcode_macro M600]
########### Gcode ############
gcode:
  {% set X = params.X|default(175)|int %}
  {% set Y = params.Y|default(0)|int %}
  {% set Z = params.Z|default(10)|int %}
  {% set E = params.E|default(-20)|int %}
  {% set tool = params.tool|default(0)|int %}
  PAUSE
  G91
  G1 E-5 F4000
  G1 Z{Z}
  G90
  G1 X{X} Y{Y} F3000 ;park position
  G0 E10 F500 ;extrude filament to get better blob on end
  G0 E{E} F600 ;retract additional filament to move out of melt zone
  G92 E0

[delayed_gcode bed_mesh_init]
initial_duration: .01
gcode:
  BED_MESH_PROFILE LOAD=default

[gcode_macro TEST_SPEED]
# from ellis
# Home, get position, throw around toolhead, home again.
# If MCU stepper positions (first line in GET_POSITION) are greater than a full step different (your number of microsteps), then skipping occured.
# We only measure to a full step to accomodate for endstop variance.
# Example: TEST_SPEED SPEED=300 ACCEL=5000 ITERATIONS=10

description: Test for max speed and acceleration parameters for the printer. Procedure: Home -> ReadPositionFromMCU -> MovesToolhead@Vel&Accel -> Home -> ReadPositionfromMCU

gcode:
    # Speed
    {% set speed  = params.SPEED|default(printer.configfile.settings.printer.max_velocity)|int %}
    # Iterations
    {% set iterations = params.ITERATIONS|default(5)|int %}
    # Acceleration
    {% set accel  = params.ACCEL|default(printer.configfile.settings.printer.max_accel)|int %}
    # Minimum Cruise Ratio
    {% set min_cruise_ratio = params.MIN_CRUISE_RATIO|default(0.5)|float %}
    # Bounding inset for large pattern (helps prevent slamming the toolhead into the sides after small skips, and helps to account for machines with imperfectly set dimensions)
    {% set bound = params.BOUND|default(20)|int %}
    # Size for small pattern box
    {% set smallpatternsize = SMALLPATTERNSIZE|default(20)|int %}
    
    # Large pattern
        # Max positions, inset by BOUND
        {% set x_min = printer.toolhead.axis_minimum.x + bound %}
        {% set x_max = printer.toolhead.axis_maximum.x - bound %}
        {% set y_min = printer.toolhead.axis_minimum.y + bound %}
        {% set y_max = printer.toolhead.axis_maximum.y - bound %}
    
    # Small pattern at center
        # Find X/Y center point
        {% set x_center = (printer.toolhead.axis_minimum.x|float + printer.toolhead.axis_maximum.x|float ) / 2 %}
        {% set y_center = (printer.toolhead.axis_minimum.y|float + printer.toolhead.axis_maximum.y|float ) / 2 %}
        
        # Set small pattern box around center point
        {% set x_center_min = x_center - (smallpatternsize/2) %}
        {% set x_center_max = x_center + (smallpatternsize/2) %}
        {% set y_center_min = y_center - (smallpatternsize/2) %}
        {% set y_center_max = y_center + (smallpatternsize/2) %}

    # Save current gcode state (absolute/relative, etc)
    SAVE_GCODE_STATE NAME=TEST_SPEED
    
    # Output parameters to g-code terminal
    { action_respond_info("TEST_SPEED: starting %d iterations at speed %d, accel %d" % (iterations, speed, accel)) }
    
    # Home and get position for comparison later:
        M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
        G28
        # QGL if not already QGLd (only if QGL section exists in config)
        {% if printer.configfile.settings.quad_gantry_level %}
            {% if printer.quad_gantry_level.applied == False %}
                QUAD_GANTRY_LEVEL
                G28 Z
            {% endif %}
        {% endif %} 
        # Move 50mm away from max position and home again (to help with hall effect endstop accuracy - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/24)
        G90
        G1 X{printer.toolhead.axis_maximum.x-50} Y{printer.toolhead.axis_maximum.y-50} F{30*60}
        M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
        G28 X Y
        G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{30*60}
        G4 P1000 
        GET_POSITION

    # Go to starting position
    G0 X{x_min} Y{y_min} Z{bound + 10} F{speed*60}

    # Set new limits
    {% if printer.configfile.settings.printer.minimum_cruise_ratio is defined %}
        SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} MINIMUM_CRUISE_RATIO={min_cruise_ratio}
    {% else %}
        SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} ACCEL_TO_DECEL={accel / 2}
    {% endif %}

    {% for i in range(iterations) %}
        # Large pattern diagonals
        G0 X{x_min} Y{y_min} F{speed*60}
        G0 X{x_max} Y{y_max} F{speed*60}
        G0 X{x_min} Y{y_min} F{speed*60}
        G0 X{x_max} Y{y_min} F{speed*60}
        G0 X{x_min} Y{y_max} F{speed*60}
        G0 X{x_max} Y{y_min} F{speed*60}
        
        # Large pattern box
        G0 X{x_min} Y{y_min} F{speed*60}
        G0 X{x_min} Y{y_max} F{speed*60}
        G0 X{x_max} Y{y_max} F{speed*60}
        G0 X{x_max} Y{y_min} F{speed*60}
    
        # Small pattern diagonals
        G0 X{x_center_min} Y{y_center_min} F{speed*60}
        G0 X{x_center_max} Y{y_center_max} F{speed*60}
        G0 X{x_center_min} Y{y_center_min} F{speed*60}
        G0 X{x_center_max} Y{y_center_min} F{speed*60}
        G0 X{x_center_min} Y{y_center_max} F{speed*60}
        G0 X{x_center_max} Y{y_center_min} F{speed*60}
        
        # Small pattern box
        G0 X{x_center_min} Y{y_center_min} F{speed*60}
        G0 X{x_center_min} Y{y_center_max} F{speed*60}
        G0 X{x_center_max} Y{y_center_max} F{speed*60}
        G0 X{x_center_max} Y{y_center_min} F{speed*60}
    {% endfor %}

    # Restore max speed/accel/accel_to_decel to their configured values
    {% if printer.configfile.settings.printer.minimum_cruise_ratio is defined %}
        SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} MINIMUM_CRUISE_RATIO={printer.configfile.settings.printer.minimum_cruise_ratio} 
    {% else %}
        SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} ACCEL_TO_DECEL={printer.configfile.settings.printer.max_accel_to_decel}
    {% endif %}

    # Re-home and get position again for comparison:
        M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
        G28 # This is a full G28 to fix an issue with CoreXZ - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/12
        # Go to XY home positions (in case your homing override leaves it elsewhere)
        G90
        G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{30*60}
        G4 P1000 
        GET_POSITION

    # Restore previous gcode state (absolute/relative, etc)
    RESTORE_GCODE_STATE NAME=TEST_SPEED
    

[gcode_shell_command backup_cfg]
command: ~/printer_data/config/autocommit.sh
timeout: 30
verbose: True

[gcode_macro BACKUP_CFG]
description: Backs up config directory GitHub
gcode:
    RUN_SHELL_COMMAND CMD=backup_cfg

; For KlipperScreen
[gcode_macro LOAD_FILAMENT]
variable_load_distance:  50
variable_purge_distance:  25
gcode:
    {% set speed = params.SPEED|default(300) %}
    {% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity  * 60 %}
    SAVE_GCODE_STATE NAME=load_state
    G91
    G92 E0
    G1 E{load_distance} F{max_velocity} # fast-load
    G1 E{purge_distance} F{speed} # purge
    RESTORE_GCODE_STATE NAME=load_state

[gcode_macro UNLOAD_FILAMENT]
variable_unload_distance:  50
variable_purge_distance:  25
gcode:
    {% set speed = params.SPEED|default(300) %}
    {% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity  * 60 %}
    SAVE_GCODE_STATE NAME=unload_state
    G91
    G92 E0
    G1 E{purge_distance} F{speed} # purge
    G1 E-{unload_distance} F{max_velocity} # fast-unload
    RESTORE_GCODE_STATE NAME=unload_state

[gcode_macro _SAFE_X_HOME]
; This macro is to ensure that we're not at y=home when X is homed.
gcode:
  G90
  SET_KINEMATIC_POSITION Y=20
  G0 Y0 F50000
  G28 X

[gcode_macro _SAFE_Z_HOME_LIFT]
; Lift the Z no matter what (replicate z-hop from [safe_z_home]
gcode:
  G90
  SET_KINEMATIC_POSITION Z=0
  G0 Z10 F1000

[gcode_macro _SAFE_Z_HOME]
; this macro recreates the save_z_home setup center the toolhead before z home.
gcode:
  G0 X175 Y175 F50000
  G28 Z

[homing_override]
; The ebb36 mount often catches on the drag chain at the back of the printer.
; This ensures that if X is asked to be homed, first Y is homed and then y is
; moved away from the back of the printer and then homed.
axes: xyz
gcode:
  #z hop no matter what
  _SAFE_Z_HOME_LIFT
  {% if not 'Z' in params and not 'Y' in params and 'X' in params %} # Home X
  _SAFE_X_HOME
  {% elif not 'Z' in params and not 'X' in params and 'Y' in params %} #Home Y
  G28 Y
  {% elif not 'Z' in params %} #Home X+Y
  _SAFE_X_HOME
  G28 Y
  {% else %} #Home X+Y+Z
  _SAFE_X_HOME
  G28 Y
  _SAFE_Z_HOME
  {% endif %}