Skip to content

Commit

Permalink
Initial shell command power device implementation and documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleNyanCat committed Feb 22, 2025
1 parent f2d53fe commit ccb127f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
43 changes: 43 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,49 @@ location: 1-1
port: 2
```

#### Arbitrary devices via Shell commands

Control any device as long as you can come up with a way to control it with a shell command.

The most practical way of doing it will likely be with a short Python script, although it doesn't have to be.

```ini {title="Moonraker Config Specification"}
# moonraker.conf

on_cmd:
# Command to be ran to switch the device on. This parameter must be provided.
off_cmd:
# Command to be ran to switch the device off. This parameter must be provided.
timeout:
# Number of seconds after which the subprocess spawned by the command will be
# forcefully terminated. It should not need to be increased in most cases. Default is 1 second.
```

/// Warning
These commands will not recognize the tilde (`~`) shorthand for your home directory, and as such, you must always use full paths when referring to files.

`python3 /home/<user>/printer_data/psuctrl.py on` will work

`python3 ~/printer_data/psuctrl.py on` will not.
///


Example:

```ini {title="Moonraker Config Example"}
# moonraker.conf

# This assumes the presence of a Python script in the path /home/nyan/printer_data/psuctrl.py,
# that recieves an 'on' or 'off' argument and controls the power supply accordingly.
# (eg. by sending a command via serial to an Arduino, which in turn controls the
# PSU directly or via a relay)

[power atx_psu]
type: shell_cmd
on_cmd: python3 /home/nyan/printer_data/psuctrl.py on
off_cmd: python3 /home/nyan/printer_data/psuctrl.py off
```

#### Generic HTTP Devices

Support for configurable HTTP switches. This device type may be used when
Expand Down
29 changes: 28 additions & 1 deletion moonraker/components/power.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ def __init__(self, config: ConfigHelper) -> None:
"smartthings": SmartThings,
"hue": HueDevice,
"http": GenericHTTP,
"uhubctl": UHubCtl
"uhubctl": UHubCtl,
"shell_cmd": ShellCmd
}

for section in prefix_sections:
Expand Down Expand Up @@ -1585,6 +1586,32 @@ async def _run_uhubctl(self, action: str) -> Dict[str, Any]:
f"port {self.port}, "
)

class ShellCmd(PowerDevice):
def __init__(self,
config: ConfigHelper,
initial_val: Optional[int] = None
) -> None:
super().__init__(config)
self.scmd: ShellCommand = self.server.load_component(config, "shell_command")
self.on_cmd: Optional[str] = config.get('on_cmd')
self.off_cmd: Optional[str] = config.get('off_cmd')
self.timeout: Optional[float] = config.getfloat('timeout', 1.0)

async def init_state(self) -> None:
if self.initial_state is None:
self.set_power("off")
else:
self.set_power("on" if self.initial_state else "off")

def refresh_status(self) -> None:
pass

def set_power(self, state) -> None:
if state == "on":
self.scmd.exec_cmd(cmd=self.on_cmd, timeout=self.timeout)
else:
self.scmd.exec_cmd(cmd=self.off_cmd, timeout=self.timeout)
self.state = state

# The power component has multiple configuration sections
def load_component(config: ConfigHelper) -> PrinterPower:
Expand Down

0 comments on commit ccb127f

Please sign in to comment.