aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlec B. Plumb <alec@etherwalker.com>2019-01-02 14:45:35 -0800
committerKevinOConnor <kevin@koconnor.net>2019-01-02 17:45:35 -0500
commit59e9b6562fb39c1e4860971e818e94a455622547 (patch)
treec257eaab9c71f3c13b9d3e6590f3ae43e68d1ea7
parentf6c9150349d3ffb364a990132a16afa64c890b2e (diff)
downloadkutter-59e9b6562fb39c1e4860971e818e94a455622547.tar.gz
kutter-59e9b6562fb39c1e4860971e818e94a455622547.tar.xz
kutter-59e9b6562fb39c1e4860971e818e94a455622547.zip
respond: An extra for sending messages to the printer host. (#1053)
I have made one change to `gcode.py` to support quoted parameter values. I have added support for the basic `M118` command (see https://reprap.org/wiki/G-code#M118:_Echo_message_on_host). I have also added a `RESPOND` command that takes extended parameters. `ECHO` might be a better name than `RESPOND` but is already defined in `gcode.py`. Signed-off-by: Alec B. Plumb <alec@etherwalker.com>
-rw-r--r--config/example-extras.cfg12
-rw-r--r--docs/G-Codes.md16
-rw-r--r--klippy/extras/respond.py51
-rw-r--r--klippy/gcode.py4
4 files changed, 81 insertions, 2 deletions
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 <message>`: echo the message prepended with the configured default
+ prefix (or `echo: ` if no prefix is configured).
+ - `RESPOND MSG="<message>"`: echo the message prepended with the configured default
+ prefix (or `echo: ` if no prefix is configured).
+ - `RESPOND TYPE=echo MSG="<message>"`: echo the message prepended with `echo: `.
+ - `RESPOND TYPE=command MSG="<message>"`: 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="<message>"`: echo the message prepended with `!! `.
+ - `RESPOND PREFIX=<prefix> MSG="<message>"`: echo the message prepended with `<prefix>`
+ (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 <alec@etherwalker.com>
+#
+# 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 <kevin@koconnor.net>
#
# 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