Connecting your 3D printer to OctoPrint automatically

Recently I joined the group of 3d printer owners and OctoPrint users. After some days I got annoyed by the fact that so far nobody seems to have thought about automatically connecting a printer to OctoPrint after turning the printer on. If you start OctoPrint after your printer, everything works fine. But here OctoPrint runs 24/7 but I turn off the printer when it is done with printing.

My solution of the problem is based on udev and systemd and should work on most recent Linux installations. I’ve only tested it on Debian Stretch, though. I’m using the same paths and users as in the official OctoPrint on Raspian setup documentation. Make sure to change the user/group and path names if you have a different installation.

Talking to the OctoPrint API

First we need a script to talk to the OctoPrint API to issue a connect command. For that you need to copy the API key from your OctoPrint User settings, also I’m passing the baudrate for my printer, just in case. If OctoPrint ist not listening on localhost port 5000 make sure to change the URL, too. For details and other optins please read the API documentation and change the code accordingly.

Save the script to /home/pi/connect_octoprint.py.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/home/pi/OctoPrint/venv/bin/python

OCTOPRINT_URL = 'http://localhost:5000/api/connection'
API_KEY = 'AAABBB000YOURAPIKEYHERE000BBBAAA'
BAUDRATE = 115200


import requests
import sys

port = sys.argv[1]
headers = {'X-Api-Key': API_KEY}
json = {
  "command": "connect",
  "port": port,
  "baudrate": BAUDRATE,
}

r = requests.post(
        OCTOPRINT_URL,
        json=json,
        headers=headers
)

if (r.status_code == 204):
    sys.exit(0)
else:
    print(r)
    sys.exit(1)

From now on you’ll need root permissions to continue, so use sudo bash or login as root.

Creating a new systemd service

The next thing we need is a systemd service to execute the script. Drop the following snippet into /etc/systemd/system/[email protected] (yes, the @ in the file name is important!).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[Unit]
Description=Connect printer to OctoPrint automatically
BindsTo=dev-%i.device
After=dev-%i.device

[Service]
Type=oneshot
User=pi
RemainAfterExit=yes
ExecStart=/home/pi/connect_octoprint.py /dev/%I

To let systemd know about the new service, run systemctl daemon-reload.

Handling udev events

Finally we need to configure udev to notify systemd as soon as the 3d printer USB device is being connected. For that we need to know the Verndor and Product ID of the printer’s USB port. Normally it will be some kind of USB-Serial converter.

To find it, run

lsusb -v | grep -iE ‘(^bus|idvendor|idproduct)'

You should find lines similar to the following entry:

Bus 001 Device 035: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
  idVendor           0x0403 Future Technology Devices International, Ltd
  idProduct          0x6001 FT232 USB-Serial (UART) IC

If you have no clue which Device your 3d printer is, run lsusb when it is turned off and again after turning it on and compare the output.

In my example the idVendor is 0403 and the idProduct 6001. Create /etc/udev/rules.d/3dprinter.rules and change my example to match your printer’s ids.

KERNEL=="tty*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \
    TAG+="systemd", ENV{SYSTEMD_WANTS}="octoprint_connect@%k.service"

Udev will reload automatically and use the rule - if the syntax is correct.

Give it a try

Try to powercycle the printer and see if it is connected to OctoPrint automatically. If you’ve done everything right, it should be ready for printing.

Debugging

Debugging this in case it does not work is not a trivial task, but a good start is to look into the log/output of OctoPrint, maybe the authorization did not work. Next place to look at is systemd. Running

_systemctl list-units ‘octoprint_connect*'_

will show you the name of the automatically created service. If there is one, you can see its output by running

journalctl -u [email protected]

(replace XXXXXX properly from the systemctl output from above. Details about debugging udev are in the Arch wiki.

Enjoy!