mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-12-24 08:38:34 -07:00
- Create /tmp/homing_obstacle_flag when timeout occurs (no trigger) - Expand Z limits temporarily to allow full travel during homing - Add gcode_shell_command.py for shell command execution - Add obstacle_detector.py Klipper module 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
# Shell command execution support for Klipper
|
|
#
|
|
# Copyright (C) 2024 Microlay
|
|
#
|
|
# This file may be distributed under the terms of the GNU GPLv3 license.
|
|
|
|
import subprocess
|
|
import logging
|
|
import os
|
|
|
|
|
|
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')
|
|
self.command = config.get('command')
|
|
self.timeout = config.getfloat('timeout', 2.0)
|
|
self.verbose = config.getboolean('verbose', True)
|
|
|
|
# Register the gcode command
|
|
self.gcode.register_mux_command(
|
|
"RUN_SHELL_COMMAND", "CMD", self.name,
|
|
self.cmd_RUN_SHELL_COMMAND,
|
|
desc="Run a predefined shell command"
|
|
)
|
|
|
|
def cmd_RUN_SHELL_COMMAND(self, gcmd):
|
|
# Get optional parameters
|
|
params = gcmd.get('PARAMS', '')
|
|
|
|
# Build the full command
|
|
if params:
|
|
full_command = f"{self.command} {params}"
|
|
else:
|
|
full_command = self.command
|
|
|
|
if self.verbose:
|
|
self.gcode.respond_info(f"Running: {full_command}")
|
|
|
|
try:
|
|
# Execute the command
|
|
result = subprocess.run(
|
|
full_command,
|
|
shell=True,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=self.timeout
|
|
)
|
|
|
|
if self.verbose:
|
|
if result.stdout:
|
|
self.gcode.respond_info(f"Output: {result.stdout.strip()}")
|
|
if result.stderr:
|
|
self.gcode.respond_info(f"Stderr: {result.stderr.strip()}")
|
|
if result.returncode != 0:
|
|
self.gcode.respond_info(f"Return code: {result.returncode}")
|
|
|
|
except subprocess.TimeoutExpired:
|
|
raise self.gcode.error(f"Shell command timed out after {self.timeout}s")
|
|
except Exception as e:
|
|
raise self.gcode.error(f"Shell command error: {str(e)}")
|
|
|
|
|
|
def load_config_prefix(config):
|
|
return ShellCommand(config)
|