KlipperScreen / KlipperScreen

GUI for Klipper
https://klipperscreen.github.io/KlipperScreen/
GNU Affero General Public License v3.0
1k stars 318 forks source link

[BUG] Bed Level UI Fails to Render Properly #1328

Closed cneshi closed 1 month ago

cneshi commented 1 month ago

What happened?

When I enter the More->Bed Level Menu, the arrows are not rendered properly, and pressing the arrow buttons (that are present) do not match the bed_screw_adjust points in the Klipper config. Using screw_rotation did not seem to fix the issue.

I believe this issue is occuring because I have the Y axis inverted (the print bed is upside down).

What did you expect to happen instead?

I believe there should be some code in bed_level.py that checks y axis inversion in the klipperscreen.conf and swap out y-max and y-min when attempting to match the fr, fl, fm, bl, br, bm points. We did this manually in the code and it fixed the issue for us.

How to reproduce this bug?

The physical bed has dimensions of 180x180

In klipper config put in the following configs:

[bed_screws]
screw1: 5,170
screw1_name: fl
screw2: 180,170
screw2_name: fr
screw3: 90,20
screw3_name: bm

In klipperscreen.conf put in the following configs: screw_positions: fl, fr, bm

Restart Klipperscreen and enter the More->Bed Level menu

Additional information:

The relavant code is in bed_level.py line 137 to 146

Log output

