So I decided to get a 3d printer, the Creality Ender 3 pro. These things are really neat :)

One of the big missing things about the cheap 3d printers is that they are missing remote control and monitoring solutions. Octoprint seems to be the most popular solution, especially with the Octopi images which are pre-configured Raspberry Pi images you can just hook up to the printer and make work.

I did this as a first step and it does work neatly, except for that the printer I got has some issues with the serial port making it not reliable to print through. Also I wanted to have the camera stream so I can view the print progress remotely since the printer is 2 rooms over because its loud.

I do have a raspberry pi camera and that seems to be the go-to solution for this, except that involves printing a case for the raspberry pi, something to hold up the camera, and dealing with the fact that the camera I have is an ebay knockoff that does not fit in the normal cases since it has a larger lens mount.

Then I realized that the PinePhone is pretty much perfect for this. It has the touchscreen to run a UI on, it can do ethernet and the usb connection with the dock, it has a built in camera, and it is fast enough to run all this.

Installation

I started with installing postmarketOS edge on the PinePhone. I chose the Phosh UI so I can easily set up the phone using the touchscreen. Then the first step was setting up octoprint:

Install the dependencies to build and run octoprint in Alpine Linux
$ apk add python3 py3-pip python3-dev alpine-sdk linux-headers
[enjoy the speed at which apk installs software here]
$ sudo pip3 install octoprint
[octoprint will now be installed as /usr/bin/octoprint]

The postmarketOS firewall will block the traffic by default, disable it for now:
$ sudo service nftables stop
$ octoprint serve

Now the webinterface for octoprint should be reachable on the IP address of the PinePhone on port 5000. From there you can run through the install steps of octoprint itself.

For the camera feed I used mjpg-streamer which seems to be a nice lightweight tool for streaming the camera over http for a stream that's nice and low-cpu for the phone so it can spend more CPU on the Octoprint things.

$ sudo apk add mjpg-streamer v4l-utils

To set up the camera in the PinePhone I wrote this small shell script:

#!/bin/sh
media-ctl -d /dev/media1 -r
media-ctl -d /dev/media1 --links '"ov5640 4-004c":0->"sun6i-csi":0[1]'
media-ctl -d /dev/media1 --set-v4l2 '"ov5640 4-004c":0[fmt:UYVY8_2X8/640x480@1/15]'
mjpg_streamer -i "input_uvc.so -d /dev/video2 -r 640x480 -f 15 -u" -o "output_http.so"

This will switch the video system in the phone to the rear camera, set the resolution and mode and start mjpg streamer. I saved this as /usr/local/bin/camera

The URLs that are needed for Octoprint are:

# The mjpeg video stream
http://ip-of-the-pinephone:8080/?action=stream

# The snapshot URL for the timelapse
http://127.0.0.1:8080/?action=snapshot

To start this I made 2 init scripts for the two services this needs to run:

#!/sbin/openrc-run
# This is /etc/init.d/camera

supervisor=supervise-daemon
name="camera server"
command="/usr/local/bin/camera"

depend() {
	need net localmount
	after firewall
}

and

#!/sbin/openrc-run
# This is /etc/init.d/octoprint

supervisor=supervise-daemon
name="print server"
command="/usr/bin/octoprint"
command_args="serve"
command_user="user"

depend() {
	need net localmount
	after firewall
}

Now to do the final setup, the account needs to have permission to use usb serial adapters and the right services should be enabled:

$ groupadd user dialout
$ rc-update add camera default
$ rc-update add octoprint default
$ rc-update del nftables default

After rebooting you should have a fully functional octoprint setup.