[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
    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
    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} Y{th.axis_maximum.y - 2} F3600  ; park nozzle at rear
    M107                                     ; turn off fan
    
    RESTORE_GCODE_STATE NAME=STATE_PRINT_END

[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: 298
variable_start_y: 349
variable_start_z: 1
variable_wipe_dist: -39
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