You might be wondering why Karmen cloud service doesn’t yet natively support OctoPrint boxes whilst our Karmen Pill companion is built upon it. Strange, isn’t it? In this article, I will explain the reasons behind it and also introduce our new tool to connect any OctoPrint box without a hassle.
Karmen with its simple online access solves what many OctoPrint users just can’t achieve easily: having their box accessible on the road literally from anywhere. The problem here is networking. Kicking off a new OctoPi with RPi4 isn’t much of an effort but exposing it safely via the internet is an entirely different beast. There are several ways you do it but all of them require substantial amount of work. Here are some options one can come up with quickly:
- Port forwarding on your router — relatively easy albeit not exactly safe without further SSL configuration.
- VPN—simple to use (if you’re okay with turning VPN connection on and off just to see how your prints are doing), much harder to configure.
- SSH tunneling—rather straight forward, not so much on you phone though.
At Karmen, we needed to find more elegant solution that wouldn’t need any configuration on the users end. We don’t want our users configuring their router port forwarding just to use their Karmen Pills! That’s why we came up with our open source websocket-proxy.
It takes care of the difficult networking part by inverting the logic. Instead of talking directly to your box and needing to slip through all those routers and firewalls, Karmen talks to a websocket-proxy server which your box also connects to. This effectively avoids exposing the box out to the wild! Each proxy connection has an identifier which allows Karmen to easily talk to gazillions of boxes. It only needs to know the right connection identifier. And yes, that’s the key you use when registering a Karmen Pill with Karmen as described in the docs.
Good, just tell me how to connect my OctoPrint
Sorry for drifting away from the original topic! It was necessary for you to understand how you actually connect your OctoPrint instance. Simply said, you need to establish a connection with the websocket-proxy server Karmen cloud service has access to. Up until now, we only had a private endpoint for connecting Karmen Pills. This changes now as we’ve exposed another and public proxy server for connecting other devices like OctoPrint installations.
Also, we’ve created the karmen-octoprint-connector utility that simplifies setting this up as much as possible. You will need to install connector utility directly on your OctoPrint box and make sure it’s up & running at all times—keeping the connection alive. But before you do so, you first need to get yourself a valid connection key.
Getting the connection key
Obtaining a connection key is simple. Sign in to Karmen, navigate to the printer addition dialog under the Settings menu item and choose Other device in the I’m adding field instead of the default Karmen Pill.
Fresh connection key will be generated for you in the Connection key field value. Simply copy it to your clipboard with the Copy button right next to it. Don’t forget to name your printer and save it even though it won’t report as connected just yet.
Using OctoPrint with the access control enabled? If so, make sure to also provide Karmen with an API key under the Advanced options on the printer addition screen. See our docs for more information if unsure how to get one.
Now that you have the key at your hand, time has come to run the connector and enable Karmen to take control. There are two basic ways you can deploy it:
- Using Docker—often the easiest option, Docker is rather widespread
npx—useful when you have NPM already installed
The obvious requirement here is having the Docker daemon available on your machine. In case you happen to run an Debian-based OctoPi, you can install it with just a few shell commands:
# Install docker
sudo apt install software-properties-common -y
curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh
# Allow pi default user to manage docker
sudo usermod -aG docker pi# Reboot
If you’re on different OS, there are plenty of resources out there to help you: just Google “install docker on [your OS]”. Once you have Docker installed, running karmen-octoprint-connector boils down to executing the following one-liner:
# Fill your key
docker run --init --net=host fragaria/karmen-octoprint-connector:latest connect $karmen_key
This will run our multi-arch Docker image (compatible with both arm and amd64). Just make sure you use the right connection key. If everything worked out, you should soon see something like this:
OctoPrint on non-80 port
Previous setup assumes you have your OctoPrint running on the default port
80. If that’s not your case, you need to tell the connector to use another port instead:
docker run --init --net=host fragaria/karmen-octoprint-connector:latest connect -f http://localhost:80 $karmen_key
Provide full URL of the address you want to forward. Most of the time, it will be
http://localhost:[port] where only the port is different.
In case you prefer going with
npm(installing it is out of scope of this article), the principle stays same, only the command changes:
# Fill your key
npx karmen-octoprint-connector connect $karmen_key
A more resilient setup
Examples above are useful when you just wanna play around and try Karmen out. If you conclude you want Karmen to be your daily driver, it’s a good idea to make the OctoPrint connector deployment more resilient. Let’s install a systemd service to take care about running the connector daemon in the background. It will also ensure it’s started automatically when your machine reboots. We will only cover the Docker-based scenario here but the setup for npx-based option will be similar.
In order to run the connector using systemd, we need a service config file. Start by creating a blank file at
/etc/systemd/system/karmen-octoprint-connector.service. Here is our recommended service configuration:
# A systemd script to run karmen-octoprint-connector resiliently.
# This script expects docker to be available, make sure you instal
# it first.[Unit]
Description=Karmen OctoPrint connector
ExecStartPre=-/usr/bin/docker stop %n
ExecStartPre=-/usr/bin/docker rm %n
ExecStartPre=/usr/bin/docker pull fragaria/karmen-octoprint-connector
ExecStart=/usr/bin/docker run --rm --init --net=host --name %n fragaria/karmen-octoprint-connector:latest connect --url $SERVER_URL --forward $FORWARD $KEY
Let’s just quickly go through it. First, the
Unit section states that our service requires Docker and networking to be available before starting the connector service: this ensures all the necessary services are started before attempting to run the connector itself. Second, in the
Service section, there are multiple pre-execution steps (
- Stop existing connector container in case there’s one already running.
- Delete container if it’s already present which forces the container to be recreated.
- Pull a fresh release of the connector image from Docker Hub.
Note that the first and second steps are denoted with
ExecStartPre=-. This means our service start won’t be considered failed should these housekeeping steps fail. The reason for that is that they’re actually likely to fail at least once: during the first run when no previous containers are present on your machine.
The rest is rather straightforward: we use the same command as we did previously and just make sure it runs under
pi user and group—this service configuration is meant for OctoPi where
pi user is the default. Feel free to modify this to fit your scenario.
Note that our main command references some environment variables. These will be provided by the environment file which holds the connector configuration. Create this file at
/etc/karmen-octoprint-connector.conf. It should look like this:
Make sure you provide the connection key and address to forward. No need to modify
SERVER_URL—it already points to our public websocket-proxy instance. Now that we have all configuration we needed, we just enable our service and start it:
sudo systemctl daemon-reload
sudo systemctl start karmen-octoprint-connector.service
First launch might take a bit longer as the service needs to pull the Docker image. But shorty, you can verify it’s running with:
systemctl status karmen-octoprint-connector.service
It should report something similar to the following:
● karmen-octoprint-connector.service - Karmen OctoPrint connector
Loaded: loaded (/etc/systemd/system/karmen-octoprint-connector.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2020-05-12 04:10:55 CEST; 7h ago
Process: 10786 ExecStartPre=/usr/bin/docker stop karmen-octoprint-connector.service (code=exited, status=1/FAILURE)
Process: 10796 ExecStartPre=/usr/bin/docker rm karmen-octoprint-connector.service (code=exited, status=1/FAILURE)
Process: 10804 ExecStartPre=/usr/bin/docker pull fragaria/karmen-octoprint-connector (code=exited, status=0/SUCCESS)
Main PID: 10829 (docker)
Tasks: 11 (limit: 4915)
└─10829 /usr/bin/docker run --rm --init --net=host --name karmen-octoprint-connector.service fragaria/karmen-octoprint-connector:latest connect ...
After a minute or two, Karmen will realise your printer is now online and automagically begin to manage it. You can now navigate to cloud.karmen.tech and see your printer for yourself! But… where the hell is your slick video feed?
The video feed issue
No worries, we will fix this real quick. We just need to modify OctoPrint configuration to expose the video feed on a different URL. Karmen will realise that immediately as it reads the OctoPrint config via its REST API.
Problem with default configuration is that it uses port
8080 (namely, configuration points to
127.0.0.1:8080). Remember we configured our connector utility to forward port
80? That’s right, port
8080 isn’t forwarded and thus, Karmen won’t be able to access it. Fortunately, OctoPrint comes up bundled with haproxy which already proxies whatever webcam has to offer on
127.0.0.1:80/webcam. Therefore, we just need to tell OctoPrint to use that address instead. Navigate to your OctoPrint settings and on the Webcam & Timelapse page and set the Snapshot URL to
Wondering why we’re modifying the snapshot URL when video is what we’re after? Karmen favors snapshots over standard video feed because the the mjpeg-streamer OctoPrint uses is very hungry bandwith-wise. Snaphosts work equally well and produce a lot less traffic. Save you smartphone data plan for the important stuff like Facebook!
Adjusting the bitrate and resolution
Almost there! The last piece of the puzzle is to set the proper bitrate and resolution for your webcam. Karmen works best with 640x480px, 5 FPS and a slightly adjusted cam bitrate.
Start by modifying your
/boot/octopi.txt. Look for
camera_raspi_options and change it (or change both just to make sure it works either way) to tell the webcam to use the suggested resolution and frame rate:
camera_usb_options="-r 640x480 -f 5"
camera_raspi_options="-x 640 -y 480 -fps 5"
Now, let’s modify the bitrate. Create a
/etc/systemd/system/webcam-bitrate.service file and put following content there:
Description=Sets webcam bitrateAfter=webcamd.service[Service]
ExecStart=/usr/bin/v4l2-ctl --set-ctrl video_bitrate=5000000[Install]
Since the command for setting bitrate itself wouldn’t persist the settings for future reboots, we need to create a systemd service to take care of that. Make sure the service is loaded:
sudo systemctl daemon-reload
Now just reboot your OctoPi box with
reboot and celebrate! Having finished all the necessary steps, it’s now time to enjoy managing your printers from anywhere! You should see your printer in Karmen with a working video feed ready to accept commands over the wire.