Skip to content

Commit

Permalink
Merge pull request #224 from stereotech/STEAPP-841
Browse files Browse the repository at this point in the history
STEAPP-800, STEAPP-841, STEAPP-842: added the wizard modules.
  • Loading branch information
frylock34 authored Dec 29, 2023
2 parents f63e26c + e16d563 commit 7aaf01e
Show file tree
Hide file tree
Showing 13 changed files with 810 additions and 0 deletions.
2 changes: 2 additions & 0 deletions HTE530-5-4-22.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ path: /home/ste/uploads
[include stereotech_config/common/variables.cfg]
[include stereotech_config/common/diagnostics.cfg]

[include stereotech_config/wizards/wizards.cfg]

[gcode_macro CONSTANTS]
description: Holds printer constants
variable_probe_a_horizontal: 159, 246.5, 40
Expand Down
11 changes: 11 additions & 0 deletions docs/stereotech/error_list_guide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ config:
2047: auto_wcs: improperly formatted entry for point %s
2048: The parameter value is out of range, param=%smm max=%smm, min=0.0mm. Check params.
2049: Large difference between two values (x1-x2 or y1-y2), maximum difference=%smm. Check the parameters.
2050: No module named %s, error: %s
2051: Unknown wizard variable '%s'
2052: Unable to parse '%s' as a literal: %s
2053: Unknown step: '%s'
2054: Macro %s called recursively
2055: Failure set value:%s to variable:%s in the slider %s
2056: The selected item %s not in the items %s
2057: error setting the value:%s to move the axis, the value is out of range
2058: error moved the axis:%s, the axis not availability
2059: Macro %s called recursively
2060: The button '%s' does not exist

перефирия(mcu):
301: Timeout on wait for '%s' response
Expand Down
10 changes: 10 additions & 0 deletions klippy/extras/wizard/__init__.py
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))
100 changes: 100 additions & 0 deletions klippy/extras/wizard/wizard.py
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)
67 changes: 67 additions & 0 deletions klippy/extras/wizard/wizard_step.py
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)
46 changes: 46 additions & 0 deletions klippy/extras/wizard/wizard_step_button.py
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)
64 changes: 64 additions & 0 deletions klippy/extras/wizard/wizard_step_jog.py
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)
48 changes: 48 additions & 0 deletions klippy/extras/wizard/wizard_step_selector.py
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)
Loading

0 comments on commit 7aaf01e

Please sign in to comment.