======================= 2024-04-10 23:08:05,696 [config.py:init()] - Configured printers: [ { "Positron_V3": { "moonraker_host": "127.0.0.1", "moonraker_port": "7125", "moonraker_api_key": "" } } ] 2024-04-10 23:08:05,769 [config.py:create_translations()] - Selected lang: None OS lang: en_GB 2024-04-10 23:08:05,769 [config.py:install_language()] - Using lang en 2024-04-10 23:08:05,780 [screen.py:init()] - Monitors: 1 using number: 0 2024-04-10 23:08:05,781 [screen.py:init()] - Wayland: False Display name: :0 2024-04-10 23:08:05,783 [screen.py:init()] - Screen resolution: 640x480 2024-04-10 23:08:05,784 [KlippyGtk.py:init()] - Font size: 14.9 (medium) 2024-04-10 23:08:06,077 [screen.py:set_screenblanking_timeout()] - Changing screen blanking to: 3600 2024-04-10 23:08:06,086 [screen.py:set_screenblanking_timeout()] - Using DPMS 2024-04-10 23:08:06,094 [screen.py:initial_connection()] - Default printer: None 2024-04-10 23:08:06,118 [screen.py:connect_printer()] - Connecting to printer: Positron_V3 2024-04-10 23:08:06,118 [screen.py:_load_panel()] - Loading panel: splash_screen 2024-04-10 23:08:06,152 [screen.py:attach_panel()] - Current panel hierarchy: splash_screen 2024-04-10 23:08:06,160 [KlippyWebsocket.py:connect()] - Attempting to connect 2024-04-10 23:08:06,160 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/server/info 2024-04-10 23:08:06,174 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/access/oneshot_token 2024-04-10 23:08:06,185 [KlippyWebsocket.py:connect()] - Starting websocket thread 2024-04-10 23:08:06,192 [_logging.py:info()] - Websocket connected 2024-04-10 23:08:06,193 [KlippyWebsocket.py:on_open()] - Moonraker Websocket Open 2024-04-10 23:08:06,197 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/server/info 2024-04-10 23:08:06,209 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/server/webcams/list 2024-04-10 23:08:06,219 [printer.py:configure_cameras()] - Cameras: [] 2024-04-10 23:08:06,219 [screen.py:init_klipper()] - Moonraker info {'klippy_connected': True, 'klippy_state': 'ready', 'components': ['secrets', 'template', 'klippy_connection', 'jsonrpc', 'internal_transport', 'application', 'websockets', 'dbus_manager', 'database', 'file_manager', 'authorization', 'klippy_apis', 'shell_command', 'machine', 'data_store', 'proc_stats', 'job_state', 'job_queue', 'http_client', 'announcements', 'webcam', 'extensions', 'octoprint_compat', 'history', 'update_manager'], 'failed_components': [], 'registered_directories': ['config', 'logs', 'gcodes', 'config_examples', 'docs'], 'warnings': [], 'websocket_count': 4, 'moonraker_version': 'v0.8.0-325-g99b97af', 'missing_klippy_requirements': [], 'api_version': [1, 4, 0], 'api_version_string': '1.4.0'} 2024-04-10 23:08:06,220 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/printer/info 2024-04-10 23:08:06,233 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/printer/objects/query?configfile 2024-04-10 23:08:06,463 [screen.py:init_klipper()] - {'configfile': {'config': {'virtual_sdcard': {'path': '/home/pi/printer_data/gcodes', 'on_error_gcode': 'CANCEL_PRINT'}, 'pause_resume': {}, 'display_status': {}, 'respond': {}, 'gcode_macro CANCEL_PRINT': {'description': 'Cancel the actual running print', 'rename_existing': 'BASE_CANCEL_PRINT', 'gcode': '\n{% set th = printer.toolhead %}\n{% set z_safe = [th.position.z + 2, th.axis_maximum.z]|min %}\n{% set z_final = [th.position.z + 50, th.axis_maximum.z]|min %}\n{% set y_final = th.axis_maximum.y - 1 %}\n\nCLEAR_PAUSE\nSDCARD_RESET_FILE\n\nSAVE_GCODE_STATE NAME=STATE_CANCEL_PRINT\nM400\nG92 E0\nG1 E-3.0 F3600\nTURN_OFF_HEATERS\n\nG90\nG0 Z{z_safe} F3600\nG1 X5 Y{y_final} F3600\nG1 Z{z_final} F600\nM107\nRESTORE_GCODE_STATE NAME=STATE_CANCEL_PRINT MOVE=0\n\nLED_ERROR\nBASE_CANCEL_PRINT'}, 'gcode_macro PAUSE': {'description': 'Pause the actual running print', 'rename_existing': 'BASE_PAUSE', 'gcode': '\n\n{% set E = printer["gcode_macro PAUSE"].extrude|float %}\n\n\n{% set x_park = printer.toolhead.axis_maximum.x|float - 10.0 %}\n{% set y_park = printer.toolhead.axis_maximum.y|float - 10.0 %}\n\n{% set max_z = printer.toolhead.axis_maximum.z|float %}\n{% set act_z = printer.toolhead.position.z|float %}\n{% if act_z < (max_z - 2.0) %}\n{% set z_safe = 2.0 %}\n{% else %}\n{% set z_safe = max_z - act_z %}\n{% endif %}\n\nSAVE_GCODE_STATE NAME=PAUSE_state\nBASE_PAUSE\nG91\nG1 E-{E} F240\nG1 Z{z_safe} F900\nG90\nG1 X{x_park} Y{y_park} F5000', 'variable_extrude': '1.0'}, 'gcode_macro RESUME': {'description': 'Resume the actual running print', 'rename_existing': 'BASE_RESUME', 'variable_last_extruder_temp': "{'restore': False, 'temp': 0}", 'variable_restore_idle_timeout': '0', 'variable_idle_state': 'False', 'gcode': '\n\n{% set E = printer["gcode_macro PAUSE"].extrude|float %}\n\nG91\nG1 E{E} F240\nRESTORE_GCODE_STATE NAME=PAUSE_state\nBASE_RESUME'}, 'gcode_macro SET_PAUSE_NEXT_LAYER': {'description': 'Enable a pause if the next layer is reached', 'gcode': '\n{% set pause_next_layer = printer[\'gcode_macro SET_PRINT_STATS_INFO\'].pause_next_layer %}\n{% set ENABLE = params.ENABLE | default(1) | int != 0 %}\n{% set MACRO = params.MACRO | default(pause_next_layer.call, True) %}\nSET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_next_layer VALUE="{{ \'enable\': ENABLE, \'call\': MACRO }}"'}, 'gcode_macro SET_PAUSE_AT_LAYER': {'description': 'Enable/disable a pause if a given layer number is reached', 'gcode': '\n{% set pause_at_layer = printer[\'gcode_macro SET_PRINT_STATS_INFO\'].pause_at_layer %}\n{% set ENABLE = params.ENABLE | int != 0 if params.ENABLE is defined\nelse params.LAYER is defined %}\n{% set LAYER = params.LAYER | default(pause_at_layer.layer) | int %}\n{% set MACRO = params.MACRO | default(pause_at_layer.call, True) %}\nSET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_at_layer VALUE="{{ \'enable\': ENABLE, \'layer\': LAYER, \'call\': MACRO }}"'}, 'gcode_macro SET_PRINT_STATS_INFO': {'rename_existing': 'SET_PRINT_STATS_INFO_BASE', 'description': 'Overwrite, to get pause_next_layer and pause_at_layer feature', 'variable_pause_next_layer': '{ \'enable\': False, \'call\': "PAUSE" }', 'variable_pause_at_layer': '{ \'enable\': False, \'layer\': 0, \'call\': "PAUSE" }', 'gcode': '\n{% if pause_next_layer.enable %}\nRESPOND TYPE=echo MSG=\'{"%s, forced by pause_next_layer" % pause_next_layer.call}\'\n{pause_next_layer.call}\nSET_PAUSE_NEXT_LAYER ENABLE=0\n{% elif pause_at_layer.enable and params.CURRENT_LAYER is defined and params.CURRENT_LAYER | int == pause_at_layer.layer %}\nRESPOND TYPE=echo MSG=\'{"%s, forced by pause_at_layer [%d]" % (pause_at_layer.call, pause_at_layer.layer)}\'\n{pause_at_layer.call}\nSET_PAUSE_AT_LAYER ENABLE=0\n{% endif %}\nSET_PRINT_STATS_INFO_BASE {rawparams}'}, 'gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL': {'description': 'Helper: park toolhead used in PAUSE and CANCEL_PRINT', 'gcode': '\n\n{% set client = printer[\'gcode_macro _CLIENT_VARIABLE\'] | default({}) %}\n{% set velocity = printer.configfile.settings.pause_resume.recover_velocity %}\n{% set use_custom = client.use_custom_pos | default(false) | lower == \'true\' %}\n{% set custom_park_x = client.custom_park_x | default(0.0) %}\n{% set custom_park_y = client.custom_park_y | default(0.0) %}\n{% set park_dz = client.custom_park_dz | default(2.0) | abs %}\n{% set sp_hop = client.speed_hop | default(15) 60 %}\n{% set sp_move = client.speed_move | default(velocity) 60 %}\n\n{% set origin = printer.gcode_move.homing_origin %}\n{% set act = printer.gcode_move.gcode_position %}\n{% set max = printer.toolhead.axis_maximum %}\n{% set cone = printer.toolhead.cone_start_z | default(max.z) %}\n{% set round_bed = True if printer.configfile.settings.printer.kinematics is in [\'delta\',\'polar\',\'rotary_delta\',\'winch\']\nelse False %}\n\n{% set z_min = params.Z_MIN | default(0) | float %}\n{% set z_park = [[(act.z + park_dz), z_min] | max, (max.z - origin.z)] | min %}\n{% set x_park = params.X if params.X is defined\nelse custom_park_x if use_custom\nelse 0.0 if round_bed\nelse (max.x - 5.0) %}\n{% set y_park = params.Y if params.Y is defined\nelse custom_park_y if use_custom\nelse (max.y - 5.0) if round_bed and z_park < cone\nelse 0.0 if round_bed\nelse (max.y - 5.0) %}\n\n_CLIENT_RETRACT\n{% if "xyz" in printer.toolhead.homed_axes %}\nG90\nG1 Z{z_park} F{sp_hop}\nG1 X{x_park} Y{y_park} F{sp_move}\n{% if not printer.gcode_move.absolute_coordinates %} G91 {% endif %}\n{% else %}\nRESPOND TYPE=echo MSG=\'Printer not homed\'\n{% endif %}'}, 'gcode_macro _CLIENT_EXTRUDE': {'description': 'Extrudes, if the extruder is hot enough', 'gcode': '\n\n{% set client = printer[\'gcode_macro _CLIENT_VARIABLE\'] | default({}) %}\n{% set use_fw_retract = (client.use_fw_retract | default(false) | lower == \'true\') and (printer.firmware_retraction is defined) %}\n{% set length = params.LENGTH | default(client.unretract) | default(1.0) | float %}\n{% set speed = params.SPEED | default(client.speed_unretract) | default(35) %}\n{% set absolute_extrude = printer.gcode_move.absolute_extrude %}\n\n{% if printer.toolhead.extruder != \'\' %}\n{% if printer[printer.toolhead.extruder].can_extrude %}\n{% if use_fw_retract %}\n{% if length < 0 %}\nG10\n{% else %}\nG11\n{% endif %}\n{% else %}\nM83\nG1 E{length} F{(speed | float | abs) * 60}\n{% if absolute_extrude %}\nM82\n{% endif %}\n{% endif %}\n{% else %}\nRESPOND TYPE=echo MSG=\'{"\"%s\" not hot enough" % printer.toolhead.extruder}\'\n{% endif %}\n{% endif %}'}, 'gcode_macro _CLIENT_RETRACT': {'description': 'Retracts, if the extruder is hot enough', 'gcode': "\n{% set client = printer['gcode_macro _CLIENT_VARIABLE'] | default({}) %}\n{% set length = params.LENGTH | default(client.retract) | default(1.0) | float %}\n{% set speed = params.SPEED | default(client.speed_retract) | default(35) %}\n\n_CLIENT_EXTRUDE LENGTH=-{length | float | abs} SPEED={speed | float | abs}"}, 'mcu': {'serial': '/dev/serial/by-path/platform-fe9c0000.xhci-usb-0:1.3:1.0', 'restart_method': 'command'}, 'mcu pth': {'serial': '/dev/serial/by-path/platform-fe9c0000.xhci-usb-0:1.2:1.0', 'restart_method': 'command'}, 'printer': {'kinematics': 'corexy', 'max_velocity': '420', 'max_accel': '8000', 'max_accel_to_decel': '6000', 'square_corner_velocity': '7', 'max_z_velocity': '20', 'max_z_accel': '150'}, 'stepper_x': {'step_pin': 'gpio14', 'dir_pin': '!gpio13', 'enable_pin': '!gpio15', 'microsteps': '16', 'rotation_distance': '40', 'endstop_pin': 'tmc2209_stepper_x:virtual_endstop', 'homing_retract_dist': '0', 'position_endstop': '0', 'position_max': '185', 'homing_speed': '40'}, 'tmc2209 stepper_x': {'uart_pin': 'gpio9', 'tx_pin': 'gpio8', 'uart_address': '3', 'run_current': '0.7', 'stealthchop_threshold': '999999', 'diag_pin': '^gpio16', 'driver_sgthrs': '52'}, 'stepper_y': {'step_pin': 'gpio19', 'dir_pin': '!gpio28', 'enable_pin': '!gpio2', 'microsteps': '16', 'rotation_distance': '40', 'endstop_pin': 'tmc2209_stepper_y:virtual_endstop', 'homing_retract_dist': '0', 'position_endstop': '180', 'position_max': '180', 'homing_speed': '40', 'homing_positive_dir': 'True'}, 'tmc2209 stepper_y': {'uart_pin': 'gpio9', 'tx_pin': 'gpio8', 'uart_address': '1', 'run_current': '0.7', 'stealthchop_threshold': '999999', 'diag_pin': '^gpio25', 'driver_sgthrs': '55'}, 'stepper_z': {'step_pin': 'gpio6', 'dir_pin': '!gpio5', 'enable_pin': '!gpio7', 'microsteps': '16', 'rotation_distance': '40', 'gear_ratio': '75:10', 'endstop_pin': 'probe:z_virtual_endstop', 'position_min': '-4.0', 'position_max': '165', 'homing_speed': '13'}, 'tmc2209 stepper_z': {'uart_pin': 'gpio9', 'tx_pin': 'gpio8', 'uart_address': '2', 'run_current': '0.25', 'stealthchop_threshold': '999999'}, 'extruder': {'step_pin': 'gpio11', 'dir_pin': '!gpio10', 'enable_pin': '!gpio12', 'microsteps': '16', 'rotation_distance': '4.561', 'nozzle_diameter': '0.4', 'filament_diameter': '1.75', 'heater_pin': 'pth:gpio9', 'sensor_type': 'ATC Semitec 104NT-4-R025H42G', 'sensor_pin': 'pth:gpio29', 'pullup_resistor': '2200', 'control': 'pid', 'pid_kp': '25.12', 'pid_ki': '1.073', 'pid_kd': '147', 'min_temp': '-100', 'max_temp': '300', 'max_extrude_cross_section': '2', 'pressure_advance': '0.18', 'min_extrude_temp': '150', 'max_extrude_only_distance': '400'}, 'tmc2209 extruder': {'uart_pin': 'gpio9', 'tx_pin': 'gpio8', 'uart_address': '0', 'run_current': '0.72', 'hold_current': '0.4'}, 'thermistor SDNT2012X104_3950': {'temperature1': '25', 'resistance1': '100000', 'beta': '3950'}, 'heater_bed': {'heater_pin': 'gpio21', 'sensor_type': 'SDNT2012X104_3950', 'sensor_pin': 'gpio26', 'pwm_cycle_time': '0.3', 'max_power': '1.0', 'control': 'pid', 'pid_kp': '56.852', 'pid_ki': '2.1', 'pid_kd': '383.75', 'min_temp': '0', 'max_temp': '120'}, 'probe': {'pin': 'pth:gpio24', 'x_offset': '0', 'y_offset': '0', 'z_offset': '-0.1', 'speed': '3', 'samples': '3', 'sample_retract_dist': '0.7', 'samples_tolerance': '0.05', 'samples_result': 'median'}, 'controller_fan mcu_fan1': {'pin': 'gpio17', 'max_power': '0.8', 'shutdown_speed': '0', 'kick_start_time': '1', 'fan_speed': '0.8', 'idle_timeout': '5', 'stepper': 'stepper_x, stepper_y, stepper_z'}, 'controller_fan mcu_fan2': {'pin': 'gpio18', 'max_power': '0.5', 'shutdown_speed': '0', 'kick_start_time': '1', 'fan_speed': '0.5', 'idle_timeout': '5', 'stepper': 'stepper_x, stepper_y, stepper_z'}, 'heater_fan hotend_fan': {'pin': 'pth:gpio5', 'max_power': '1.0', 'kick_start_time': '0.5', 'heater': 'extruder', 'fan_speed': '0.7'}, 'fan': {'pin': 'pth:gpio6', 'max_power': '1.0', 'kick_start_time': '0.5', 'off_below': '0.13', 'cycle_time': '0.010'}, 'output_pin pcb_led': {'pin': '!pth:gpio8'}, 'neopixel indicator': {'pin': 'gpio24', 'chain_count': '5', 'color_order': 'GRB', 'initial_red': '1.0', 'initial_green': '0.0', 'initial_blue': '0.0'}, 'adxl345': {'cs_pin': 'pth:gpio21', 'spi_software_sclk_pin': 'pth:gpio18', 'spi_software_mosi_pin': 'pth:gpio20', 'spi_software_miso_pin': 'pth:gpio19'}, 'resonance_tester': {'accel_chip': 'adxl345', 'probe_points': '\n85, 85, 20'}, 'idle_timeout': {'timeout': '1800'}, 'bed_screws': {'screw1': '5,170', 'screw1_name': 'fl', 'screw2': '180,170', 'screw2_name': 'fr', 'screw3': '90,20', 'screw3_name': 'bm'}, 'output_pin beeper': {'pin': 'gpio22', 'value': '0', 'shutdown_value': '0'}, 'bed_tilt': {'points': '\n0, 14\n116, 14\n116, 106\n0, 106', 'speed': '150', 'horizontal_move_z': '4'}, 'gcode_macro _HOME_X': {'gcode': "\n\n{% set RUN_CURRENT_X = printer.configfile.settings['tmc2209 stepper_x'].run_current|float %}\n{% set RUN_CURRENT_Y = printer.configfile.settings['tmc2209 stepper_y'].run_current|float %}\n{% set HOME_CURRENT = 0.7 %}\nSET_TMC_CURRENT STEPPER=stepper_x CURRENT={HOME_CURRENT}\nSET_TMC_CURRENT STEPPER=stepper_y CURRENT={HOME_CURRENT}\nSAVE_GCODE_STATE NAME=STATE_HOME_X\n\n\nG28 X\n\nG91\nG1 X5 F1200\n\n\nG4 P500\n\nSET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}\nSET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}\nRESTORE_GCODE_STATE NAME=STATE_HOME_X"}, 'gcode_macro _HOME_Y': {'gcode': "\n\n{% set RUN_CURRENT_X = printer.configfile.settings['tmc2209 stepper_x'].run_current|float %}\n{% set RUN_CURRENT_Y = printer.configfile.settings['tmc2209 stepper_y'].run_current|float %}\n{% set HOME_CURRENT = 0.7 %}\nSET_TMC_CURRENT STEPPER=stepper_x CURRENT={HOME_CURRENT}\nSET_TMC_CURRENT STEPPER=stepper_y CURRENT={HOME_CURRENT}\nSAVE_GCODE_STATE NAME=STATE_HOME_Y\n\n\nG28 Y\n\nG91\nG1 Y-5 F1200\n\n\nG4 P500\n\nSET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}\nSET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}\nRESTORE_GCODE_STATE NAME=STATE_HOME_Y"}, 'homing_override': {'axes': 'xyz', 'set_position_z': '0', 'gcode': "\n{% set home_all = 'X' not in params and 'Y' not in params and 'Z' not in params %}\nSAVE_GCODE_STATE NAME=STATE_HOME_OVERRIDE\n\n{% if home_all or 'Y' in params or 'X' in params %}\nG91\nG1 Z5\n{% endif %}\n\n{% if home_all or 'Y' in params %}\n_HOME_Y\n{% endif %}\n\n{% if home_all or 'X' in params %}\n_HOME_X\n{% endif %}\n\n{% if home_all or 'Z' in params %}\nG90\nG0 X40 Y60 F3600\nG28 Z\nG91\nG0 Z30\n{% endif %}\n\nRESTORE_GCODE_STATE NAME=STATE_HOME_OVERRIDE"}, 'gcode_macro M300': {'description': 'Implements M300 gcode which allows beeper to be used', 'gcode': '\n{% set TIME_MS = params.P|default(100)|float %}\nSET_PIN PIN=beeper VALUE=1\nG4 P{TIME_MS}\nSET_PIN PIN=beeper VALUE=0'}, 'gcode_macro M600': {'description': 'Implements M600 gcode (pause & filament change)', 'gcode': '\npause\nSAVE_GCODE_STATE NAME=M600\nG91\nG1 Z20\nFRONT\nM83\nG1 E10 F300\nG1 E-30 F3000\nG4 P200\nG1 E-100 F1200\nG1 E-100 F1200\nG1 E-100 F1200\nG1 E-100 F1200\nM400\nRESTORE_GCODE_STATE NAME=M600\nM117 Unload Complete!'}, 'gcode_macro CHOME': {'description': 'Homes XYZ axis only if printer is in a non-homed state', 'gcode': '\n{% if "xyz" not in printer.toolhead.homed_axes %}\nG28\n{% endif %}'}, 'gcode_macro CENTER': {'description': 'Moves the toolhead to the center', 'gcode': '\nCHOME\n{% set x_center = printer.toolhead.axis_maximum.x|float / 2.0 %}\n{% set y_center = printer.toolhead.axis_maximum.y|float / 2.0 %}\nG90\nG1 X{x_center} Y{x_center} F7800'}, 'gcode_macro FRONT': {'description': 'Moves the toolhead to the front', 'gcode': '\nCHOME\n{% set x_center = printer.toolhead.axis_maximum.x|float / 2.0 %}\n{% set y_front = printer.toolhead.axis_maximum.y|float - 10 %}\nG90\nG1 X{x_center} Y{y_front} F7800'}, 'gcode_macro NOZZLE_PURGE': {'description': 'Draw a purge line at the front left edge of the build plate', 'gcode': '\nCHOME\nSAVE_GCODE_STATE NAME=NOZZLE_PURGE\nG0 X2 Y175 F7200\nG0 Z0.2\nM83\nG1 X2 Y105 E20 F800\nG1 E-0.5 F400\nG1 Y65 F4000\nG1 Z0.4\nRESTORE_GCODE_STATE NAME=NOZZLE_PURGE'}, 'gcode_macro UNLOAD_FILAMENT': {'description': 'Unloads filament from toolhead. Hotend is not preheated, if TEMP parameter is set to 0', 'gcode': '\n{% set EXTRUDER_TEMP = params.TEMP|default(215)|int %}\n{% set MIN_TEMP = params.TEMP|default(215)|float 0.98 %}\n{% set CURRENT_TARGET = printer.extruder.target|float %}\nCHOME\nSAVE_GCODE_STATE NAME=UNLOAD_FILAMENT\nG91\nG1 Z20\nFRONT\n\n{% if EXTRUDER_TEMP != 0 %}\nLED_PENDING\n{% if CURRENT_TARGET < EXTRUDER_TEMP %}\nM104 S{EXTRUDER_TEMP}\n{% endif %}\nTEMPERATURE_WAIT SENSOR="extruder" MINIMUM={MIN_TEMP}\n{% endif %}\nLED_WORKING\nM83\nG1 E10 F300\nG1 E-30 F3600\nG4 P200\nG1 E-100 F1200\nG1 E-100 F1200\nG1 E-100 F1200\nG1 E-100 F1200\nM400\nRESTORE_GCODE_STATE NAME=UNLOAD_FILAMENT\nM300 P1000\nM117 Unload Complete!\nLED_READY'}, 'gcode_macro LOAD_FILAMENT': {'description': 'Loads new filament into toolhead. Hotend is not preheated, if TEMP parameter is set to 0', 'gcode': '\n{% set EXTRUDER_TEMP = params.TEMP|default(215)|int %}\n{% set MIN_TEMP = params.TEMP|default(215)|float 0.98 %}\n{% set CURRENT_TARGET = printer.extruder.target|float %}\nSAVE_GCODE_STATE NAME=LOAD_FILAMENT\nG91\nG1 Z20\nFRONT\n\n{% if EXTRUDER_TEMP != 0 %}\nLED_PENDING\n{% if CURRENT_TARGET < EXTRUDER_TEMP %}\nM104 S{EXTRUDER_TEMP}\n{% endif %}\nTEMPERATURE_WAIT SENSOR="extruder" MINIMUM={MIN_TEMP}\n{% endif %}\nLED_WORKING\nM83\nG1 E100 F1200\nG1 E100 F1200\nG1 E100 F1200\nG1 E100 F1200\nG1 E20 F600\nM400\nRESTORE_GCODE_STATE NAME=LOAD_FILAMENT\nM300 P200\nG4 P100\nM300 P200\nM117 Load Complete!\nLED_READY'}, 'gcode_macro G29': {'description': 'Loads new filament into toolhead. Hotend is not preheated, if TEMP parameter is set to 0', 'gcode': '\nCHOME\nG1 Z5 F800\nBED_TILT_CALIBRATE\nG28'}, 'gcode_macro PRINT_START': {'description': 'print startup sequence', 'gcode': '\n{% set BED_TEMP = params.BED|default(65)|float %}\n{% set READY_TEMP = params.BED|default(65)|float 0.92 %}\n{% set EXTRUDER_TEMP = params.EXTRUDER|default(190)|float %}\n\nLED_PENDING\nM140 S{BED_TEMP}\nM104 S150\nG28\nTEMPERATURE_WAIT SENSOR="heater_bed" MINIMUM={READY_TEMP}\n\nG1 Z40 F300\nG1 X5 F3000\nM109 S{EXTRUDER_TEMP}\nM190 S{BED_TEMP}\n\nG29\nG90\nLED_WORKING\nNOZZLE_PURGE'}, 'gcode_macro PRINT_END': {'description': 'print finish sequence', 'gcode': '\n{% set th = printer.toolhead %}\n{% set x_safe = th.position.x + 20 (1 if th.axis_maximum.x - th.position.x > 20 else -1) %}\n{% set y_safe = th.position.y + 20 (1 if th.axis_maximum.y - th.position.y > 20 else -1) %}\n{% set z_safe = [th.position.z + 2, th.axis_maximum.z]|min %}\n{% set y_final = max_y - 1 %}\n{% set z_final = [th.position.z + 50, th.axis_maximum.z]|min %}\n\nSAVE_GCODE_STATE NAME=STATE_PRINT_END\nM400\nG92 E0\nG1 E-3.0 F3600\nTURN_OFF_HEATERS\n\n\nG90\nG0 X{x_safe} Y{y_safe} Z{z_safe} F20000\nG0 X5 Y{y_final} F3600\nG0 Z{z_final} F600\n\nM107\nLED_COMPLETE\nRESTORE_GCODE_STATE NAME=STATE_PRINT_END MOVE=0'}, 'gcode_macro LED_PENDING': {'description': 'sets the indicators to teal', 'gcode': '\nSET_LED LED=indicator RED=0 GREEN=0.4 BLUE=0.2 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0 GREEN=0.4 BLUE=0.2 INDEX=3'}, 'gcode_macro LED_WORKING': {'description': 'sets the indicators to purple', 'gcode': '\nSET_LED LED=indicator RED=0.5 GREEN=0.1 BLUE=0.6 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0.5 GREEN=0.1 BLUE=0.6 INDEX=3'}, 'gcode_macro LED_COMPLETE': {'description': 'sets the indicators to green', 'gcode': '\nSET_LED LED=indicator RED=0 GREEN=0.8 BLUE=0 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0 GREEN=0.8 BLUE=0 INDEX=3'}, 'gcode_macro LED_ERROR': {'description': 'sets the indicators to red', 'gcode': '\nSET_LED LED=indicator RED=0.6 GREEN=0 BLUE=0 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0.6 GREEN=0 BLUE=0 INDEX=3'}, 'gcode_macro LED_READY': {'description': 'sets the indicators and light strips to white', 'gcode': '\nSET_LED LED=indicator RED=0.5 GREEN=0.5 BLUE=0.5 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0.05 GREEN=0.08 BLUE=0.1 INDEX=2 TRANSMIT=0\nSET_LED LED=indicator RED=0.5 GREEN=0.5 BLUE=0.5 INDEX=3 TRANSMIT=0\nSET_LED LED=indicator RED=1.0 GREEN=1.0 BLUE=1.0 INDEX=4 TRANSMIT=0\nSET_LED LED=indicator RED=1.0 GREEN=1.0 BLUE=1.0 INDEX=5'}, 'gcode_macro LED_OFF': {'gcode': '\nSET_LED LED=indicator RED=0 GREEN=0 BLUE=0'}, 'delayed_gcode STARTUP_CODE': {'initial_duration': '0.5', 'gcode': '\nLED_READY'}, 'exclude_object': {}}, 'settings': {'mcu': {'serial': '/dev/serial/by-path/platform-fe9c0000.xhci-usb-0:1.3:1.0', 'baud': 250000, 'restart_method': 'command', 'max_stepper_error': 2.5e-05}, 'mcu pth': {'serial': '/dev/serial/by-path/platform-fe9c0000.xhci-usb-0:1.2:1.0', 'baud': 250000, 'restart_method': 'command', 'max_stepper_error': 2.5e-05}, 'virtual_sdcard': {'path': '/home/pi/printer_data/gcodes', 'on_error_gcode': 'CANCEL_PRINT'}, 'pause_resume': {'recover_velocity': 50.0}, 'respond': {'default_type': 'echo', 'default_prefix': 'echo:'}, 'gcode_macro cancel_print': {'gcode': '\n{% set th = printer.toolhead %}\n{% set z_safe = [th.position.z + 2, th.axis_maximum.z]|min %}\n{% set z_final = [th.position.z + 50, th.axis_maximum.z]|min %}\n{% set y_final = th.axis_maximum.y - 1 %}\n\nCLEAR_PAUSE\nSDCARD_RESET_FILE\n\nSAVE_GCODE_STATE NAME=STATE_CANCEL_PRINT\nM400\nG92 E0\nG1 E-3.0 F3600\nTURN_OFF_HEATERS\n\nG90\nG0 Z{z_safe} F3600\nG1 X5 Y{y_final} F3600\nG1 Z{z_final} F600\nM107\nRESTORE_GCODE_STATE NAME=STATE_CANCEL_PRINT MOVE=0\n\nLED_ERROR\nBASE_CANCEL_PRINT', 'rename_existing': 'BASE_CANCEL_PRINT', 'description': 'Cancel the actual running print'}, 'gcode_macro pause': {'gcode': '\n\n{% set E = printer["gcode_macro PAUSE"].extrude|float %}\n\n\n{% set x_park = printer.toolhead.axis_maximum.x|float - 10.0 %}\n{% set y_park = printer.toolhead.axis_maximum.y|float - 10.0 %}\n\n{% set max_z = printer.toolhead.axis_maximum.z|float %}\n{% set act_z = printer.toolhead.position.z|float %}\n{% if act_z < (max_z - 2.0) %}\n{% set z_safe = 2.0 %}\n{% else %}\n{% set z_safe = max_z - act_z %}\n{% endif %}\n\nSAVE_GCODE_STATE NAME=PAUSE_state\nBASE_PAUSE\nG91\nG1 E-{E} F240\nG1 Z{z_safe} F900\nG90\nG1 X{x_park} Y{y_park} F5000', 'rename_existing': 'BASE_PAUSE', 'description': 'Pause the actual running print', 'variable_extrude': '1.0'}, 'gcode_macro resume': {'gcode': '\n\n{% set E = printer["gcode_macro PAUSE"].extrude|float %}\n\nG91\nG1 E{E} F240\nRESTORE_GCODE_STATE NAME=PAUSE_state\nBASE_RESUME', 'rename_existing': 'BASE_RESUME', 'description': 'Resume the actual running print', 'variable_last_extruder_temp': "{'restore': False, 'temp': 0}", 'variable_restore_idle_timeout': '0', 'variable_idle_state': 'False'}, 'gcode_macro set_pause_next_layer': {'gcode': '\n{% set pause_next_layer = printer[\'gcode_macro SET_PRINT_STATS_INFO\'].pause_next_layer %}\n{% set ENABLE = params.ENABLE | default(1) | int != 0 %}\n{% set MACRO = params.MACRO | default(pause_next_layer.call, True) %}\nSET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_next_layer VALUE="{{ \'enable\': ENABLE, \'call\': MACRO }}"', 'description': 'Enable a pause if the next layer is reached'}, 'gcode_macro set_pause_at_layer': {'gcode': '\n{% set pause_at_layer = printer[\'gcode_macro SET_PRINT_STATS_INFO\'].pause_at_layer %}\n{% set ENABLE = params.ENABLE | int != 0 if params.ENABLE is defined\nelse params.LAYER is defined %}\n{% set LAYER = params.LAYER | default(pause_at_layer.layer) | int %}\n{% set MACRO = params.MACRO | default(pause_at_layer.call, True) %}\nSET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_at_layer VALUE="{{ \'enable\': ENABLE, \'layer\': LAYER, \'call\': MACRO }}"', 'description': 'Enable/disable a pause if a given layer number is reached'}, 'gcode_macro set_print_stats_info': {'gcode': '\n{% if pause_next_layer.enable %}\nRESPOND TYPE=echo MSG=\'{"%s, forced by pause_next_layer" % pause_next_layer.call}\'\n{pause_next_layer.call}\nSET_PAUSE_NEXT_LAYER ENABLE=0\n{% elif pause_at_layer.enable and params.CURRENT_LAYER is defined and params.CURRENT_LAYER | int == pause_at_layer.layer %}\nRESPOND TYPE=echo MSG=\'{"%s, forced by pause_at_layer [%d]" % (pause_at_layer.call, pause_at_layer.layer)}\'\n{pause_at_layer.call}\nSET_PAUSE_AT_LAYER ENABLE=0\n{% endif %}\nSET_PRINT_STATS_INFO_BASE {rawparams}', 'rename_existing': 'SET_PRINT_STATS_INFO_BASE', 'description': 'Overwrite, to get pause_next_layer and pause_at_layer feature', 'variable_pause_next_layer': '{ \'enable\': False, \'call\': "PAUSE" }', 'variable_pause_at_layer': '{ \'enable\': False, \'layer\': 0, \'call\': "PAUSE" }'}, 'gcode_macro _toolhead_park_pause_cancel': {'gcode': '\n\n{% set client = printer[\'gcode_macro _CLIENT_VARIABLE\'] | default({}) %}\n{% set velocity = printer.configfile.settings.pause_resume.recover_velocity %}\n{% set use_custom = client.use_custom_pos | default(false) | lower == \'true\' %}\n{% set custom_park_x = client.custom_park_x | default(0.0) %}\n{% set custom_park_y = client.custom_park_y | default(0.0) %}\n{% set park_dz = client.custom_park_dz | default(2.0) | abs %}\n{% set sp_hop = client.speed_hop | default(15) 60 %}\n{% set sp_move = client.speed_move | default(velocity) 60 %}\n\n{% set origin = printer.gcode_move.homing_origin %}\n{% set act = printer.gcode_move.gcode_position %}\n{% set max = printer.toolhead.axis_maximum %}\n{% set cone = printer.toolhead.cone_start_z | default(max.z) %}\n{% set round_bed = True if printer.configfile.settings.printer.kinematics is in [\'delta\',\'polar\',\'rotary_delta\',\'winch\']\nelse False %}\n\n{% set z_min = params.Z_MIN | default(0) | float %}\n{% set z_park = [[(act.z + park_dz), z_min] | max, (max.z - origin.z)] | min %}\n{% set x_park = params.X if params.X is defined\nelse custom_park_x if use_custom\nelse 0.0 if round_bed\nelse (max.x - 5.0) %}\n{% set y_park = params.Y if params.Y is defined\nelse custom_park_y if use_custom\nelse (max.y - 5.0) if round_bed and z_park < cone\nelse 0.0 if round_bed\nelse (max.y - 5.0) %}\n\n_CLIENT_RETRACT\n{% if "xyz" in printer.toolhead.homed_axes %}\nG90\nG1 Z{z_park} F{sp_hop}\nG1 X{x_park} Y{y_park} F{sp_move}\n{% if not printer.gcode_move.absolute_coordinates %} G91 {% endif %}\n{% else %}\nRESPOND TYPE=echo MSG=\'Printer not homed\'\n{% endif %}', 'description': 'Helper: park toolhead used in PAUSE and CANCEL_PRINT'}, 'gcode_macro _client_extrude': {'gcode': '\n\n{% set client = printer[\'gcode_macro _CLIENT_VARIABLE\'] | default({}) %}\n{% set use_fw_retract = (client.use_fw_retract | default(false) | lower == \'true\') and (printer.firmware_retraction is defined) %}\n{% set length = params.LENGTH | default(client.unretract) | default(1.0) | float %}\n{% set speed = params.SPEED | default(client.speed_unretract) | default(35) %}\n{% set absolute_extrude = printer.gcode_move.absolute_extrude %}\n\n{% if printer.toolhead.extruder != \'\' %}\n{% if printer[printer.toolhead.extruder].can_extrude %}\n{% if use_fw_retract %}\n{% if length < 0 %}\nG10\n{% else %}\nG11\n{% endif %}\n{% else %}\nM83\nG1 E{length} F{(speed | float | abs) 60}\n{% if absolute_extrude %}\nM82\n{% endif %}\n{% endif %}\n{% else %}\nRESPOND TYPE=echo MSG=\'{"\"%s\" not hot enough" % printer.toolhead.extruder}\'\n{% endif %}\n{% endif %}', 'description': 'Extrudes, if the extruder is hot enough'}, 'gcode_macro _client_retract': {'gcode': "\n{% set client = printer['gcode_macro _CLIENT_VARIABLE'] | default({}) %}\n{% set length = params.LENGTH | default(client.retract) | default(1.0) | float %}\n{% set speed = params.SPEED | default(client.speed_retract) | default(35) %}\n\n_CLIENT_EXTRUDE LENGTH=-{length | float | abs} SPEED={speed | float | abs}", 'description': 'Retracts, if the extruder is hot enough'}, 'tmc2209 stepper_x': {'uart_pin': 'gpio9', 'tx_pin': 'gpio8', 'uart_address': 3, 'diag_pin': '^gpio16', 'run_current': 0.7, 'hold_current': 2.0, 'sense_resistor': 0.11, 'interpolate': True, 'stealthchop_threshold': 999999.0, 'driver_multistep_filt': True, 'driver_toff': 3, 'driver_hstrt': 5, 'driver_hend': 0, 'driver_tbl': 2, 'driver_iholddelay': 8, 'driver_pwm_ofs': 36, 'driver_pwm_grad': 14, 'driver_pwm_freq': 1, 'driver_pwm_autoscale': True, 'driver_pwm_autograd': True, 'driver_pwm_reg': 8, 'driver_pwm_lim': 12, 'driver_tpowerdown': 20, 'driver_sgthrs': 52}, 'stepper_x': {'microsteps': 16, 'step_pin': 'gpio14', 'dir_pin': '!gpio13', 'rotation_distance': 40.0, 'full_steps_per_rotation': 200, 'gear_ratio': [], 'enable_pin': '!gpio15', 'endstop_pin': 'tmc2209_stepper_x:virtual_endstop', 'position_endstop': 0.0, 'position_min': 0.0, 'position_max': 185.0, 'homing_speed': 40.0, 'second_homing_speed': 20.0, 'homing_retract_speed': 40.0, 'homing_retract_dist': 0.0, 'homing_positive_dir': False}, 'tmc2209 stepper_y': {'uart_pin': 'gpio9', 'tx_pin': 'gpio8', 'uart_address': 1, 'diag_pin': '^gpio25', 'run_current': 0.7, 'hold_current': 2.0, 'sense_resistor': 0.11, 'interpolate': True, 'stealthchop_threshold': 999999.0, 'driver_multistep_filt': True, 'driver_toff': 3, 'driver_hstrt': 5, 'driver_hend': 0, 'driver_tbl': 2, 'driver_iholddelay': 8, 'driver_pwm_ofs': 36, 'driver_pwm_grad': 14, 'driver_pwm_freq': 1, 'driver_pwm_autoscale': True, 'driver_pwm_autograd': True, 'driver_pwm_reg': 8, 'driver_pwm_lim': 12, 'driver_tpowerdown': 20, 'driver_sgthrs': 55}, 'stepper_y': {'microsteps': 16, 'step_pin': 'gpio19', 'dir_pin': '!gpio28', 'rotation_distance': 40.0, 'full_steps_per_rotation': 200, 'gear_ratio': [], 'enable_pin': '!gpio2', 'endstop_pin': 'tmc2209_stepper_y:virtual_endstop', 'position_endstop': 180.0, 'position_min': 0.0, 'position_max': 180.0, 'homing_speed': 40.0, 'second_homing_speed': 20.0, 'homing_retract_speed': 40.0, 'homing_retract_dist': 0.0, 'homing_positive_dir': True}, 'tmc2209 stepper_z': {'uart_pin': 'gpio9', 'tx_pin': 'gpio8', 'uart_address': 2, 'run_current': 0.25, 'hold_current': 2.0, 'sense_resistor': 0.11, 'interpolate': True, 'stealthchop_threshold': 999999.0, 'driver_multistep_filt': True, 'driver_toff': 3, 'driver_hstrt': 5, 'driver_hend': 0, 'driver_tbl': 2, 'driver_iholddelay': 8, 'driver_pwm_ofs': 36, 'driver_pwm_grad': 14, 'driver_pwm_freq': 1, 'driver_pwm_autoscale': True, 'driver_pwm_autograd': True, 'driver_pwm_reg': 8, 'driver_pwm_lim': 12, 'driver_tpowerdown': 20, 'driver_sgthrs': 0}, 'stepper_z': {'microsteps': 16, 'step_pin': 'gpio6', 'dir_pin': '!gpio5', 'rotation_distance': 40.0, 'full_steps_per_rotation': 200, 'gear_ratio': [[75.0, 10.0]], 'enable_pin': '!gpio7', 'endstop_pin': 'probe:z_virtual_endstop', 'position_min': -4.0, 'position_max': 165.0, 'homing_speed': 13.0, 'second_homing_speed': 6.5, 'homing_retract_speed': 13.0, 'homing_retract_dist': 5.0, 'homing_positive_dir': False}, 'tmc2209 extruder': {'uart_pin': 'gpio9', 'tx_pin': 'gpio8', 'uart_address': 0, 'run_current': 0.72, 'hold_current': 0.4, 'sense_resistor': 0.11, 'interpolate': True, 'driver_multistep_filt': True, 'driver_toff': 3, 'driver_hstrt': 5, 'driver_hend': 0, 'driver_tbl': 2, 'driver_iholddelay': 8, 'driver_pwm_ofs': 36, 'driver_pwm_grad': 14, 'driver_pwm_freq': 1, 'driver_pwm_autoscale': True, 'driver_pwm_autograd': True, 'driver_pwm_reg': 8, 'driver_pwm_lim': 12, 'driver_tpowerdown': 20, 'driver_sgthrs': 0}, 'extruder': {'microsteps': 16, 'sensor_type': 'ATC Semitec 104NT-4-R025H42G', 'pullup_resistor': 2200.0, 'inline_resistor': 0.0, 'sensor_pin': 'pth:gpio29', 'min_temp': -100.0, 'max_temp': 300.0, 'min_extrude_temp': 150.0, 'max_power': 1.0, 'smooth_time': 1.0, 'control': 'pid', 'pid_kp': 25.12, 'pid_ki': 1.073, 'pid_kd': 147.0, 'heater_pin': 'pth:gpio9', 'pwm_cycle_time': 0.1, 'nozzle_diameter': 0.4, 'filament_diameter': 1.75, 'max_extrude_cross_section': 2.0, 'max_extrude_only_velocity': 111.7540537550406, 'max_extrude_only_accel': 2128.648642953154, 'max_extrude_only_distance': 400.0, 'instantaneous_corner_velocity': 1.0, 'step_pin': 'gpio11', 'pressure_advance': 0.18, 'pressure_advance_smooth_time': 0.04, 'dir_pin': '!gpio10', 'rotation_distance': 4.561, 'full_steps_per_rotation': 200, 'gear_ratio': [], 'enable_pin': '!gpio12'}, 'thermistor sdnt2012x104_3950': {'temperature1': 25.0, 'resistance1': 100000.0, 'beta': 3950.0}, 'heater_bed': {'sensor_type': 'SDNT2012X104_3950', 'pullup_resistor': 4700.0, 'inline_resistor': 0.0, 'sensor_pin': 'gpio26', 'min_temp': 0.0, 'max_temp': 120.0, 'min_extrude_temp': 170.0, 'max_power': 1.0, 'smooth_time': 1.0, 'control': 'pid', 'pid_kp': 56.852, 'pid_ki': 2.1, 'pid_kd': 383.75, 'heater_pin': 'gpio21', 'pwm_cycle_time': 0.3}, 'verify_heater heater_bed': {'hysteresis': 5.0, 'max_error': 120.0, 'heating_gain': 2.0, 'check_gain_time': 60.0}, 'probe': {'z_offset': -0.1, 'deactivate_on_each_sample': True, 'activate_gcode': '', 'deactivate_gcode': '', 'pin': 'pth:gpio24', 'speed': 3.0, 'lift_speed': 3.0, 'x_offset': 0.0, 'y_offset': 0.0, 'samples': 3, 'sample_retract_dist': 0.7, 'samples_result': 'median', 'samples_tolerance': 0.05, 'samples_tolerance_retries': 0}, 'controller_fan mcu_fan1': {'stepper': ['stepper_x', 'stepper_y', 'stepper_z'], 'max_power': 0.8, 'kick_start_time': 1.0, 'off_below': 0.0, 'cycle_time': 0.01, 'hardware_pwm': False, 'shutdown_speed': 0.0, 'pin': 'gpio17', 'fan_speed': 0.8, 'idle_speed': 0.8, 'idle_timeout': 5, 'heater': ['extruder']}, 'controller_fan mcu_fan2': {'stepper': ['stepper_x', 'stepper_y', 'stepper_z'], 'max_power': 0.5, 'kick_start_time': 1.0, 'off_below': 0.0, 'cycle_time': 0.01, 'hardware_pwm': False, 'shutdown_speed': 0.0, 'pin': 'gpio18', 'fan_speed': 0.5, 'idle_speed': 0.5, 'idle_timeout': 5, 'heater': ['extruder']}, 'heater_fan hotend_fan': {'heater': ['extruder'], 'heater_temp': 50.0, 'max_power': 1.0, 'kick_start_time': 0.5, 'off_below': 0.0, 'cycle_time': 0.01, 'hardware_pwm': False, 'shutdown_speed': 1.0, 'pin': 'pth:gpio5', 'fan_speed': 0.7}, 'fan': {'max_power': 1.0, 'kick_start_time': 0.5, 'off_below': 0.13, 'cycle_time': 0.01, 'hardware_pwm': False, 'shutdown_speed': 0.0, 'pin': 'pth:gpio6'}, 'output_pin pcb_led': {'pwm': False, 'pin': '!pth:gpio8', 'maximum_mcu_duration': 0.0, 'value': 0.0, 'shutdown_value': 0.0}, 'neopixel indicator': {'pin': 'gpio24', 'chain_count': 5, 'color_order': ['GRB'], 'initial_red': 1.0, 'initial_green': 0.0, 'initial_blue': 0.0, 'initial_white': 0.0}, 'adxl345': {'axes_map': ['x', 'y', 'z'], 'rate': 3200, 'cs_pin': 'pth:gpio21', 'spi_speed': 5000000, 'spi_software_sclk_pin': 'pth:gpio18', 'spi_software_miso_pin': 'pth:gpio19', 'spi_software_mosi_pin': 'pth:gpio20'}, 'resonance_tester': {'move_speed': 50.0, 'min_freq': 5.0, 'max_freq': 133.33333333333334, 'accel_per_hz': 75.0, 'hz_per_sec': 1.0, 'probe_points': [[85.0, 85.0, 20.0]], 'accel_chip': 'adxl345'}, 'idle_timeout': {'timeout': 1800.0, 'gcode': "\n{% if 'heaters' in printer %}\n TURN_OFF_HEATERS\n{% endif %}\nM84\n"}, 'bed_screws': {'screw1': [5.0, 170.0], 'screw1_name': 'fl', 'screw2': [180.0, 170.0], 'screw2_name': 'fr', 'screw3': [90.0, 20.0], 'screw3_name': 'bm', 'speed': 50.0, 'probe_speed': 5.0, 'horizontal_move_z': 5.0, 'probe_height': 0.0}, 'output_pin beeper': {'pwm': False, 'pin': 'gpio22', 'maximum_mcu_duration': 0.0, 'value': 0.0, 'shutdown_value': 0.0}, 'bed_tilt': {'x_adjust': 0.0, 'y_adjust': 0.0, 'z_adjust': 0.0, 'points': [[0.0, 14.0], [116.0, 14.0], [116.0, 106.0], [0.0, 106.0]], 'horizontal_move_z': 4.0, 'speed': 150.0}, 'gcode_macro _home_x': {'gcode': "\n\n{% set RUN_CURRENT_X = printer.configfile.settings['tmc2209 stepper_x'].run_current|float %}\n{% set RUN_CURRENT_Y = printer.configfile.settings['tmc2209 stepper_y'].run_current|float %}\n{% set HOME_CURRENT = 0.7 %}\nSET_TMC_CURRENT STEPPER=stepper_x CURRENT={HOME_CURRENT}\nSET_TMC_CURRENT STEPPER=stepper_y CURRENT={HOME_CURRENT}\nSAVE_GCODE_STATE NAME=STATE_HOME_X\n\n\nG28 X\n\nG91\nG1 X5 F1200\n\n\nG4 P500\n\nSET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}\nSET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}\nRESTORE_GCODE_STATE NAME=STATE_HOME_X", 'description': 'G-Code macro'}, 'gcode_macro _home_y': {'gcode': "\n\n{% set RUN_CURRENT_X = printer.configfile.settings['tmc2209 stepper_x'].run_current|float %}\n{% set RUN_CURRENT_Y = printer.configfile.settings['tmc2209 stepper_y'].run_current|float %}\n{% set HOME_CURRENT = 0.7 %}\nSET_TMC_CURRENT STEPPER=stepper_x CURRENT={HOME_CURRENT}\nSET_TMC_CURRENT STEPPER=stepper_y CURRENT={HOME_CURRENT}\nSAVE_GCODE_STATE NAME=STATE_HOME_Y\n\n\nG28 Y\n\nG91\nG1 Y-5 F1200\n\n\nG4 P500\n\nSET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}\nSET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}\nRESTORE_GCODE_STATE NAME=STATE_HOME_Y", 'description': 'G-Code macro'}, 'homing_override': {'set_position_z': 0.0, 'axes': 'xyz', 'gcode': "\n{% set home_all = 'X' not in params and 'Y' not in params and 'Z' not in params %}\nSAVE_GCODE_STATE NAME=STATE_HOME_OVERRIDE\n\n{% if home_all or 'Y' in params or 'X' in params %}\nG91\nG1 Z5\n{% endif %}\n\n{% if home_all or 'Y' in params %}\n_HOME_Y\n{% endif %}\n\n{% if home_all or 'X' in params %}\n_HOME_X\n{% endif %}\n\n{% if home_all or 'Z' in params %}\nG90\nG0 X40 Y60 F3600\nG28 Z\nG91\nG0 Z30\n{% endif %}\n\nRESTORE_GCODE_STATE NAME=STATE_HOME_OVERRIDE"}, 'gcode_macro m300': {'gcode': '\n{% set TIME_MS = params.P|default(100)|float %}\nSET_PIN PIN=beeper VALUE=1\nG4 P{TIME_MS}\nSET_PIN PIN=beeper VALUE=0', 'description': 'Implements M300 gcode which allows beeper to be used'}, 'gcode_macro m600': {'gcode': '\npause\nSAVE_GCODE_STATE NAME=M600\nG91\nG1 Z20\nFRONT\nM83\nG1 E10 F300\nG1 E-30 F3000\nG4 P200\nG1 E-100 F1200\nG1 E-100 F1200\nG1 E-100 F1200\nG1 E-100 F1200\nM400\nRESTORE_GCODE_STATE NAME=M600\nM117 Unload Complete!', 'description': 'Implements M600 gcode (pause & filament change)'}, 'gcode_macro chome': {'gcode': '\n{% if "xyz" not in printer.toolhead.homed_axes %}\nG28\n{% endif %}', 'description': 'Homes XYZ axis only if printer is in a non-homed state'}, 'gcode_macro center': {'gcode': '\nCHOME\n{% set x_center = printer.toolhead.axis_maximum.x|float / 2.0 %}\n{% set y_center = printer.toolhead.axis_maximum.y|float / 2.0 %}\nG90\nG1 X{x_center} Y{x_center} F7800', 'description': 'Moves the toolhead to the center'}, 'gcode_macro front': {'gcode': '\nCHOME\n{% set x_center = printer.toolhead.axis_maximum.x|float / 2.0 %}\n{% set y_front = printer.toolhead.axis_maximum.y|float - 10 %}\nG90\nG1 X{x_center} Y{y_front} F7800', 'description': 'Moves the toolhead to the front'}, 'gcode_macro nozzle_purge': {'gcode': '\nCHOME\nSAVE_GCODE_STATE NAME=NOZZLE_PURGE\nG0 X2 Y175 F7200\nG0 Z0.2\nM83\nG1 X2 Y105 E20 F800\nG1 E-0.5 F400\nG1 Y65 F4000\nG1 Z0.4\nRESTORE_GCODE_STATE NAME=NOZZLE_PURGE', 'description': 'Draw a purge line at the front left edge of the build plate'}, 'gcode_macro unload_filament': {'gcode': '\n{% set EXTRUDER_TEMP = params.TEMP|default(215)|int %}\n{% set MIN_TEMP = params.TEMP|default(215)|float 0.98 %}\n{% set CURRENT_TARGET = printer.extruder.target|float %}\nCHOME\nSAVE_GCODE_STATE NAME=UNLOAD_FILAMENT\nG91\nG1 Z20\nFRONT\n\n{% if EXTRUDER_TEMP != 0 %}\nLED_PENDING\n{% if CURRENT_TARGET < EXTRUDER_TEMP %}\nM104 S{EXTRUDER_TEMP}\n{% endif %}\nTEMPERATURE_WAIT SENSOR="extruder" MINIMUM={MIN_TEMP}\n{% endif %}\nLED_WORKING\nM83\nG1 E10 F300\nG1 E-30 F3600\nG4 P200\nG1 E-100 F1200\nG1 E-100 F1200\nG1 E-100 F1200\nG1 E-100 F1200\nM400\nRESTORE_GCODE_STATE NAME=UNLOAD_FILAMENT\nM300 P1000\nM117 Unload Complete!\nLED_READY', 'description': 'Unloads filament from toolhead. Hotend is not preheated, if TEMP parameter is set to 0'}, 'gcode_macro load_filament': {'gcode': '\n{% set EXTRUDER_TEMP = params.TEMP|default(215)|int %}\n{% set MIN_TEMP = params.TEMP|default(215)|float 0.98 %}\n{% set CURRENT_TARGET = printer.extruder.target|float %}\nSAVE_GCODE_STATE NAME=LOAD_FILAMENT\nG91\nG1 Z20\nFRONT\n\n{% if EXTRUDER_TEMP != 0 %}\nLED_PENDING\n{% if CURRENT_TARGET < EXTRUDER_TEMP %}\nM104 S{EXTRUDER_TEMP}\n{% endif %}\nTEMPERATURE_WAIT SENSOR="extruder" MINIMUM={MIN_TEMP}\n{% endif %}\nLED_WORKING\nM83\nG1 E100 F1200\nG1 E100 F1200\nG1 E100 F1200\nG1 E100 F1200\nG1 E20 F600\nM400\nRESTORE_GCODE_STATE NAME=LOAD_FILAMENT\nM300 P200\nG4 P100\nM300 P200\nM117 Load Complete!\nLED_READY', 'description': 'Loads new filament into toolhead. Hotend is not preheated, if TEMP parameter is set to 0'}, 'gcode_macro g29': {'gcode': '\nCHOME\nG1 Z5 F800\nBED_TILT_CALIBRATE\nG28', 'description': 'Loads new filament into toolhead. Hotend is not preheated, if TEMP parameter is set to 0'}, 'gcode_macro print_start': {'gcode': '\n{% set BED_TEMP = params.BED|default(65)|float %}\n{% set READY_TEMP = params.BED|default(65)|float 0.92 %}\n{% set EXTRUDER_TEMP = params.EXTRUDER|default(190)|float %}\n\nLED_PENDING\nM140 S{BED_TEMP}\nM104 S150\nG28\nTEMPERATURE_WAIT SENSOR="heater_bed" MINIMUM={READY_TEMP}\n\nG1 Z40 F300\nG1 X5 F3000\nM109 S{EXTRUDER_TEMP}\nM190 S{BED_TEMP}\n\nG29\nG90\nLED_WORKING\nNOZZLE_PURGE', 'description': 'print startup sequence'}, 'gcode_macro print_end': {'gcode': '\n{% set th = printer.toolhead %}\n{% set x_safe = th.position.x + 20 (1 if th.axis_maximum.x - th.position.x > 20 else -1) %}\n{% set y_safe = th.position.y + 20 * (1 if th.axis_maximum.y - th.position.y > 20 else -1) %}\n{% set z_safe = [th.position.z + 2, th.axis_maximum.z]|min %}\n{% set y_final = max_y - 1 %}\n{% set z_final = [th.position.z + 50, th.axis_maximum.z]|min %}\n\nSAVE_GCODE_STATE NAME=STATE_PRINT_END\nM400\nG92 E0\nG1 E-3.0 F3600\nTURN_OFF_HEATERS\n\n\nG90\nG0 X{x_safe} Y{y_safe} Z{z_safe} F20000\nG0 X5 Y{y_final} F3600\nG0 Z{z_final} F600\n\nM107\nLED_COMPLETE\nRESTORE_GCODE_STATE NAME=STATE_PRINT_END MOVE=0', 'description': 'print finish sequence'}, 'gcode_macro led_pending': {'gcode': '\nSET_LED LED=indicator RED=0 GREEN=0.4 BLUE=0.2 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0 GREEN=0.4 BLUE=0.2 INDEX=3', 'description': 'sets the indicators to teal'}, 'gcode_macro led_working': {'gcode': '\nSET_LED LED=indicator RED=0.5 GREEN=0.1 BLUE=0.6 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0.5 GREEN=0.1 BLUE=0.6 INDEX=3', 'description': 'sets the indicators to purple'}, 'gcode_macro led_complete': {'gcode': '\nSET_LED LED=indicator RED=0 GREEN=0.8 BLUE=0 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0 GREEN=0.8 BLUE=0 INDEX=3', 'description': 'sets the indicators to green'}, 'gcode_macro led_error': {'gcode': '\nSET_LED LED=indicator RED=0.6 GREEN=0 BLUE=0 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0.6 GREEN=0 BLUE=0 INDEX=3', 'description': 'sets the indicators to red'}, 'gcode_macro led_ready': {'gcode': '\nSET_LED LED=indicator RED=0.5 GREEN=0.5 BLUE=0.5 INDEX=1 TRANSMIT=0\nSET_LED LED=indicator RED=0.05 GREEN=0.08 BLUE=0.1 INDEX=2 TRANSMIT=0\nSET_LED LED=indicator RED=0.5 GREEN=0.5 BLUE=0.5 INDEX=3 TRANSMIT=0\nSET_LED LED=indicator RED=1.0 GREEN=1.0 BLUE=1.0 INDEX=4 TRANSMIT=0\nSET_LED LED=indicator RED=1.0 GREEN=1.0 BLUE=1.0 INDEX=5', 'description': 'sets the indicators and light strips to white'}, 'gcode_macro led_off': {'gcode': '\nSET_LED LED=indicator RED=0 GREEN=0 BLUE=0', 'description': 'G-Code macro'}, 'delayed_gcode startup_code': {'gcode': '\nLED_READY', 'initial_duration': 0.5}, 'printer': {'max_velocity': 420.0, 'max_accel': 8000.0, 'max_accel_to_decel': 6000.0, 'square_corner_velocity': 7.0, 'buffer_time_low': 1.0, 'buffer_time_high': 2.0, 'buffer_time_start': 0.25, 'move_flush_time': 0.05, 'kinematics': 'corexy', 'max_z_velocity': 20.0, 'max_z_accel': 150.0}, 'force_move': {'enable_force_move': False}, 'verify_heater extruder': {'hysteresis': 5.0, 'max_error': 120.0, 'heating_gain': 2.0, 'check_gain_time': 20.0}}, 'warnings': [], 'save_config_pending': False, 'save_config_pending_items': {}}} 2024-04-10 23:08:06,465 [printer.py:stop_tempstore_updates()] - Stopping tempstore 2024-04-10 23:08:06,465 [printer.py:reinit()] - Klipper version: v0.12.0-12-g38221df8 2024-04-10 23:08:06,466 [printer.py:reinit()] - # Extruders: 1 2024-04-10 23:08:06,466 [printer.py:reinit()] - # Temperature devices: 1 2024-04-10 23:08:06,466 [printer.py:reinit()] - # Fans: 4 2024-04-10 23:08:06,466 [printer.py:reinit()] - # Output pins: 2 2024-04-10 23:08:06,466 [printer.py:reinit()] - # Leds: 1 2024-04-10 23:08:06,466 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/printer/gcode/help 2024-04-10 23:08:06,479 [KlippyWebsocket.py:object_subscription()] - Sending printer.objects.subscribe 2024-04-10 23:08:06,480 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/printer/objects/query?bed_mesh&configfile&display_status&extruder&fan&gcode_move&heater_bed&idle_timeout&pause_resume&print_stats&toolhead&virtual_sdcard&webhooks&motion_report&firmware_retraction&exclude_object&manual_probe&extruder&heater_bed&fan&controller_fan mcu_fan1&controller_fan mcu_fan2&heater_fan hotend_fan&output_pin pcb_led&output_pin beeper&neopixel indicator 2024-04-10 23:08:06,745 [files.py:set_gcodes_path()] - Gcodes path: /home/pi/printer_data/gcodes 2024-04-10 23:08:06,745 [screen.py:init_klipper()] - Printer initialized 2024-04-10 23:08:06,745 [printer.py:change_state()] - Changing state from 'disconnected' to 'ready' 2024-04-10 23:08:06,746 [printer.py:change_state()] - Adding callback for state: ready 2024-04-10 23:08:06,774 [KlippyWebsocket.py:get_file_list()] - Sending server.files.list 2024-04-10 23:08:06,776 [screen.py:_load_panel()] - Loading panel: main_menu 2024-04-10 23:08:06,835 [main_menu.py:init()] - ### Making MainMenu 2024-04-10 23:08:06,842 [main_menu.py:add_device()] - Adding device: extruder 2024-04-10 23:08:06,847 [main_menu.py:add_device()] - Adding device: heater_bed 2024-04-10 23:08:06,871 [screen.py:attach_panel()] - Current panel hierarchy: main_menu 2024-04-10 23:08:06,872 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/server/temperature_store 2024-04-10 23:08:06,890 [printer.py:init_temp_store()] - Temp store: ['heater_bed', 'extruder'] 2024-04-10 23:08:06,892 [KlippyRest.py:_do_request()] - Sending get to http://127.0.0.1:7125/server/config 2024-04-10 23:08:06,901 [screen.py:init_tempstore()] - Temperature store size: 1200 2024-04-10 23:08:17,576 [screen.py:_go_to_submenu()] - #### Go to submenu more 2024-04-10 23:08:17,577 [screen.py:_go_to_submenu()] - #### Menu main 2024-04-10 23:08:17,589 [screen.py:_load_panel()] - Loading panel: menu 2024-04-10 23:08:17,774 [screen.py:attach_panel()] - Current panel hierarchy: main_menu > more 2024-04-10 23:08:17,782 [menu.py:arrangeMenuItems()] - X > more bedmesh 2024-04-10 23:08:17,787 [menu.py:arrangeMenuItems()] - X > more retraction 2024-04-10 23:08:17,800 [menu.py:arrangeMenuItems()] - X > more power 2024-04-10 23:08:17,803 [menu.py:arrangeMenuItems()] - X > more camera 2024-04-10 23:08:17,808 [menu.py:arrangeMenuItems()] - X > more input_shaper 2024-04-10 23:08:17,814 [menu.py:arrangeMenuItems()] - X > more spoolman 2024-04-10 23:08:18,723 [screen.py:_load_panel()] - Loading panel: bed_level 2024-04-10 23:08:18,746 [bed_level.py:_get_screws()] - bed_screws 2024-04-10 23:08:18,747 [bed_level.py:_get_screws()] - screw1: 5,170 2024-04-10 23:08:18,747 [bed_level.py:_get_screws()] - screw1_name: fl 2024-04-10 23:08:18,747 [bed_level.py:_get_screws()] - screw2: 180,170 2024-04-10 23:08:18,748 [bed_level.py:_get_screws()] - screw2_name: fr 2024-04-10 23:08:18,748 [bed_level.py:_get_screws()] - screw3: 90,20 2024-04-10 23:08:18,748 [bed_level.py:_get_screws()] - screw3_name: bm 2024-04-10 23:08:18,748 [bed_level.py:init()] - bed_screws: [[90.0, 20.0], [5.0, 170.0], [180.0, 170.0]] 2024-04-10 23:08:18,748 [bed_level.py:init()] - Positions: ['fl', 'fr', 'bm'] 2024-04-10 23:08:18,748 [bed_level.py:init()] - Rotation: 0 2024-04-10 23:08:18,748 [bed_level.py:init()] - X: {90.0, 180.0, 5.0} Y: {170.0, 20.0} 2024-04-10 23:08:18,749 [bed_level.py:init()] - Using max_distance: 116 to fit: 3 screws. 2024-04-10 23:08:18,749 [bed_level.py:init()] - Screws not used: [[180.0, 170.0]] 2024-04-10 23:08:18,749 [bed_level.py:init__()] - Using 2/3-screw locations 2024-04-10 23:08:18,783 [screen.py:attach_panel()] - Current panel hierarchy: main_menu > more > bed_level 2024-04-10 23:08:22,658 [screen.py:_menu_go_back()] - #### Menu go back 2024-04-10 23:08:22,697 [screen.py:attach_panel()] - Current panel hierarchy: main_menu > more 2024-04-10 23:08:22,708 [menu.py:arrangeMenuItems()] - X > more bedmesh 2024-04-10 23:08:22,712 [menu.py:arrangeMenuItems()] - X > more retraction 2024-04-10 23:08:22,724 [menu.py:arrangeMenuItems()] - X > more power 2024-04-10 23:08:22,727 [menu.py:arrangeMenuItems()] - X > more camera 2024-04-10 23:08:22,732 [menu.py:arrangeMenuItems()] - X > more input_shaper 2024-04-10 23:08:22,739 [menu.py:arrangeMenuItems()] - X > more spoolman 2024-04-10 23:08:23,169 [screen.py:_menu_go_back()] - #### Menu go back 2024-04-10 23:08:23,185 [screen.py:attach_panel()] - Current panel hierarchy: main_menu 2024-04-10 23:08:26,999 [screen.py:_load_panel()] - Loading panel: gcode_macros 2024-04-10 23:08:27,032 [screen.py:attach_panel()] - Current panel hierarchy: main_menu > gcode_macros 2024-04-10 23:08:28,453 [screen.py:_menu_go_back()] - #### Menu go back 2024-04-10 23:08:28,483 [screen.py:attach_panel()] - Current panel hierarchy: main_menu

alfrix commented 1 month ago

the issue you are having is not really a bug based on the coordinates your config should be screw_positions: bl, br, fm the reason is that is the convention for Front-Left is 0,0 Back-Right Max-X and Max-Y.

the display would need to be then rotated using screw rotation but, you are right there is no invert support. inversion based on config could be the used to rotate the interface visually so to me this would be a FR of support inversion to show the bed screws (and probably mesh)

Furthermore i have researched a little about this printer, and it seems that it homes front left (Steve-Builds YT), so all the coordinates and everything should work normally without any special inversion, i don't understand why you are using inverted Y

cneshi commented 1 month ago

The printhead does indeed home front left but the front left coordinates are 0,180(max y). The rear left is 0,0. As I mentioned, the whole system is upside down. Imagine a normal printer where the front left is 0,0 and flipping the bed using the back edge as the pivot. The left and right stay the same, but the front and back coordiates are inverted.