diff --git a/config/example-extras.cfg b/config/example-extras.cfg index 57c9ddd1..0afc5ae3 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1051,3 +1051,15 @@ # Replicape support - see the generic-replicape.cfg file for further # details. #[replicape] + +# Enable the "M118" and "RESPOND" extended commands. +# [respond] +# default_type: echo +# Sets the default prefix of the "M118" and "RESPOND" output to one of +# the following: +# echo: "echo: " (This is the default) +# command: "// " +# error: "!! " +# default_prefix: echo: +# Directly sets the default prefix. If present, this value will override +# the "default_type". diff --git a/docs/G-Codes.md b/docs/G-Codes.md index a4e44ced..a7847d40 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -273,3 +273,19 @@ section is enabled: may lead to internal software errors. This command may invalidate future boundary checks; issue a G28 afterwards to reset the kinematics. + +## Send message (respond) to host + +The following commands are availabe when the "respond" config section is +enabled. + - `M118 `: echo the message prepended with the configured default + prefix (or `echo: ` if no prefix is configured). + - `RESPOND MSG=""`: echo the message prepended with the configured default + prefix (or `echo: ` if no prefix is configured). + - `RESPOND TYPE=echo MSG=""`: echo the message prepended with `echo: `. + - `RESPOND TYPE=command MSG=""`: echo the message prepended with `// `. + Octopint can be configured to respond to these messages (e.g. + `RESPOND TYPE=command MSG=action:pause`). + - `RESPOND TYPE=error MSG=""`: echo the message prepended with `!! `. + - `RESPOND PREFIX= MSG=""`: echo the message prepended with `` + (The `PREFIX` parameter will take priority over the `TYPE` parameter) diff --git a/klippy/extras/respond.py b/klippy/extras/respond.py new file mode 100644 index 00000000..0f8fd24c --- /dev/null +++ b/klippy/extras/respond.py @@ -0,0 +1,51 @@ +# Add 'RESPOND' and 'M118' commands for sending messages to the host +# +# Copyright (C) 2018 Alec Plumb +# +# This file may be distributed under the terms of the GNU GPLv3 license. + +respond_types = { + 'echo': 'echo:', + 'command': '//', + 'error' : '!!', +} + +class HostResponder: + def __init__(self, config): + self.printer = config.get_printer() + self.reactor = self.printer.get_reactor() + self.default_prefix = config.getchoice('default_type', respond_types, 'echo') + self.default_prefix = config.get('default_prefix', self.default_prefix) + self.gcode = self.printer.lookup_object('gcode') + self.cmd_M118_help = "Send a message to the host prefixed with '%s'" % self.default_prefix + self.gcode.register_command( + 'M118', self.cmd_M118, True, desc=self.cmd_M118_help) + self.gcode.register_command('RESPOND', self.cmd_RESPOND, True) + def cmd_M118(self, params): + if '#original' in params: + msg = params['#original'] + if not msg.startswith('M118'): + # Parse out additional info if M118 recd during a print + start = msg.find('M118') + end = msg.rfind('*') + msg = msg[start:end] + if len(msg) > 5: + msg = msg[5:] + else: + msg = '' + self.gcode.respond("%s %s" %(self.default_prefix, msg)) + def cmd_RESPOND(self, params): + respond_type = self.gcode.get_str('TYPE', params, None) + prefix = self.default_prefix + if(respond_type != None): + respond_type = respond_type.lower() + if(respond_type in respond_types): + prefix = respond_types[respond_type] + else: + raise self.gcode.error("RESPOND TYPE '%s' is invalid. Must be one of 'echo', 'command', or 'error'" % respond_type) + prefix = self.gcode.get_str('PREFIX', params, prefix) + msg = self.gcode.get_str('MSG', params, '') + self.gcode.respond("%s %s" %(prefix, msg)) + +def load_config(config): + return HostResponder(config) diff --git a/klippy/gcode.py b/klippy/gcode.py index 2897b664..c2abbf45 100644 --- a/klippy/gcode.py +++ b/klippy/gcode.py @@ -3,7 +3,7 @@ # Copyright (C) 2016-2018 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. -import os, re, logging, collections +import os, re, logging, collections, shlex import homing, kinematics.extruder class error(Exception): @@ -356,7 +356,7 @@ class GCodeParser: return params eargs = m.group('args') try: - eparams = [earg.split('=', 1) for earg in eargs.split()] + eparams = [earg.split('=', 1) for earg in shlex.split(eargs)] eparams = { k.upper(): v for k, v in eparams } eparams.update({k: params[k] for k in params if k.startswith('#')}) return eparams