Skip to content

Commit

Permalink
Merge branch 'master' into bleeding-edge
Browse files Browse the repository at this point in the history
  • Loading branch information
rogerlz committed Oct 19, 2023
2 parents d51c012 + f2ca654 commit 2ac2ab3
Show file tree
Hide file tree
Showing 10 changed files with 299 additions and 7 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Features merged into the master branch:

- [gcode: Jinja2.ext.do extension](https://github.com/DangerKlippers/danger-klipper/pull/26) ([klipper#5149](https://github.com/Klipper3d/klipper/pull/5149))

- [gcode: gcode_shell_command](https://github.com/DangerKlippers/danger-klipper/pull/26) ([klipper#2173](https://github.com/Klipper3d/klipper/pull/2173) / [kiuah](https://github.com/dw-0/kiauh/blob/master/resources/gcode_shell_command.py) )

- [probe: Dockable Probe](https://github.com/DangerKlippers/danger-klipper/pull/43) ([klipper#4328](https://github.com/Klipper3d/klipper/pull/4328))

- [probe: Drop the first result](https://github.com/DangerKlippers/danger-klipper/pull/2) ([klipper#3397](https://github.com/Klipper3d/klipper/issues/3397))
Expand All @@ -38,6 +40,8 @@ Features merged into the master branch:

- [homing: sensorless minimum home distance](https://github.com/DangerKlippers/danger-klipper/pull/65)

- [virtual_sdcard: scanning of subdirectories](https://github.com/DangerKlippers/danger-klipper/pull/68) ([klipper#6327](https://github.com/Klipper3d/klipper/pull/6327))

If you're feeling adventurous, take a peek at the extra features in the bleeding-edge branch:

- [dmbutyugin's advanced-features branch](https://github.com/DangerKlippers/danger-klipper/pull/69) [dmbutyugin/advanced-features](https://github.com/dmbutyugin/klipper/commits/advanced-features)
Expand All @@ -64,3 +68,5 @@ To begin using Klipper start by

Klipper is Free Software. See the [license](COPYING) or read the
[documentation](https://DangerKlippers.github.io/danger-klipper/Overview.html).

[![Join me on Discord](https://discord.com/api/guilds/1029426383614648421/widget.png?style=banner2)](https://discord.gg/armchairengineeringsux)
10 changes: 6 additions & 4 deletions docs/Config_Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ A collection of DangerKlipper-specific system options
# if False, will warn but allow klipper to still run
error_on_unused_config_options: True
# If statistics should be logged
# If statistics should be logged
# (helpful for keeping the log clean during development)
log_statistics: True
log_statistics: True
# If the config file should be logged at startup
log_config_file_at_startup: True
log_config_file_at_startup: True
# If the bed mesh should be logged on startup
# If the bed mesh should be logged on startup
# (helpful for keeping the log clean during development)
log_bed_mesh_at_startup: True
Expand Down Expand Up @@ -1521,6 +1521,8 @@ path:
# be provided.
#on_error_gcode:
# A list of G-Code commands to execute when an error is reported.
#with_subdirs: False
# Enable scanning of subdirectories for the menu and for the M20 and M23 commands. The default is False.
```

Expand Down
77 changes: 77 additions & 0 deletions docs/G-Code_Shell_Command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# G-Code Shell Command Extension

### Creator of this extension is [Arksine](https://github.com/Arksine).

This is a brief explanation of how to use the shell command extension for Klipper, which you can install with KIAUH.

After installing the extension you can execute linux commands or even scripts from within Klipper with custom commands defined in your printer.cfg.

#### How to configure a shell command:

```shell
# Runs a linux command or script from within klipper. Note that sudo commands
# that require password authentication are disallowed. All executable scripts
# should include a shebang.
# [gcode_shell_command my_shell_cmd]
#command:
# The linux shell command/script to be executed. This parameter must be
# provided
#timeout: 2.
# The timeout in seconds until the command is forcably terminated. Default
# is 2 seconds.
#verbose: True
# If enabled, the command's output will be forwarded to the terminal. Its
# recommended to set this to false for commands that my run in quick
# succession. Default is True.
```

Once you have set up a shell command with the given parameters from above in your printer.cfg you can run the command as follows:
`RUN_SHELL_COMMAND CMD=name`

Example:

```
[gcode_shell_command hello_world]
command: echo hello world
timeout: 2.
verbose: True
```

Execute with:
`RUN_SHELL_COMMAND CMD=hello_world`

### Passing parameters:

As of commit [f231fa9](https://github.com/dw-0/kiauh/commit/f231fa9c69191f23277b4e3319f6b675bfa0ee42) it is also possible to pass optional parameters to a `gcode_shell_command`.
The following short example shows storing the extruder temperature into a variable, passing that value with a parameter to a `gcode_shell_command`, which then,
once the gcode_macro runs and the gcode_shell_command gets called, executes the `script.sh`. The script then echoes a message to the console (if `verbose: True`)
and writes the value of the parameter into a textfile called `test.txt` located in the home directory.

Content of the `gcode_shell_command` and the `gcode_macro`:

```
[gcode_shell_command print_to_file]
command: sh /home/pi/klipper_config/script.sh
timeout: 30.
verbose: True
[gcode_macro GET_TEMP]
gcode:
{% set temp = printer.extruder.temperature %}
{ action_respond_info("%s" % (temp)) }
RUN_SHELL_COMMAND CMD=print_to_file PARAMS={temp}
```

Content of `script.sh`:

```shell
#!/bin/sh

echo "temp is: $1"
echo "$1" >> "${HOME}/test.txt"
```

## Warning

This extension may have a high potential for abuse if not used carefully! Also, depending on the command you execute, high system loads may occur and can cause system instabilities.
Use this extension at your own risk and only if you know what you are doing!
2 changes: 1 addition & 1 deletion klippy/extras/display/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ def _populate(self):
super(MenuVSDList, self)._populate()
sdcard = self.manager.printer.lookup_object("virtual_sdcard", None)
if sdcard is not None:
files = sdcard.get_file_list()
files = sdcard.get_file_list(sdcard.with_subdirs)
for fname, fsize in files:
self.insert_item(
self.manager.menuitem_from(
Expand Down
96 changes: 96 additions & 0 deletions klippy/extras/gcode_shell_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Run a shell command via gcode
#
# Copyright (C) 2019 Eric Callahan <[email protected]>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import os
import shlex
import subprocess
import logging


class ShellCommand:
def __init__(self, config):
self.name = config.get_name().split()[-1]
self.printer = config.get_printer()
self.gcode = self.printer.lookup_object("gcode")
cmd = config.get("command")
cmd = os.path.expanduser(cmd)
self.command = shlex.split(cmd)
self.timeout = config.getfloat("timeout", 2.0, above=0.0)
self.verbose = config.getboolean("verbose", True)
self.proc_fd = None
self.partial_output = ""
self.gcode.register_mux_command(
"RUN_SHELL_COMMAND",
"CMD",
self.name,
self.cmd_RUN_SHELL_COMMAND,
desc=self.cmd_RUN_SHELL_COMMAND_help,
)

def _process_output(self, eventime):
if self.proc_fd is None:
return
try:
data = os.read(self.proc_fd, 4096)
except Exception:
pass
data = self.partial_output + data.decode()
if "\n" not in data:
self.partial_output = data
return
elif data[-1] != "\n":
split = data.rfind("\n") + 1
self.partial_output = data[split:]
data = data[:split]
else:
self.partial_output = ""
self.gcode.respond_info(data)

cmd_RUN_SHELL_COMMAND_help = "Run a linux shell command"

def cmd_RUN_SHELL_COMMAND(self, params):
gcode_params = params.get("PARAMS", "")
gcode_params = shlex.split(gcode_params)
reactor = self.printer.get_reactor()
try:
proc = subprocess.Popen(
self.command + gcode_params,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
except Exception:
logging.exception(
"shell_command: Command {%s} failed" % (self.name)
)
raise self.gcode.error("Error running command {%s}" % (self.name))
if self.verbose:
self.proc_fd = proc.stdout.fileno()
self.gcode.respond_info("Running Command {%s}...:" % (self.name))
hdl = reactor.register_fd(self.proc_fd, self._process_output)
eventtime = reactor.monotonic()
endtime = eventtime + self.timeout
complete = False
while eventtime < endtime:
eventtime = reactor.pause(eventtime + 0.05)
if proc.poll() is not None:
complete = True
break
if not complete:
proc.terminate()
if self.verbose:
if self.partial_output:
self.gcode.respond_info(self.partial_output)
self.partial_output = ""
if complete:
msg = "Command {%s} finished\n" % (self.name)
else:
msg = "Command {%s} timed out" % (self.name)
self.gcode.respond_info(msg)
reactor.unregister_fd(hdl)
self.proc_fd = None


def load_config_prefix(config):
return ShellCommand(config)
5 changes: 3 additions & 2 deletions klippy/extras/virtual_sdcard.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def __init__(self, config):
self.reactor = self.printer.get_reactor()
# sdcard state
sd = config.get("path")
self.with_subdirs = config.getboolean("with_subdirs", False)
self.sdcard_dirname = os.path.normpath(os.path.expanduser(sd))
self.filename = ""
self.current_file = None
Expand Down Expand Up @@ -172,7 +173,7 @@ def load_file(self, gcmd, filename, check_subdirs=False):
except:
logging.exception("virtual_sdcard file open")
raise gcmd.error("Unable to open file")
gcmd.respond_raw("File opened:%s Size:%d" % (filename, fsize))
gcmd.respond_raw("File opened: %s Size: %d" % (filename, fsize))
gcmd.respond_raw("File selected")
self.current_file = f
self.file_position = 0
Expand All @@ -191,7 +192,7 @@ def cmd_error(self, gcmd):

def cmd_M20(self, gcmd):
# List SD card
files = self.get_file_list()
files = self.get_file_list(self.with_subdirs)
gcmd.respond_raw("Begin file list")
for fname, fsize in files:
gcmd.respond_raw("%s %d" % (fname, fsize))
Expand Down
13 changes: 13 additions & 0 deletions test/klippy/gcode_shell_command.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Test case for gcode_shell_command
[mcu]
serial: /dev/ttyACM0

[printer]
kinematics: none
max_velocity: 300
max_accel: 3000

[gcode_shell_command HELLO_WORLD]
command: echo hello world
timeout: 2.
verbose: True
5 changes: 5 additions & 0 deletions test/klippy/gcode_shell_command.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Test case for gcode_shell_command
CONFIG gcode_shell_command.cfg
DICTIONARY atmega2560.dict

HELLO_WORLD
85 changes: 85 additions & 0 deletions test/klippy/virtual_sdcard.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Test config for sdcard_loop
[virtual_sdcard]
path: test/klippy/sdcard_loop
with_subdirs: True

[display_status]

# Override to support unlimited belt size
# (homing Z simply resets its virtual position to 0.0)
[homing_override]
axes: xyz
set_position_x: 0
set_position_y: 0
set_position_z: 0
gcode:
G92 X0 Y0 Z0


[stepper_x]
step_pin: PF0
dir_pin: PF1
enable_pin: !PD7
microsteps: 16
rotation_distance: 40
endstop_pin: ^PE5
position_endstop: 0
position_max: 200
homing_speed: 50

[stepper_y]
step_pin: PF6
dir_pin: !PF7
enable_pin: !PF2
microsteps: 16
rotation_distance: 40
endstop_pin: ^PJ1
position_endstop: 0
position_max: 200
homing_speed: 50

[stepper_z]
step_pin: PL3
dir_pin: PL1
enable_pin: !PK0
microsteps: 16
rotation_distance: 8
endstop_pin: ^PD3
position_endstop: 0.5
position_max: 200000000

[extruder]
step_pin: PA4
dir_pin: PA6
enable_pin: !PA2
microsteps: 16
rotation_distance: 33.5
nozzle_diameter: 0.500
filament_diameter: 3.500
heater_pin: PB4
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PK5
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
pid_Kd: 114
min_temp: 0
max_temp: 210

[heater_bed]
heater_pin: PH5
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PK6
control: watermark
min_temp: 0
max_temp: 110

[mcu]
serial: /dev/ttyACM0

[printer]
kinematics: cartesian
max_velocity: 300
max_accel: 3000
max_z_velocity: 5
max_z_accel: 100
7 changes: 7 additions & 0 deletions test/klippy/virtual_sdcard.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
; Virtual SD card unit tests

DICTIONARY atmega2560.dict
CONFIG virtual_sdcard.cfg

G28
M20

0 comments on commit 2ac2ab3

Please sign in to comment.