USB Power Control via OctoPrint

I guess I missed a word that I thought was implied- "programmatically".

I'd love to do "power on to GPIO pin 3, USB on, now connect serial".

[edit] oh, there is a serial connection API: http://docs.octoprint.org/en/master/api/connection.html#post--api-connection

1 Like

It's how I control the SB Motor Shield that turns on and off my printer lights

Upon reflection, I should have used an Arduino. It's much more popular, and there's much more documentation available. As it is, I had to turn them on one at a time until I got it to work

So if you're looking to programmatically turn off USB power then uhubctl might be useful.

Assuming USB port 2:

uhubctl -a off -p 2
2 Likes

Any update on this? I’d love to find a way to do this without yet another relay.

You could use my last posted suggestion as combined with a GCode Systems Command that you'd create a pair of new commands like OCTO912 and OCTO902. The first would turn ON USB port 2 (per the example) and the second would turn it OFF.

Next, you could edit the config.yaml for the Controls section and add a pair of buttons which point to those new OCTO commands. After a restart, OctoPrint's Control tab would have two buttons for toggling ON/OFF USB port 2 in this case.

1 Like

Hey guys. I turn on an off my printer from GUI, using a relay to turn on and off the power supply, and a command line to turn off USB port. It was just simple to do.

I´ve installed a package called hub-ctrl. It controls USB power.

Step-by step was like this:
1- Downloaded the package here: https://github.com/codazoda/hub-ctrl.c
2- Copied to /tmp using WinSCP
3- Elevated privileges with sudo to get root permissions
4- Compiled the package with the following command (in the tmp folder): gcc -o hub-ctrl hub-ctrl.c -lusb
It created a file called hub-ctrl. I,ve copied that file to /usr/bin: mv hub-ctrl /usr/bin/
5- Created my scripts to power on and off the printer at /usr/local/bin/scripts/

Script to start the USB power, wait 5 seconds then activate the relay - printer_on.sh

#!/bin/bash
sudo hub-ctrl -h 0 -P 2 -p 1
sleep 5
gpio export 4 out
gpio -g write 4 1

Script to power off - printer_off.sh

#!/bin/bash
gpio export 4 out
gpio -g write 4 0
sudo hub-ctrl -h 0 -P 2 -p 0

Added to /home/pi/.octoprint/config.yaml the following lines, after server section:

system:
actions:

  • action: pon
    command: /usr/local/bin/scripts/printer_on.sh
    name: Turn Printer On
  • action: poff
    command: /usr/local/bin/scripts/printer_off.sh
    confirm: Are you sure you want to turn off the printer?
    name: Turn Printer Off
  • action: lon
    command: /usr/local/bin/scripts/light_on.sh
    name: Turn Light On
  • action: loff
    command: /usr/local/bin/scripts/light_off.sh
    name: Turn Light Off
4 Likes

I think technically, you only have to initialize a GPIO port once as either input/output and then you don't have to keep doing that. But it doesn't hurt to keep it in your script like this, though.

Hi guys, just registered in order to add to the discussion, hoping this isn't too old a thread to add to.

The easiest fix I found for this behaviour is simply to disconnect the red wire inside the USB cable! Easy as pie. I quite often do this with USB devices to prevent parasitic draw from the RPi.

Hope that helps

1 Like

Others use a small strip of tape.

I will note that the 5V in the USB is used by drivers to know when the serial cable is connected/disconnected. Or at least, this is the specification for USB.

I wasn't keen on the potential for glue from the tape fouling the port.
Interesting that you mention the driver side of things, I've not run into that issue yet and it's something that I've implemented for a number of years; Occasionally cables have been rewired to use the 5V from a discreet SMPS instead. Would that have overcome it?

You probably just leave the serial cable in at all times (like most of us).

You could wire the 5V as described to an ATX sort of power supply or switching power supply. And yet, the 5V on an ATX is always there (with a limited current) so that pretends like it's always on. As for the switching power supply, I'll note that my own wouldn't stay on if the load was too small. (It's fond of cycling ON/OFF with a too-small load.)

I’m trying to implement this with raspberry pi 3b. All works from SSH on command line, but I can’t figure out how to get Octoprint to execute the script. Trying to use system command editor. Have tried too many things to list here. When entering command as stated above I get no tty error. If I add an & like discussed in another thread, I get command executed successfully but nothing happens. Feel like this is a simple issue but I’m so new to Linux I can’t seem to work it out. A working example in system command editor plugin may help, any insight is appreciated. Thanks in advance!

You say that it works when you execute the script from SSH. What user do you use when run the script? You have to make sure that "pi" user has access to where you saved your script, and hs permission to run it.

Smoke this thread down to the filter and you might figure out how to get a system command to run a script which needs root access to something like a GPIO pin.

I'm using a similar solution to switch off my printer's board powered by a Raspberry Pi. It's based on this USB power control code :

config.yaml

system:
  actions:
  - action: printer_usb_on
    command: sudo uhubctl -a 1 -p 2 -l 1-1
    confirm: You are activating printer USB port.
    name: Printer USB ON
  - action: printer_usb_off
    command: sudo uhubctl -a 0 -p 2 -l 1-1
    confirm: You are deactivating printer USB port.
    name: Printer USB OFF
  - action: usb_hub_on
    command: sudo uhubctl -a 1 -p 3 -l 1-1
    confirm: You are activating USB hub.
    name: USB HUB ON
  - action: usb_hub_off
    command: sudo uhubctl -a 0 -p 3 -l 1-1
    confirm: You are deactivating USB hub.
    name: USB HUB OFF

/etc/sudoers.d/octoprint-uhubctl

pi ALL=NOPASSWD: /usr/sbin/uhubctl

I'm also using a 220 V mechanical relay for the power supply. It's switched on and off by the printer's board with G-Code instead of the Raspberry Pi. It's particularly handy when prints are finished.

1 Like

I faced the same issue with power backfeeding from the raspberry pi to the control board of my CR-10S.
Finally, instead of a hardware solution I'm using hub-ctrl to switch USB power permanently off (e.g. put the invocation into crontab with @reboot).
Switching the printer on/off with the TP-Link plugin works like a charm and octoprint automatically connects to the printer when powered on.

I'm using a Pi 2B and switch all USB ports off (no other devices connected except the printer) but this should also work for single ports, maybe depends on the Pi model.

So if it's only about the back feeding (LCD stays lit and board running), I'm wondering why one would need to switch USB power together with the printer...

2 Likes

I'm linking this over on one of the more popular threads where people are suffering undervoltage. Good idea.

To be honest I figured this out just that day and was somehow concerned now that I made this statement without real testing.
So I just checked and can confirm it works.

Being at work, I tested remotely using the TP-Link app to switch the smart plug and CURLed the REST API of Octoprint via ssh.

TP-Link OFF:

GET /api/printer (checking the printer status)
HTTP/1.1 409 CONFLICT
Printer is not operational

TP-Link ON:

POST /api/connection (connecting to printer)
GET /api/printer (checking the printer status)
"state": {
...
"operational": true,
...
"ready": true,
},
"text": "Operational"
},
"temperature": {
"bed": {
"actual": 16.6,
...
}

You can also use hub-ctrl to switch on/off USB power while Octoprint is connected to the printer. It will not break the connection.

1 Like

That's amazing. Who'd have thought that toggling the USB would be just toggling the 5V power (only)?

Switching USB Power is what the author actually promises on the hub-ctrl github. :smile:

1 Like