Arksine / moonraker

Web API Server for Klipper
https://moonraker.readthedocs.io
GNU General Public License v3.0
1.02k stars 392 forks source link

Add option to power off a power device when operating system shutdown. #856

Open jhorn70 opened 1 month ago

jhorn70 commented 1 month ago

Is your feature request related to a problem? Please describe

I am new to Klipper/Moonraker/Mainsail and recently set up a power device for my printer which separates the PI and MCU power control. My device is a shelly device, but others should work the same way in my opinion. Intuitively, I expected when a host shutdown was issued in Mainsail that it would power off the printer device. Typically, when I am shutting down the Pi I am looking to shut down the entire machine.

Describe the solution you'd like

I would like a config option for a power device that is "off_when_host_shutdown". The machine.shutdown command should look at any power devices with "off_when_host_shutdown" is set to true and power them off prior to issuing the shutdown command to the operating system.

Describe alternatives you've considered

Using Home Assistant or some external solution to see if the pi is shutdown and shutting down the printer power.

Additional information

No response

AndreKR commented 2 weeks ago

I have exactly the same requirement. I tried setting off_when_shutdown: True but that doesn't seem to work. When I issue a host shutdown, the device isn't powered off. This could be because Moonraker is immediately stopped before it has time to send the (in my case) HTTP request, in which case the solution would probably have to be to delay the shutdown for a second or two, depending on the power devices that need to be notified.

Laikulo commented 1 week ago

As a cheapshot workaround, if you are using systemd, you could add an ExecStop to some script that does whatever is needed. Since Moonraker itself won't receive a TERM until all the last one it should allow for most anything.

# Open an editor to an automatically created override
% sudo systemctl edit moonraker.service
[Service]
# The '-' below causes systemd to ignore failures, if MR is unable to process this
# Might be better to use the socket for this
ExecStop=-/usr/bin/http POST http://localhost:7125/machine/device_power/device?device=my_thingey&action=off
# This won't be needed if the above is sync
ExecStop=/usr/bin/sleep 1
# Replicate the default stop behavior (SIGTERM)
ExecStop=/usr/bin/kill 15 $MAINPID
% sudo systemctl daemon-reload

Adding an on_exit to power, and possibly an off_when_exiting parameter feels like an option to do this the real way