Connecting Automatically to my Printer

Greetings everyone,

I had to join the community because I've been struggling with this small project to allow my octopi to connect automatically to my printer without having to access to the web portal and manually press connect. There's not a lot of people who have thought about this so it was hard for me to find something, however, after looking carefully I found this website. The problem is that I don't understand most of it to be honest.

I have already created a new file in my /home/pi directory and implemented the two tweaks found on this website but the problem is that I don't understand how to find the port, since I don't even know if my port is actually 5000 and I don't know if I should delete everything on the API in connect_octoprint.py or keep the
AAABBB000_____000BBBAAA.

I have tried pretty much everything but I think all the other scripts are good to go. The problem must be with the connect_octoprint.py script.

This is the information of my printer which is an Monoprice Maker Select Plus and I have only used the 1a86 and 7523 for the scripts.

idVendor 0x1a86 QinHeng Electronics
idProduct 0x7523 HL-340 USB-Serial adapter

Thanks for your help!

P.S. Found this too but I don't understand it either. Looks like another way to achieve this.

There are some checkboxes in the Connection side panel of OctoPrint. Set things up, click the Save connection settings and Auto-connect on server startup, finally click Connect.

55%20PM

Thank you but this doesn't help, I always keep my OctoPrint server running but I turn off the 3D printer. I'm trying to avoid doing that by using a script that will connect the printer automatically without having to use that web interface.

Sorry, that wasn't clear from your first post.

  1. You leave your Raspberry Pi on at all times
  2. When you're finished printing, you turn off the printer itself; OctoPrint loses the connection as a result
  3. You turn on the printer the next day and OctoPrint doesn't automatically reconnect
  4. You don't want to visit the web interface in order to push the Connect button
  5. Correct me if I'm being thick but what good is reconnecting the printer if you don't visit the web interface to select a file and to start a job? Do you control it via a phone app instead or something? I'm not understanding your need here.

It goes without saying that there's nothing easy that the printer can do to poke the Raspberry over the serial connection to say "hey, wake up" since the serial connection is of course down.

You could of course power both Raspberry and printer from the same TP-Link outlet as I do. It's convenient.

Assuming that you'd still like to create something, it would be nice to know what would be running this script. Is this you pushing a button on your workstation Desktop... or is this a script which is supposed to fire off automatically when something magically knows that the printer is on again?

Reading through that first link you provided, it looks like the following:

  • As the pi user, you create a Python script called /home/pi/connect_octoprint.py which must be modified to include your own printer's API key.
  • As the root user, you create a text file called /etc/systemd/system/octoprint_connect@.service
  • You run sudo systemctl daemon-reload
  • As the root user, you create a text file called /etc/udev/rules.d/3dprinter.rules, modifying it with your own printer's ID information
  • Reboot with sudo reboot

You'd then try to cycle the printer OFF, wait, then back ON. Presumably the rule as created can detect the state change on the collection of serial devices in such a way that the script is run. But in my mind, this is like Schrödinger's cat. You have to go into OctoPrint's web interface to confirm that it's connected but now you've "opened the box". (Technically, you could use a mobile phone app to query the REST API.)

Well I'm not using OctoPrint as my slicer, instead I'm using the beta of Cura 4.0 which I modified in order for the OctoPrint plugin to work, since it isn't currently supported. I really don't have to open the web interface and I can even look at the webcam footage from the Cura app.

I know at first it might sound weird and yes I have to open the web interface in order to make sure that the printer auto connects, but that should only be done for the initial setup, once I know that the script is up and running I would be comfortable enough to not have to open the web interface as much as I currently do.

And yes it looks like you understand as much as I do. That's exactly what I've done, however I suck at understanding ports, so I don't even know if my port is 5000 or something else and when it comes to the API key I don't know if I should delete everything or the part where it says YOURAPIKEYHERE only.

  • In the string after the equals sign to the right of API_KEY, delete AAABBB000YOURAPIKEYHERE000BBBAAA and put your own key.
  • The part port = sys.argv[1] means "accept the port as a command line argument to the script". So later, when you call this script, it gets something as an argument. This then will be used for telling OctoPrint what to do. Note that the author has also hard-coded a different port as information into that URL in the script.
  • Note that in a later script, you see this line ExecStart=/home/pi/connect_octoprint.py /dev/%I. As it turns out, that entire /dev/something is the command line argument to that script earlier. Maybe it's /dev/ttyAMA0 if it's like my own printer. So that then becomes the port variable seen in the earlier script. In other words, one of these port variables is really a device and one of them is a tcp port. The author probably should have made this known to you.
#!/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)

Check out the PortLister plugin. It will allow you to automatically reconnect once a serial port becomes available. May take a couple of extra seconds.

5 Likes

Maybe I'm just horrible at this, but this was my attempt:

