153 lines
6.1 KiB
INI
153 lines
6.1 KiB
INI
# Copyright (C) 2023 Justin Schuh <code@justinschuh.com>
|
|
#
|
|
# This file may be distributed under the terms of the GNU GPLv3 license.
|
|
|
|
|
|
[gcode_macro _km_print_status]
|
|
variable_last_status: 'none'
|
|
variable_status_stack: []
|
|
variable_command_list: {}
|
|
variable_status_list: [
|
|
'ready', # Printer is ready to receive a job
|
|
'filament_load', # Loading filament
|
|
'filament_unload', # Unloading filament
|
|
'bed_heating', # Waiting for the bed to reach target
|
|
'chamber_heating', # Waiting for the chamber to reach target
|
|
'homing', # Homing any axis
|
|
'leveling_gantry', # Performing quad gantry-leveling
|
|
'calibrating_z', # Performing z-tilt adjustment
|
|
'meshing', # Calibrating a bed mesh
|
|
'extruder_heating', # Waiting for the extruder to reach target
|
|
'purging', # Printing purge line
|
|
'printing', # Actively printing
|
|
'pausing', # Print is paused
|
|
'cancelling', # Print is being cancelled
|
|
'completing', # Print completed
|
|
]
|
|
gcode:
|
|
{% set ACTION = params.ACTION|trim|upper %}
|
|
{% set STATUS = params.STATUS|default("")|trim|lower %}
|
|
|
|
# Add a status handler.
|
|
{% if ACTION == "ADD_EVENT" %}
|
|
{% set COMMAND = params.COMMAND %}
|
|
{% set ARGS = params.ARGS|default(0)|int != 0 %}
|
|
{% set TYPE = params.TYPE|default('ENTER')|trim|upper %}
|
|
{% set WHEN = params.WHEN|default('PRINTING')|trim|upper %}
|
|
{% set FILTER_ENTER =
|
|
(params.FILTER_ENTER|default("")|trim|lower).split(',')|
|
|
select()|unique|list %}
|
|
{% set FILTER_LEAVE =
|
|
(params.FILTER_LEAVE|default("")|trim|lower).split(',')|
|
|
select()|unique|list %}
|
|
|
|
{% set STATUSES = STATUS.split(',')|map('trim')|list %}
|
|
{% for s in (STATUSES if STATUSES[0] != 'all' else status_list) %}
|
|
{% if not s in command_list %}
|
|
{% set dummy = command_list.__setitem__(s,[]) %}
|
|
{% endif %}
|
|
{% set dummy = command_list[s].append({'cmd':COMMAND, 'args':ARGS,
|
|
'type':TYPE, 'when':WHEN,
|
|
'filt_e':FILTER_ENTER,
|
|
'filt_l':FILTER_LEAVE}) %}
|
|
{% endfor %}
|
|
|
|
# Change the current status.
|
|
{% elif ACTION == "CHANGE" %}
|
|
{% if params.RESET_STACK|default(0)|int %}
|
|
{% for dummy in range(status_stack|length) %}
|
|
{% set dummy = status_stack.pop() %}
|
|
{% endfor %}
|
|
# TODO: Once python 3 is required, switch the for loop above to this:
|
|
#{% set dummy = status_stack.clear() %}
|
|
{% elif STATUS == "pop_status" %}
|
|
{% set STATUS = (status_stack|default(['ready'], True)).pop() %}
|
|
{% endif %}
|
|
|
|
{% if STATUS not in status_list %}
|
|
{action_raise_error("Status '%s' not valid."|format(STATUS))}
|
|
{% endif %}
|
|
|
|
{% if STATUS != last_status %}
|
|
{% set is_printing =
|
|
printer["gcode_macro print_start_set"].print.PRINT_START_PHASE|
|
|
default("")|length != 0 %}
|
|
{% set print_states = ('ALWAYS', 'PRINTING' if is_printing else 'IDLE') %}
|
|
# Process commands for the state we're leaving first.
|
|
{% for c in command_list[last_status]|default([]) %}
|
|
{% if c.type in ('BOTH','LEAVE') and c.when in print_states and
|
|
(not c.filt_l or STATUS in c.filt_l) %}
|
|
M400
|
|
{c.cmd}{% if c.args %} TYPE=LEAVE WHEN={print_states[1]
|
|
} LAST_STATUS={last_status} NEXT_STATUS={STATUS}{% endif %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
# Process commands for the state we're entering last.
|
|
{% for c in command_list[STATUS]|default([]) %}
|
|
{% if c.type in ('BOTH','ENTER') and c.when in print_states and
|
|
(not c.filt_e or STATUS in c.filt_e) %}
|
|
M400
|
|
{c.cmd}{% if c.args %} TYPE=ENTER WHEN={print_states[1]
|
|
} LAST_STATUS={last_status} NEXT_STATUS={STATUS}{% endif %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
SET_GCODE_VARIABLE MACRO=_km_print_status VARIABLE=last_status VALUE="'{
|
|
STATUS}'"
|
|
{% endif %}
|
|
|
|
# Push the current status onto the stack.
|
|
{% elif ACTION == "PUSH_STATUS" %}
|
|
{% set dummy = status_stack.append(last_status) %}
|
|
|
|
# Illegal operation.
|
|
{% else %}
|
|
{action_raise_error("Action '%s' not valid."|format(ACTION))}
|
|
{% endif %}
|
|
|
|
[gcode_macro gcode_on_print_status]
|
|
description: Adds a gcode command for a status event.
|
|
Usage: GCODE_ON_PRINT_STATUS STATUS=<status> COMMAND=<gcode> [ARGS=<1|0>]
|
|
[WHEN=<PRINTING|IDLE|ALWAYS>]
|
|
[TYPE=<ENTER|LEAVE|BOTH>]
|
|
[FILTER_ENTER=<status list>]
|
|
[FILTER_LEAVE=<status list>]
|
|
gcode:
|
|
{% set STATUS = (params.STATUS|lower).split(',')|map('trim')|list %}
|
|
{% set TYPE = params.TYPE|default('ENTER')|trim|upper %}
|
|
{% set WHEN = params.WHEN|default('PRINTING')|trim|upper %}
|
|
{% set FILTER_ENTER =
|
|
(params.FILTER_ENTER|default("")|trim|lower).split(',')|select()|list %}
|
|
{% set FILTER_LEAVE =
|
|
(params.FILTER_LEAVE|default("")|trim|lower).split(',')|select()|list %}
|
|
|
|
# Error checking
|
|
{% set status_list = printer["gcode_macro _km_print_status"].status_list %}
|
|
{% for s in STATUS %}
|
|
{% if not (s in status_list or s == 'all' and STATUS|length == 1) %}
|
|
{action_raise_error("STATUS parameter '%s' not valid."|format(s))}
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% if TYPE not in ('ENTER', 'LEAVE', 'BOTH') %}
|
|
{action_raise_error("TYPE paramater '%s' not valid."|format(TYPE))}
|
|
{% elif WHEN not in ('PRINTING', 'IDLE', 'ALWAYS') %}
|
|
{action_raise_error("WHEN parameter '%s' not valid."|format(WHEN))}
|
|
{% elif TYPE == 'ENTER' and FILTER_LEAVE %}
|
|
{action_raise_error("FILTER_LEAVE not valid with TYPE=ENTER.")}
|
|
{% elif TYPE == 'LEAVE' and FILTER_ENTER %}
|
|
{action_raise_error("FILTER_ENTER not valid with TYPE=LEAVE.")}
|
|
{% endif %}
|
|
{% for f in FILTER_ENTER %}
|
|
{% if f not in status_list %}
|
|
{action_raise_error("FILTER_ENTER parameter '%s' not valid."|format(f))}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% for f in FILTER_LEAVE %}
|
|
{% if f not in status_list %}
|
|
{action_raise_error("FILTER_LEAVE parameter '%s' not valid."|format(f))}
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
# Run the command.
|
|
_KM_PRINT_STATUS ACTION=ADD_EVENT {rawparams}
|