OctoPrint-Tentacles
import octoprint.printer
# Dictionary of actions that have been defined
# Key will be the action name, value will be a class object
ACTIONS = {}
# Return all actions
def get_actions():
return ACTIONS
# Return a single action with 'name' or None if action does not exist
def get_action(name):
if name in ACTIONS:
return ACTIONS[name]
else:
return None
# @tentacle_action(name)
# Define an action for a tentacle to execute
def tentacle_action(name):
def decorator_tentacle_action(action_func):
ACTIONS[name] = action_func
action_func.name = name
return action_func
return decorator_tentacle_action
# Extend BaseAction to define a new action
class BaseAction(object):
def __init__(self, *args, **kwargs):
pass
def configure(self, *args, **kwargs):
pass
def run(self):
pass
def _run(self):
self._running = True
self.run()
self._running = False
# Menu actions get the Tentacles class instance injected
class MenuAction(BaseAction):
def __init__(self, tentacles=None, *args, **kwargs):
self._tentacles = tentacles
@tentacle_action('menu_start')
class StartMenuAction(MenuAction):
def run(self):
self._tentacles._mode = self._tentacles._menu.start_menu(self._tentacles._mode)
@tentacle_action('menu_change')
class ChangeMenuAction(MenuAction):
def configure(self, opt=None, *args, **kwargs):
self._opt = opt
def run(self):
self._tentacles._menu.change_menu(self._opt)
@tentacle_action('menu_set')
class SetMenuAction(MenuAction):
def run(self):
self._tentacles._mode = self._tentacles._menu.set_menu()
# Printer actions get the _printer object injected
class PrinterAction(BaseAction):
def __init__(self, printer=None, *args, **kwargs):
self._printer = printer
@tentacle_action('home')
class HomeAction(PrinterAction):
def configure(self, axis=['x', 'y', 'z']):
self._axis = axis
def run(self):
self._printer.home(self._axis)
@tentacle_action('jog')
class JogAction(PrinterAction):
def configure(self, axis=None, speed=4500, relative=True):
self._axis = axis
self._speed = speed
self._relative = relative
def run(self):
self._printer.jog(self._axis, speed=self._speed, relative=self._relative)
@tentacle_action('jog-repeat')
class JogRepeatAction(octoprint.printer.PrinterCallback, JogAction):
def configure(self, axis={}, speed=4500, relative=True):
self._axis = axis
self._speed = speed
self._relative = relative
self._jog = f"G0 { ' '.join([f'{x.upper()}{d}' for x, d in self._axis.items() ])} F{self._speed}"
self._max_repeat = 5
self._running = False
def _run(self):
print('Registering PrinterCallback')
self._printer.register_callback(self)
self._running = True
if self._relative:
self._printer.commands('G91')
self._prev_log = self._jog
self._printer.commands(self._jog)
def stop(self):
self._running = False
self._printer.unregister_callback(self)
def on_printer_add_log(self, log):
if log.startswith('Recv: '):
log = log[6:]
if log == 'ok' and self._prev_log == self._jog:
self._printer.commands('M400')
elif log == 'ok' and self._prev_log == 'M400':
if self._running:
self._printer.commands(self._jog)
elif log.startswith('Send: '):
self._prev_log = log[6:]
# Plotter actions extend printer base
@tentacle_action('plot_home')
class HomePlotterAction(PrinterAction):
def configure(self, home_axis=['x', 'y'], z=150, **kwargs):
self._z = z
self._home_axis = home_axis
def run(self):
self._printer.home(self._home_axis)
self._printer.jog({'z':self._z}, relative=False, speed=4500)