#!/home/pi/oprint/bin/python

OCTOPRINT_URL = 'http://192.168.0.179/api/connection'
API_KEY = 'REDACTED'
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)


[Unit]
Description=Connect printer to OctoPrint automatically
BindsTo=dev-%i.device
After=dev-%i.device

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


KERNEL=="tty*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523",
TAG+="systemd", ENV{SYSTEMD_WANTS}="octoprint_connect@%k.service"

Just so you know the 5V cable was cut because my printer's LCD was always on! Also I tried changing the exec command you said and replacing it by ttyUSB0 but didn't work. And I used the localhost:5000 but then tried the IP to see what would happen, could it be the port or something? I feel like I'm trying to achieve something way out of my league right now.

Fyi, the second beta of Cura 4 is available, and there’s now a version of the OctoPrint Connection plugin available from the Marketplace. No modification necessary.

I just reinstalled Cura and deleted all my modified files for the OctoPrint connection. Are you the author of the plugin? What about the script I uploaded?

I am indeed the author of that plugin. To keep this thread more on-topic, if you have questions about that plugin you could use this thread: Cura OctoPrint Connection plugin

I did not really look in to your script.

Have you seen the PortLister plugin? It doesn't just refresh the list of serial ports, it also lets you (re)connect to a port when it becomes available.

1 Like

I'm not sure what you're trying to say here. Did you open up the serial cable for your printer and cut the 5V wire?

It's entirely possible that none of this will work unless that 5V line is still there.

I was also trying the instructions on that website but they didn't work for me.
After a bit of research I made it work.

First I deleted the /etc/systemd/system/octoprint_connect@.service file.
Then I changed the udev rules file to this:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", RUN+="/home/pi/scripts/connect_octoprint.py"

and the in the connect python script i changed port = sys.argv[1] into port = "serial_port", replace serial_port with the actual port used for the printer i.e. /dev/ttyUSB1
change the first line to #!/usr/bin/env python
and chmod +x the file

Now as soon as the printer is on Octoprint will connect.

There are a few errors in that article. After figuring them out it worked perfectly and it was exactly what I needed. I know you figured some of these things out and x140x1n also pointed some things out already but I'm posting this to make it easy for others who may stumble upon this thread.
Here are the things that needed to be changed/added/fixed:

In connect_octoprint.py:

  1. Change
    #!/home/pi/OctoPrint/venv/bin/python
    to
    #!/home/pi/oprint/bin/python

  2. Change the permissions for the script using the command
    chmod ug+x /home/pi/connect_octoprint.py

In /etc/systemd/system/octoprint_connect@.service change the line that reads
ExecStart=/home/pi/connect_octoprint.py /dev/%I
to
ExecStart=/home/pi/connect_octoprint.py /dev/%i
In other words, just change the uppercase I to lowercase.

In the command
lsusb -v | grep -iE ‘(^bus|idvendor|idproduct)’ change the single quotes so that they are both apostrophes
( ' ) -- the one on the same key as the double quote.

That's it. After all that, even if the article says "Udev will reload automatically and use the rule", I rebooted the Raspberry Pi and tried turning on the printer through Octoprint. It connected immediately.

One last note. I know it should still work if you use your OctoPi's IP address or FQDN in the OCTOPRINT_URL but I would leave it as localhost. That way, this would still work even if the Pi were unable to connect to the network and get an IP address. Of course, OctoPrint would be useless without a network connection but if you were using it with TouchUI or some other local user interface it would still work.

1 Like

If I am understanding you right, you power cycle the printer via the PSU plugin using a IOT smart plug on the printer it self ?

Octoprint will auto connect on server start, but not on printer start on its own.
Yet PSU plugin handles that for you. For that you need to increase (at least in my case) the 'Post On Delay' setting in PSU control, so it gives the system a second or two to wait until the system actually lists the USB port of the reconnected printer. With that setting increased and 'Connect when powered up' enabled, the printer will come online all by it self.

But you need to power cycle via the web interface of octoprint, or if you use OctoDash by waking it up.

@fieldOfView I literally just created an account to say thank you for this plugin. It works perfectly for my situation.

I have a similar setup, my Pi runs off a separate power supply and I can turn the printer on/off using GPIO, and your plugin just helps make everything smoother because it will now automatically connect when I turn the printer on using my button in the webUI or from my phone.

Only the OctoPrint connection plugin for Cura is mine. The PortLister plugin is by @markwal

There is still a typo in connect_octoprint.py!

In the block

json={
"command": "connect",
"port": port,
"baudrate": BAUDRATE
}

you need to remove the last comma, the one after BAUDRATE, or your printer will be sent a lot of gibberish.
You can see that for yourself when you enable the ./octoprint/logs/serial.log and watch it.