diff --git a/docs/stereotech/error_list_guide.txt b/docs/stereotech/error_list_guide.txt index ef1eadc4212d..3d9f864f967d 100644 --- a/docs/stereotech/error_list_guide.txt +++ b/docs/stereotech/error_list_guide.txt @@ -33,6 +33,8 @@ config: 0023: Option '%s' in section '%s' must be above %s 0024: Option '%s' in section '%s' must be below %s 0025: Unable to load module '%s' + 0026: do not parse .json file, error %s + 0027: file with data not exist печать/кинематика/движение: 101: Error loading kinematics @@ -123,6 +125,8 @@ config: 2058: error moved the axis:%s, the axis not availability 2059: Macro %s called recursively 2060: The button '%s' does not exist + 2061: Failure set value to step, value out of the range[0-%s] + 2062: the key does not exist - %s, check the key перефирия(mcu): 301: Timeout on wait for '%s' response diff --git a/docs/stereotech/guide_config/wizards.md b/docs/stereotech/guide_config/wizards.md new file mode 100644 index 000000000000..335b6871aee2 --- /dev/null +++ b/docs/stereotech/guide_config/wizards.md @@ -0,0 +1,334 @@ +# [wizard] + +This object creates a manager that specifies all the steps that will be performed during execution. + +## configure + +``` +[wizard ] +image: /path/to/image/wizard/ + path to wizard image +type: 3d, 5d, any + type the modules supported this wizard +steps: step_1, step_2 + list the all steps for current wizard will be used +variable_: 1 +variable_: 2 + the wizard variables +``` + +## status + +``` +{'current_step': current wizard_step, +'enabled': 1/0, +'error': error_string, +'variables': variables, +'name': , +'steps': steps, +'type': type} +``` + +## commands + +#### SET_WIZARD_ENABLE + +`SET_WIZARD_ENABLE WIZARD= ENABLE=<1/0> ERROR=`: This command using for change the wizard state to the enable or disable. If need can set the error message. + +#### RESET_WIZARD + +`RESET_WIZARD WIZARD=`: The command reset current step to first and set set the wizard to the disabled. + +#### SET_WIZARD_STEP + +`SET_WIZARD_STEP WIZARD=: Set the step to wizard. + +#### SET_WIZARD_VARIABLE + +`SET_WIZARD_STEP WIZARD=`: Set the value to the wizard variables + +# [wizard_step] + +This is the base object that implements the template for creating the rest of the wizard steps. + +## configure + +``` +[wizard_step ] +image: path/to/image/wizard/ + path to wizard_step image +landscape: false + set True if this wizard_step can supported horizontal rendering +description: description_string + description for this wizard_step, this description the client will be rendered +warning: warning_string + warning msg for this wizard_step, this msg the client will be rendered +countdown: 0 + time until the end of the wizard +info: info_string + info about +placeholder: + placeholder component name +action_gcode: + write gcode which will be running if send the cmd [EXECUTE_WIZARD_STEP] +cancel_gcode: + write gcode which will be running if send the cmd [CANCEL_WIZARD_STEP] +``` + +## status + +``` +{'loading':loading, +'placeholder': placeholder} +``` + +## commands + +#### EXECUTE_WIZARD_STEP + +`EXECUTE_WIZARD_STEP WIZARD= STEP=`: Run gcode in the 'action_gcode' option + +#### CANCEL_WIZARD_STEP + +`CANCEL_WIZARD_STEP WIZARD= STEP=`: Run gcode in the 'cancel_gcode' option + +#### WIZARD_STEP_LOADING_STATE + +`WIZARD_STEP_LOADING_STATE WIZARD= STEP= ENABLE=<1/0>`: Change state for show the placeholder, enable/disable loading state. + +# [wizard_step_wizards] + +this step allows you to display all the managers that can be performed in this step. (step to select a manager) + +## configure + +``` +[wizard_step_wizards ] +! Note all options of the [wizard_step] object are supported +wizards: wizard1, wizard2 + list the all wizards for current step +``` + +## status + +such as [wizard_step] + +## commands + +! Note all cmd of the [wizard_step] object are supported + +# [wizard_step_tree] + +step for support component the data-selector (material-selector), which send json to client and client can rendering items + +## configure + +``` +[wizard_step_tree ] +! Note all options of the [wizard_step] object are supported +tree_file_path: ./path/to/data.json + path to data.json +depth: 3 + depth tree, for client can rendering items +types: manufacturer, series, name + name for everyone node, for client can rendering items +``` + +## status + +``` +{ + 'tree': tree, + 'selected': selected, + 'value': value +} + ``` + +## commands + +! Note all cmd of the [wizard_step] object are supported + +#### WIZARD_STEP_TREE + +`WIZARD_STEP_TREE WIZARD= STEP=STEP_TREE_1 KEY=pla`: select key from tree for set the value + +# [wizard_step_slider] + +Step for support component slider. You can specify the required number of sliders for which this object will change its value and interact with the client. Note: by the number of sliders, the client understands how much to draw + +## configure + +``` +[wizard_step_slider ] +! Note all options of the [wizard_step] object are supported +slider__min: 0 +slider__max: 100 +slider__step: 1 +slider__default: 20 + slider data for used to klipper and for for client can rendering it. Can set more sliders + +... + +``` + +## status + +``` +{ + : current_value, + : current_value, + ... +} + ``` + +## commands + +! Note all cmd of the [wizard_step] object are supported + +#### WIZARD_STEP_TREE + +`WIZARD_STEP_SLIDER WIZARD= STEP= SLIDER= VALUE=`: update the value for the selected slider.. + +# [wizard_step_selector] + +Step for support component selector. + +## configure + +``` +[wizard_step_selector ] +! Note all options of the [wizard_step] object are supported +items: , , ... + list items which can select, client get info from this row for rendering items. You can specify the required number of item +select_gcode: + write gcode which will be running if send the cmd [WIZARD_STEP_SELECT] +... + +``` + +## status + +``` +{ + 'selected': +} + ``` + +## commands + +! Note all cmd of the [wizard_step] object are supported + +#### WIZARD_STEP_SELECT + +`WIZARD_STEP_SELECT WIZARD= STEP= ITEM=`: Run gcode in the 'select_gcode' section. + +# [wizard_step_nozzle_offset] + +This step is used for the nozzle_offset manager, it specifies all the necessary data for rendering and operation of the klipper application + +## configure + +``` +[wizard_step_selector ] +! Note all options of the [wizard_step] object are supported +steps: 15 + the number of steps so that the application can work with this data and the client can draw it +default_step: 7 + the step number so that the application can work with this data and the client can draw it +step_value: 0.1 + the step value so that the client can work with this data +min_value: -0.7 + the minimal value so that the client can work with this data +``` + +## status + +``` +{ + 'step_x': step_x, + 'step_y': step_y, +} + ``` + +## commands + +! Note all cmd of the [wizard_step] object are supported + +#### WIZARD_STEP_NOZZLE_OFFSET + +`WIZARD_STEP_NOZZLE_OFFSET WIZARD= STEP= STEP_X= STEP_Y=`: set current step for axis X or Y. This command is used to move along the calibration ruler (vernier scale) + +# [wizard_step_jog] + +Using this step, you can control the axes of the printer, as well as the data from this step is used by the client for rendering + +## configure + +``` +[wizard_step_jog ] +! Note all options of the [wizard_step] object are supported + +axes: x, y, z, a, c + axes that can be controlled. The client uses this information to display +steps: 0.1, 1, 10, 20 + values for steps, client uses this information to display +default_step: 10 + the default value with which movements will occur for a given axis +jog_gcode: + write gcode which will be running if send the cmd [WIZARD_STEP_JOG] + +``` + +## status + +``` +{ + 'loading':loading, + 'placeholder': placeholder + 'step': default_step + } +``` + +## commands + +! Note all cmd of the [wizard_step] object are supported + +#### WIZARD_STEP_SET_STEP + +`WIZARD_STEP_SET_STEP WIZARD= STEP= VALUE=`: Set step for moving the axis + +#### WIZARD_STEP_JOG + +`WIZARD_STEP_JOG WIZARD= STEP= AXIS= DIRECTION=<1/0>`: Perform axis movement + +# [wizard_step_button] + +A step to port the button component, with which you can respond to button clicks. You can specify the required number of buttons. Data on the name and number of buttons are read from the configuration. + +## configure + +``` +[wizard_step_button ] +! Note all options of the [wizard_step] object are supported + +button__gcode: + write gcode which will be running if send the cmd [WIZARD_STEP_BUTTON] +... +``` + +## status + +``` +{ + 'loading':loading, + 'placeholder': placeholder + } +``` + +## commands + +! Note all cmd of the [wizard_step] object are supported + +#### WIZARD_STEP_BUTTON + +`WIZARD_STEP_BUTTON WIZARD= STEP= BUTTON=`: Run gcode in the 'button_%s_gcode' section diff --git a/klippy/extras/wizard/wizard_step.py b/klippy/extras/wizard/wizard_step.py index 0d37fa8d6b73..1fe79dd0e526 100644 --- a/klippy/extras/wizard/wizard_step.py +++ b/klippy/extras/wizard/wizard_step.py @@ -7,6 +7,7 @@ def __init__(self, config): section_name = config.get_name().split() self.name = section_name[1].upper() self.in_script = False + self.loading = False # load objects self.printer = printer = config.get_printer() self.gcode_macro = printer.load_object(config, 'gcode_macro') @@ -19,12 +20,16 @@ def __init__(self, config): self.warning = config.get('warning', '') self.info = config.get('info', '') self.countdown = config.getint('countdown', 0) + self.placeholder = config.get('placeholder', '') # 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("WIZARD_STEP_LOADING_STATE", 'STEP', + self.name, self.cmd_WIZARD_STEP_LOADING_STATE, + desc=self.cmd_WIZARD_STEP_LOADING_STATE_help) self.gcode.register_mux_command("EXECUTE_WIZARD_STEP", 'STEP', self.name, self.cmd_EXECUTE_WIZARD_STEP, desc=self.cmd_EXECUTE_WIZARD_STEP_help) @@ -32,6 +37,12 @@ def __init__(self, config): self.name, self.cmd_CANCEL_WIZARD_STEP, desc=self.cmd_CANCEL_WIZARD_STEP_help) + cmd_WIZARD_STEP_LOADING_STATE_help = "Change state for show the placeholder" + + def cmd_WIZARD_STEP_LOADING_STATE(self, gcmd): + state = gcmd.get_int('ENABLE', 0) + self.loading = True if state else False + cmd_EXECUTE_WIZARD_STEP_help = "Run gcode in the 'action_gcode' option" def cmd_EXECUTE_WIZARD_STEP(self, gcmd): @@ -62,6 +73,10 @@ def cmd(self, gcmd, gcode): finally: self.in_script = False + def get_status(self, eventtime): + return { + 'loading': self.loading, + 'placeholder': self.placeholder} def load_config_prefix(config): return WizardStep(config) diff --git a/klippy/extras/wizard/wizard_step_button.py b/klippy/extras/wizard/wizard_step_button.py index 6c76416fe19c..d6b938c2a0c7 100644 --- a/klippy/extras/wizard/wizard_step_button.py +++ b/klippy/extras/wizard/wizard_step_button.py @@ -41,6 +41,10 @@ def cmd_WIZARD_STEP_BUTTON(self, gcmd): finally: self.in_script = False + def get_status(self, eventtime): + status = WizardStep.get_status(self, eventtime) + return status + def load_config_prefix(config): return WizardStepButton(config) diff --git a/klippy/extras/wizard/wizard_step_jog.py b/klippy/extras/wizard/wizard_step_jog.py index 89498fcf3055..ae74364e9cca 100644 --- a/klippy/extras/wizard/wizard_step_jog.py +++ b/klippy/extras/wizard/wizard_step_jog.py @@ -57,7 +57,9 @@ def cmd_WIZARD_STEP_JOG(self, gcmd): self.in_script = False def get_status(self, eventtime): - return {'step': self.default_step} + status = WizardStep.get_status(self, eventtime) + status.update({'step': self.default_step}) + return status def load_config_prefix(config): diff --git a/klippy/extras/wizard/wizard_step_nozzle_offset.py b/klippy/extras/wizard/wizard_step_nozzle_offset.py new file mode 100644 index 000000000000..5746c20a9a75 --- /dev/null +++ b/klippy/extras/wizard/wizard_step_nozzle_offset.py @@ -0,0 +1,35 @@ +from wizard_step import WizardStep + + +class WizardStepNozzleOffset(WizardStep): + def __init__(self, config): + WizardStep.__init__(self, config) + # get options from config + self.step_x = self.step_y = config.getint('default_step', 7) + self.quantity_steps = config.getint('steps', 15) + self.step_value = config.getfloat('step_value', 0.1) + self.min_value = -config.getfloat('min_value', -0.7) + self.gcode.register_mux_command("WIZARD_STEP_NOZZLE_OFFSET", 'STEP', + self.name, self.cmd_WIZARD_STEP_NOZZLE_OFFSET, + desc=self.cmd_WIZARD_STEP_NOZZLE_OFFSET_help) + + cmd_WIZARD_STEP_NOZZLE_OFFSET_help = "update value to the slider data" + + def cmd_WIZARD_STEP_NOZZLE_OFFSET(self, gcmd): + step_x = gcmd.get_int('STEP_X', self.step_x) + step_y = gcmd.get_int('STEP_Y', self.step_y) + if min(step_x, step_y) < 0 or max(step_x, step_y) > self.quantity_steps: + raise gcmd.error( + "2060: Failure set value to step, value out of the range[0-%s]" % (self.quantity_steps)) + self.step_x = step_x + self.step_y = step_y + + def get_status(self, eventtime): + return { + 'step_x': self.step_x, + 'step_y': self.step_y, + } + + +def load_config_prefix(config): + return WizardStepNozzleOffset(config) diff --git a/klippy/extras/wizard/wizard_step_tree.py b/klippy/extras/wizard/wizard_step_tree.py new file mode 100644 index 000000000000..d54a17e7de09 --- /dev/null +++ b/klippy/extras/wizard/wizard_step_tree.py @@ -0,0 +1,71 @@ +from wizard_step import WizardStep +import os +import json + + +class WizardStepTree(WizardStep): + def __init__(self, config): + WizardStep.__init__(self, config) + self.tree = [] + self.selected = '' + self.value = 0 + config_dir_name = 'config' + # get options from config + self.depth = config.getint('depth', 1) + self.types = config.getlist('types', []) + json_path = config.get('tree_file_path', '') + # read json file + filename = self.printer.get_start_args()['config_file'] + if 'printer.cfg' not in filename.split('/')[-1]: + config_dir_name = 'stereotech_config' + abs_json_path = os.path.join(os.path.abspath('.'), config_dir_name, json_path) + if os.path.isfile(abs_json_path): + try: + with open(abs_json_path, 'r') as f: + self.tree = json.load(f) + except Exception as e: + raise config.error("0026: do not parse .json file, error %s" % e) + else: + raise config.error("0026: file with data not exist") + # register commands + self.gcode.register_mux_command("WIZARD_STEP_TREE", 'STEP', + self.name, self.cmd_WIZARD_STEP_TREE, + desc=self.cmd_WIZARD_STEP_TREE_help) + + cmd_WIZARD_STEP_TREE_help = "select key from tree for set the value" + + def cmd_WIZARD_STEP_TREE(self, gcmd): + selected = gcmd.get('KEY') + value = self.get_value(self.tree, selected) + if value: + self.value = value + self.selected = selected + else: + raise gcmd.error( + "2062: the key does not exist - %s, check the key" % (selected,)) + + def get_value(self, node, key): + if isinstance(node, list): + for item in node: + value = self.get_value(item, key) + if isinstance(value, int): + return value + elif isinstance(node, dict): + if key in node.values(): + return node['value'] + elif 'children' in node: + for child in node['children']: + value = self.get_value(child, key) + if isinstance(value, int): + return value + + def get_status(self, eventtime): + return { + 'tree': self.tree, + 'selected': self.selected, + 'value': self.value + } + + +def load_config_prefix(config): + return WizardStepTree(config) diff --git a/stereotech_config/wizards/data/materials.json b/stereotech_config/wizards/data/materials.json new file mode 100644 index 000000000000..c376353f11f2 --- /dev/null +++ b/stereotech_config/wizards/data/materials.json @@ -0,0 +1,51 @@ +[ + { + "key": "stereotech", + "children": [ + { + "key": "proto", + "children": [ + { + "key": "pla", + "value": 205 + }, + { + "key": "pva", + "value": 206 + } + ] + } + ] + }, + { + "key": "stereotech1", + "children": [ + { + "key": "proto1", + "children": [ + { + "key": "pla1", + "value": 207 + }, + { + "key": "pva1", + "value": 208 + } + ] + }, + { + "key": "proto2", + "children": [ + { + "key": "pla2", + "value": 209 + }, + { + "key": "pva2", + "value": 210 + } + ] + } + ] + } +] \ No newline at end of file diff --git a/stereotech_config/wizards/wizards.cfg b/stereotech_config/wizards/wizards.cfg index 50f03b071f3f..21f878c6c311 100644 --- a/stereotech_config/wizards/wizards.cfg +++ b/stereotech_config/wizards/wizards.cfg @@ -11,8 +11,8 @@ # wizard_step_button # CANCEL_WIZARD_STEP WIZARD=CALIBRATE STEP=STEP_BUTTON_1 # EXECUTE_WIZARD_STEP WIZARD=CALIBRATE STEP=STEP_BUTTON_1 -# WIZARD_STEP_BUTTON WIZARD=CALIBRATE STEP=STEP_BUTTON_1 BUTTON=button_button_1_gcode -# WIZARD_STEP_BUTTON WIZARD=CALIBRATE STEP=STEP_BUTTON_1 BUTTON=button_button2_gcode +# WIZARD_STEP_BUTTON WIZARD=CALIBRATE STEP=STEP_BUTTON_1 BUTTON=button_1 +# WIZARD_STEP_BUTTON WIZARD=CALIBRATE STEP=STEP_BUTTON_1 BUTTON=button2 # wizard_step_wizards # CANCEL_WIZARD_STEP WIZARD=CALIBRATE STEP=STEP_WIZARDS_1 @@ -35,10 +35,20 @@ # WIZARD_STEP_JOG WIZARD=CALIBRATE STEP=STEP_JOG_1 AXIS=z DIRECTION=0 # WIZARD_STEP_SET_STEP WIZARD=CALIBRATE STEP=STEP_JOG_1 VALUE=20 +# wizard_step_nozzle_offset +# CANCEL_WIZARD_STEP WIZARD=CALIBRATE STEP=STEP_NOZZLE_OFFSET_1 +# EXECUTE_WIZARD_STEP WIZARD=CALIBRATE STEP=STEP_NOZZLE_OFFSET_1 +# WIZARD_STEP_NOZZLE_OFFSET WIZARD=CALIBRATE STEP=STEP_NOZZLE_OFFSET_1 STEP_X=9 STEP_Y=10 + +# wizard_step_tree +# CANCEL_WIZARD_STEP WIZARD=CALIBRATE STEP=STEP_TREE_1 +# EXECUTE_WIZARD_STEP WIZARD=CALIBRATE STEP=STEP_TREE_1 +# WIZARD_STEP_TREE WIZARD=CALIBRATE STEP=STEP_TREE_1 KEY=pla + [wizard CALIBRATE] image: path/to/image/wizard/CALIBRATE type: 3d, 5d, any -steps: STEP_0, STEP_BUTTON_1, STEP_WIZARDS_1, STEP_SELECTOR_1, STEP_SLIDER_1, STEP_JOG_1 +steps: STEP_0, STEP_BUTTON_1, STEP_WIZARDS_1, STEP_SELECTOR_1, STEP_SLIDER_1, STEP_JOG_1, STEP_NOZZLE_OFFSET_1 variable_a: 1 variable_b: 2 @@ -49,9 +59,11 @@ description: description STEP_0 warning: warning STEP_0 countdown: 10 info: info about STSTEP_0 +placeholder: wizard-step-preheat action_gcode: SET_WIZARD_STEP WIZARD={wizard.name} STEP={wizard.wizard_step_name} {action_respond_info('-------------------start STEP_0')} + WIZARD_STEP_LOADING_STATE WIZARD={wizard.name} STEP=STEP_0 ENABLE=1 cancel_gcode: {action_respond_info('------------------CANCEL STEP_0')} RESET_WIZARD WIZARD={wizard.name} @@ -63,12 +75,14 @@ description: description STEP_BUTTON_1 warning: warning STEP_BUTTON_1 countdown: 20 info: info about STEP_BUTTON_1 +placeholder: wizard-step-preheat button_button_1_gcode: {action_respond_info('-------------------button_button_1_gcode')} button_button2_gcode: {action_respond_info('-------------------button_button2_gcode')} action_gcode: {action_respond_info('-------------------action_gcode STEP_BUTTON_1')} + WIZARD_STEP_LOADING_STATE WIZARD={wizard.name} STEP=STEP_BUTTON_1 ENABLE=1 SET_WIZARD_STEP WIZARD={wizard.name} STEP={wizard.wizard_step_name} cancel_gcode: {action_respond_info('------------------cancel_gcode STEP_BUTTON_1')} @@ -140,35 +154,48 @@ info: info about STEP_JOG_1 axes: x, y, z, a, c steps: 0.1, 1, 10, 20 default_step: 10 +placeholder: wizard-step-preheat jog_gcode: {action_respond_info('-------------------jog_gcode STEP_JOG_1 (G1 %s%s, direction=%s)' % (axis|upper, step, direction))} action_gcode: {action_respond_info('-------------------action_gcode STEP_JOG_1')} SET_WIZARD_ENABLE WIZARD=CALIBRATE ENABLE=1 ERROR=error_message SET_WIZARD_STEP WIZARD={wizard.name} STEP={wizard.wizard_step_name} + WIZARD_STEP_LOADING_STATE WIZARD={wizard.name} STEP=STEP_JOG_1 ENABLE=1 cancel_gcode: {action_respond_info('------------------cancel_gcode STEP_JOG_1')} RESET_WIZARD WIZARD={wizard.name} - # HOME_POSITION ABORT=1 +[wizard_step_nozzle_offset STEP_NOZZLE_OFFSET_1] +image: path/to/image/wizard/STEP_NOZZLE_OFFSET_1 +landscape: false +description: description STEP_NOZZLE_OFFSET_1 +warning: warning STEP_NOZZLE_OFFSET_1 +countdown: 20 +info: info about STEP_NOZZLE_OFFSET_1 +steps: 15 +default_step: 7 +step_value: 0.1 +min_value: -0.7 +action_gcode: + {action_respond_info('-------------------action_gcode %s' % wizard.wizard_step_name)} + SET_WIZARD_ENABLE WIZARD={wizard.name} ENABLE=1 ERROR=error_message + SET_WIZARD_STEP WIZARD={wizard.name} STEP={wizard.wizard_step_name} +cancel_gcode: + {action_respond_info('------------------cancel_gcode %s' % wizard.wizard_step_name)} + RESET_WIZARD WIZARD={wizard.name} -# ???????????????????????????????? - -# [wizard_step_material-selector material-selector_1] -# image: path/to/image/wizard/STEP_JOG_1 -# landscape: false -# description: description STEP_JOG_1 -# warning: warning STEP_JOG_1 -# countdown: 20 -# info: info about STEP_JOG_1 -# axes: x, y, z, a, c -# steps: 0.1, 1, 10, 20 -# default_step: 10 -# jog_gcode: -# {action_respond_info('-------------------jog_gcode STEP_JOG_1 axis=%s, step=%s,' % (axis, step))} -# action_gcode: -# {action_respond_info('-------------------start STEP_JOG_1')} -# cancel_gcode: -# {action_respond_info('------------------CANCEL STEP_JOG_1')} -# RESET_WIZARD WIZARD={wizard.name} -# # HOME_POSITION ABORT=1 \ No newline at end of file +[wizard_step_tree STEP_TREE_1] +# tree_file_path: /home/ste/klippy_dev/klipper/klippy/data/materials.json +tree_file_path: /home/ste/klippy_dev/klipper/stereotech_config/wizards/data/materials.json +depth: 3 # (глубина дерева) +# (типы на каждой глубине) +types: manufacturer, series, name +action_gcode: + {action_respond_info('-------------------action_gcode %s' % wizard.wizard_step_name)} + SET_WIZARD_ENABLE WIZARD={wizard.name} ENABLE=1 ERROR=error_message + SET_WIZARD_STEP WIZARD={wizard.name} STEP={wizard.wizard_step_name} + WIZARD_STEP_LOADING_STATE WIZARD={wizard.name} STEP={wizard.wizard_step_name} +cancel_gcode: + {action_respond_info('------------------cancel_gcode %s' % wizard.wizard_step_name)} + RESET_WIZARD WIZARD={wizard.name}