forked from Klipper3d/klipper
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #224 from stereotech/STEAPP-841
STEAPP-800, STEAPP-841, STEAPP-842: added the wizard modules.
- Loading branch information
Showing
13 changed files
with
810 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import importlib | ||
|
||
|
||
def load_config_prefix(config): | ||
mod_name = 'extras.wizard.' + config.get_name().split()[0] | ||
try: | ||
mod = importlib.import_module(mod_name) | ||
return mod.load_config_prefix(config) | ||
except Exception as e: | ||
raise Exception('2050: No module named %s, error: %s' % (mod_name, e)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import ast | ||
import json | ||
|
||
|
||
class Wizard: | ||
def __init__(self, config): | ||
if len(config.get_name().split()) > 2: | ||
raise config.error( | ||
"Name of section '%s' contains illegal whitespace" | ||
% (config.get_name())) | ||
self.name = config.get_name().split()[1] | ||
self.enabled = False | ||
self.error = '' | ||
self.variables = {} | ||
self._variables_bk = {} | ||
prefix = 'variable_' | ||
for option in config.get_prefix_options(prefix): | ||
try: | ||
literal = ast.literal_eval(config.get(option)) | ||
json.dumps(literal, separators=(',', ':')) | ||
self.variables[option[len(prefix):]] = literal | ||
self._variables_bk[option[len(prefix):]] = literal | ||
except (SyntaxError, TypeError, ValueError) as e: | ||
raise config.error( | ||
"Option '%s' in section '%s' is not a valid literal: %s" % ( | ||
option, config.get_name(), e)) | ||
# get options from config | ||
self.image = config.get('image', 'image_path') | ||
self.type = config.getlists('type', []) | ||
self.steps = config.getlists('steps', []) | ||
self.current_step = self.steps[0] | ||
# load objects | ||
self.printer = printer = config.get_printer() | ||
self.gcode = printer.lookup_object('gcode') | ||
# register commands | ||
self.gcode.register_mux_command("SET_WIZARD_VARIABLE", "WIZARD", | ||
self.name, self.cmd_SET_WIZARD_VARIABLE, | ||
desc=self.cmd_SET_WIZARD_VARIABLE_help) | ||
self.gcode.register_mux_command("SET_WIZARD_ENABLE", "WIZARD", | ||
self.name, self.cmd_SET_WIZARD_ENABLE, | ||
desc=self.cmd_SET_WIZARD_ENABLE_help) | ||
self.gcode.register_mux_command("SET_WIZARD_STEP", "WIZARD", | ||
self.name, self.cmd_SET_WIZARD_STEP, | ||
desc=self.cmd_SET_WIZARD_STEP_help) | ||
self.gcode.register_mux_command("RESET_WIZARD", "WIZARD", | ||
self.name, self.cmd_RESET_WIZARD, | ||
desc=self.cmd_RESET_WIZARD_help) | ||
|
||
def get_status(self, eventtime=None): | ||
return {'current_step': self.current_step, | ||
'enabled': self.enabled, | ||
'error': self.error, | ||
'variables': self.variables, | ||
'name': self.name, | ||
'steps': self.steps, | ||
'type': self.type} | ||
|
||
cmd_SET_WIZARD_VARIABLE_help = "Set the value of a wizard variable to wizard" | ||
|
||
def cmd_SET_WIZARD_VARIABLE(self, gcmd): | ||
variable = gcmd.get('VARIABLE') | ||
value = gcmd.get('VALUE') | ||
if variable not in self.variables: | ||
raise gcmd.error( | ||
"2051: Unknown wizard variable '%s'" % (variable,)) | ||
try: | ||
literal = ast.literal_eval(value) | ||
json.dumps(literal, separators=(',', ':')) | ||
except (SyntaxError, TypeError, ValueError) as e: | ||
raise gcmd.error("2052: Unable to parse '%s' as a literal: %s" % | ||
(value, e)) | ||
v = dict(self.variables) | ||
v[variable] = literal | ||
self.variables = v | ||
|
||
cmd_SET_WIZARD_ENABLE_help = "Set the enable to WIZARD" | ||
|
||
def cmd_SET_WIZARD_ENABLE(self, gcmd): | ||
self.enabled = True if gcmd.get_int('ENABLE', self.enabled) else False | ||
self.error = gcmd.get('ERROR', self.error) | ||
|
||
cmd_SET_WIZARD_STEP_help = "Set the step to WIZARD" | ||
|
||
def cmd_SET_WIZARD_STEP(self, gcmd): | ||
step = gcmd.get('STEP') | ||
if step not in self.steps: | ||
raise gcmd.error("2053: Unknown step: '%s'" % step) | ||
self.current_step = step | ||
|
||
cmd_RESET_WIZARD_help = "Reset state the wizard" | ||
|
||
def cmd_RESET_WIZARD(self, gcmd): | ||
self.error = '' | ||
self.enabled = False | ||
self.current_step = self.steps[0] | ||
self.variables = dict(self._variables_bk) | ||
|
||
|
||
def load_config_prefix(config): | ||
return Wizard(config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
class WizardStep: | ||
def __init__(self, config): | ||
if len(config.get_name().split()) > 2: | ||
raise config.error( | ||
"Name of section '%s' contains illegal whitespace" | ||
% (config.get_name())) | ||
section_name = config.get_name().split() | ||
self.name = section_name[1].upper() | ||
self.in_script = False | ||
# load objects | ||
self.printer = printer = config.get_printer() | ||
self.gcode_macro = printer.load_object(config, 'gcode_macro') | ||
self.gcode = printer.lookup_object('gcode') | ||
# get options from config | ||
self.cmd_desc = config.get("description", "G-Code wizard") | ||
self.image = config.get('image', 'image_path') | ||
self.landscape = config.getboolean('landscape', False) | ||
self.description = config.get('description', '') | ||
self.warning = config.get('warning', '') | ||
self.info = config.get('info', '') | ||
self.countdown = config.getint('countdown', 0) | ||
# create template | ||
self.template_action = self.gcode_macro.load_template( | ||
config, 'action_gcode') | ||
self.template_cancel = self.gcode_macro.load_template( | ||
config, 'cancel_gcode') | ||
# register gcode commands | ||
self.gcode.register_mux_command("EXECUTE_WIZARD_STEP", 'STEP', | ||
self.name, self.cmd_EXECUTE_WIZARD_STEP, | ||
desc=self.cmd_EXECUTE_WIZARD_STEP_help) | ||
self.gcode.register_mux_command("CANCEL_WIZARD_STEP", 'STEP', | ||
self.name, self.cmd_CANCEL_WIZARD_STEP, | ||
desc=self.cmd_CANCEL_WIZARD_STEP_help) | ||
|
||
cmd_EXECUTE_WIZARD_STEP_help = "Run gcode in the 'action_gcode' option" | ||
|
||
def cmd_EXECUTE_WIZARD_STEP(self, gcmd): | ||
self.cmd(gcmd=gcmd, gcode='action_gcode') | ||
|
||
cmd_CANCEL_WIZARD_STEP_help = "Run gcode in the 'cancel_gcode' option" | ||
|
||
def cmd_CANCEL_WIZARD_STEP(self, gcmd): | ||
self.cmd(gcmd=gcmd, gcode='cancel_gcode') | ||
|
||
def cmd(self, gcmd, gcode): | ||
if self.in_script: | ||
raise gcmd.error( | ||
"2054: Macro %s called recursively" % (self.name,)) | ||
wizard_name = gcmd.get('WIZARD').upper() | ||
wizard_obj = self.printer.lookup_object('wizard %s' % wizard_name) | ||
kwparams = self.template_action.create_template_context() | ||
kwparams['wizard'] = wizard_obj.get_status() | ||
kwparams['wizard'].update({'wizard_step_name': self.name}) | ||
kwparams['params'] = gcmd.get_command_parameters() | ||
kwparams['rawparams'] = gcmd.get_raw_command_parameters() | ||
self.in_script = True | ||
try: | ||
if gcode == 'action_gcode': | ||
self.template_action.run_gcode_from_command(kwparams) | ||
elif gcode == 'cancel_gcode': | ||
self.template_cancel.run_gcode_from_command(kwparams) | ||
finally: | ||
self.in_script = False | ||
|
||
|
||
def load_config_prefix(config): | ||
return WizardStep(config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from wizard_step import WizardStep | ||
|
||
|
||
class WizardStepButton(WizardStep): | ||
def __init__(self, config): | ||
WizardStep.__init__(self, config) | ||
# create template for buttons | ||
self.templates = {} | ||
options_name = config.get_prefix_options('button_') | ||
for option in options_name: | ||
template_button = self.gcode_macro.load_template( | ||
config, option) | ||
button_name = '_'.join(option.split('_')[1:-1]) | ||
self.templates.update({button_name: template_button}) | ||
# register commands | ||
self.gcode.register_mux_command("WIZARD_STEP_BUTTON", 'STEP', | ||
self.name, self.cmd_WIZARD_STEP_BUTTON, | ||
desc=self.cmd_WIZARD_STEP_BUTTON_help) | ||
|
||
cmd_WIZARD_STEP_BUTTON_help = "Run gcode in the 'button_%s_gcode' section" | ||
|
||
def cmd_WIZARD_STEP_BUTTON(self, gcmd): | ||
if self.in_script: | ||
raise gcmd.error( | ||
"2054: Macro %s called recursively" % (self.name,)) | ||
wizard_name = gcmd.get('WIZARD').upper() | ||
wizard_obj = self.printer.lookup_object('wizard %s' % wizard_name) | ||
button = gcmd.get('BUTTON', '').lower() | ||
template_button = self.templates.get(button, None) | ||
if template_button is None: | ||
raise gcmd.error( | ||
"2060: The button '%s' does not exist" % (button,)) | ||
kwparams = template_button.create_template_context() | ||
kwparams['wizard'] = wizard_obj.get_status() | ||
kwparams['wizard'].update({'wizard_step_name': self.name}) | ||
kwparams['params'] = gcmd.get_command_parameters() | ||
kwparams['rawparams'] = gcmd.get_raw_command_parameters() | ||
self.in_script = True | ||
try: | ||
template_button.run_gcode_from_command(kwparams) | ||
finally: | ||
self.in_script = False | ||
|
||
|
||
def load_config_prefix(config): | ||
return WizardStepButton(config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
from wizard_step import WizardStep | ||
|
||
|
||
class WizardStepJog(WizardStep): | ||
def __init__(self, config): | ||
WizardStep.__init__(self, config) | ||
# get options | ||
self.axes = config.getlists('axes', ['x', 'y', 'z']) | ||
self.steps = config.getfloatlist('steps') | ||
self.default_step = config.getfloat('default_step', 10) | ||
# create template | ||
self.template_jog = self.gcode_macro.load_template(config, 'jog_gcode') | ||
# register gcode commands | ||
self.gcode.register_mux_command("WIZARD_STEP_JOG", 'STEP', | ||
self.name, self.cmd_WIZARD_STEP_JOG, | ||
desc=self.cmd_WIZARD_STEP_JOG_help) | ||
self.gcode.register_mux_command("WIZARD_STEP_SET_STEP", 'STEP', | ||
self.name, self.cmd_WIZARD_STEP_SET_STEP, | ||
desc=self.cmd_WIZARD_STEP_SET_STEP_help) | ||
|
||
cmd_WIZARD_STEP_SET_STEP_help = "Set step for moving the axis" | ||
|
||
def cmd_WIZARD_STEP_SET_STEP(self, gcmd): | ||
value = gcmd.get_float('VALUE') | ||
if value not in self.steps: | ||
raise gcmd.error( | ||
"2057: error setting the value:%s to move the axis, the value is out of range" % (value,)) | ||
self.default_step = value | ||
|
||
cmd_WIZARD_STEP_JOG_help = "Perform axis movement" | ||
|
||
def cmd_WIZARD_STEP_JOG(self, gcmd): | ||
axis = gcmd.get('AXIS').lower() | ||
# get direction move, 1-positive, 0-negative moving | ||
direction = gcmd.get('DIRECTION', 1) | ||
if axis not in self.axes: | ||
raise gcmd.error( | ||
"2058: error moved the axis:%s, the axis not availability" % (axis,)) | ||
if self.in_script: | ||
raise gcmd.error( | ||
"2059: Macro %s called recursively" % (self.name,)) | ||
# update status to the wizard | ||
wizard_name = gcmd.get('WIZARD').upper() | ||
wizard_obj = self.printer.lookup_object('wizard %s' % wizard_name) | ||
kwparams = self.template_action.create_template_context() | ||
kwparams['wizard'] = wizard_obj.get_status() | ||
kwparams['wizard'].update({'wizard_step_name': self.name}) | ||
kwparams['params'] = gcmd.get_command_parameters() | ||
kwparams['rawparams'] = gcmd.get_raw_command_parameters() | ||
kwparams['axis'] = axis | ||
kwparams['step'] = self.default_step | ||
kwparams['direction'] = direction | ||
self.in_script = True | ||
try: | ||
self.template_jog.run_gcode_from_command(kwparams) | ||
finally: | ||
self.in_script = False | ||
|
||
def get_status(self, eventtime): | ||
return {'step': self.default_step} | ||
|
||
|
||
def load_config_prefix(config): | ||
return WizardStepJog(config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from wizard_step import WizardStep | ||
|
||
|
||
class WizardStepSelector(WizardStep): | ||
def __init__(self, config): | ||
WizardStep.__init__(self, config) | ||
self.selected = '' | ||
# get options | ||
self.items = config.getlists('items', []) | ||
# create template | ||
self.template = self.gcode_macro.load_template(config, 'select_gcode') | ||
# register commands | ||
self.gcode.register_mux_command("WIZARD_STEP_SELECT", 'STEP', | ||
self.name, self.cmd_WIZARD_STEP_SELECT, | ||
desc=self.cmd_WIZARD_STEP_SELECT_help) | ||
|
||
cmd_WIZARD_STEP_SELECT_help = "Run gcode in the 'select_gcode' section" | ||
|
||
def cmd_WIZARD_STEP_SELECT(self, gcmd): | ||
if self.in_script: | ||
raise gcmd.error( | ||
"2054: Macro %s called recursively" % (self.name,)) | ||
selected = gcmd.get('ITEM') | ||
if selected not in self.items: | ||
raise gcmd.error( | ||
"2056: The selected item %s not in the items %s" % (selected, self.items)) | ||
self.selected = selected | ||
wizard_name = gcmd.get('WIZARD').upper() | ||
wizard_obj = self.printer.lookup_object('wizard %s' % wizard_name) | ||
kwparams = self.template_action.create_template_context() | ||
kwparams['wizard'] = wizard_obj.get_status() | ||
kwparams['wizard'].update({'wizard_step_name': self.name}) | ||
kwparams['params'] = gcmd.get_command_parameters() | ||
kwparams['rawparams'] = gcmd.get_raw_command_parameters() | ||
kwparams['selected'] = self.selected | ||
self.in_script = True | ||
try: | ||
self.template.run_gcode_from_command(kwparams) | ||
finally: | ||
self.in_script = False | ||
|
||
def get_status(self, eventtime): | ||
return {'selected': self.selected | ||
} | ||
|
||
|
||
def load_config_prefix(config): | ||
return WizardStepSelector(config) |
Oops, something went wrong.