Pine64 & OctoPrint (Part 2)

Picking up where Part 1 left off, it's not time to look at how to install and configure OctoPrint on the Pine 64, setup webcam streaming to OctoPrint, and make our first print!

Important Notes

Before proceeding, it's important to understand how Linux permissions work. When following these instructions, make note as to where commands are run as sudo and when they're not. Do not simply run all of these commands as sudo or do a sudo su before starting, or these instructions will not work. Also make note of character case. OctoPrint and octoprint are not interchangeable, and must be used specifically with the case noted.

Installing OctoPrint

I've derived my install process from the Raspberry Pi Raspbian install instructions for OctoPrint, with just a few subtle changes. One big one being the installation directory, which I've changed to /usr/local/etc/ instead of the user's home directory.

  • Run cd /usr/local/etc to switch to the local etc directory
  • Install all of the required OctoPrint prerequisites by running sudo apt-get install python-pip python-dev python-setuptools python-virtualenv git libyaml-dev build-essential
  • Copy OctoPrint from the GitHub repository by running git clone https://github.com/foosel/OctoPrint.git
  • Navigate into the new OctoPrint folder with cd OctoPrint
  • Configure the virtual environment by running virtualenv venv
  • Perform the PIP install by running ./venv/bin/pip install pip -–upgrade
  • Run the OctoPrint setup script with ./venv/bin/python setup.py install

OctoPrint will by default look at ~/.octoprint/config.yaml for the configuration file, so before we run OctoPrint for the first time, we need to make sure that folder exists and has appropriate security so that OctoPrint can create config.yaml during first run.

  • First, create a folder called .octoprint in your local directory with mkdir ~/.octoprint
  • Ensure that folder is readable by running chmod 755 ~/.octoprint

Before we run OctoPrint for the first time, we want to ensure that our user has access to the Pine64's USB ports by running the following commands, where ubuntu is your username.

  • sudo usermod -a -G tty ubuntu
  • sudo usermod -a -G dialout ubuntu

Now we can start OctoPrint for the first time by running /usr/local/etc/OctoPrint/venv/bin/octoprint. If all goes well, you should see the scripts executing, and you should be able to go to http://{pine64-ip}:5000 from another machine on your network and see OctoPrint.

OctoPrint will present you with a first run Wizard, asking you to setup a username/password to use when interacting with the system via your browser, and configuring basic parameters of your 3D printer. Create the username and password; OctoPrint will tell you it's optional, but it's just smart system security to do so. You can set basic properties for your printer if you want, or you can do that later (we'll be back), then finish the wizard. We'll come back to OctoPrint later, but for now, go back to your terminal and hit Ctrl + C to kill the OctoPrint script.

If you want to change the port that you use to access OctoPrint, open the config.yaml file by running nano ~/.octoprint/config.yaml. Move down to the server: section, and add/change the port node. In my case, I added port: 8080 to the server node.

Installing Webcam Capabilities

One of the nice features of OctoPrint is the ability to stream a webcam to the browser for remote monitoring of your prints. Additionally, OctoPrint also gives you the opportunity to use this webcam to create timelapse videos of your prints, all configured and delivered through the OctoPrint UI.

  • Make sure you have a webcam that's supported by mjpg-streamer. I'm using a Logitech C920, which works great.
  • Navigate back to /usr/local/etc by running cd /usr/local/etc
  • Install the prerequisites for mjpg-streamer by running sudo apt-get install libv4l-0 fswebcam subversion libjpeg8-dev imagemagick libav-tools ffmpeg cmake
  • Copy mjpg-streamer from the GitHub repository by running git clone https://github.com/jacksonliam/mjpg-streamer.git
  • Navigate into the copied directory with cd mjpg-streamer/mjpg-streamer-experimental
  • Run export LD_LIBRARY_PATH=.
  • Compile the code by running make

We've now installed mjpg-streamer, but need to set it up to start automatically at boot. There's a few mechanisms to start it, and OctoPrint's native instructions have you setup custom actions inside the OctoPrint UI to start and stop the service, but for my purposes it's easier to just have it automatically start when my Pine64 boots up. To achieve this, we need to create a couple scripts.

  • Run nano /usr/local/etc/OctoPrint/scripts/webcam
  • Paste in the following script and save the file
#!/bin/bash
# Start / stop streamer daemon
  case "$1" in
  start)
    /usr/local/etc/OctoPrint/scripts/webcamDaemon >/dev/null 2>&1 &
    echo "$0: started"
    ;;
  stop)
    pkill -x webcamDaemon
    pkill -x mjpg_streamer
    echo "$0: stopped"
    ;;
  *)
    echo "Usage: $0 {start|stop}" >&2
    ;;
esac
  • Run nano /usr/local/etc/OctoPrint/scripts/webcamDaemon
  • Paste in the following script and save the file; note that if you're using a different camera than the Logitech C920, you'll have to change the camera_usb_options to reflect the config for your webcam. Note that I've set the output port for the webcam stream to 8088. This means that OctoPrint will run on 8080 and the webcam will be available on 8088.
#!/bin/bash

MJPGSTREAMER_HOME=/usr/local/etc/mjpg-streamer/mjpg-streamer-experimental
MJPGSTREAMER_INPUT_USB="input_uvc.so"
MJPGSTREAMER_INPUT_RASPICAM="input_raspicam.so"

# init configuration
camera="auto"
camera_usb_options="-n -r 1920x1080 -f 30"
camera_raspi_options="-fps 10"

if [ -e "/boot/octopi.txt" ]; then
    source "/boot/octopi.txt"
fi

# runs MJPG Streamer, using the provided input plugin + configuration
function runMjpgStreamer {
    input=$1
    pushd $MJPGSTREAMER_HOME
    echo Running ./mjpg_streamer -o "output_http.so -p 8088 -w ./www" -i "$inpu$
    LD_LIBRARY_PATH=. ./mjpg_streamer -o "output_http.so -p 8088 -w ./www" -i "$
    popd
}

# starts up the RasPiCam
function startRaspi {
    logger "Starting Raspberry Pi camera"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_RASPICAM $camera_raspi_options"
}

# starts up the USB webcam
function startUsb {
    logger "Starting USB webcam"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $camera_usb_options"
}

# we need this to prevent the later calls to vcgencmd from blocking
# I have no idea why, but that's how it is...
vcgencmd version

# echo configuration
echo camera: $camera
echo usb options: $camera_usb_options
echo raspi options: $camera_raspi_options

# keep mjpg streamer running if some camera is attached
while true; do
    if [ -e "/dev/video0" ] && { [ "$camera" = "auto" ] || [ "$camera" = "usb" $
        startUsb
    elif [ "`vcgencmd get_camera`" = "supported=1 detected=1" ] && { [ "$camera$
        startRaspi
    fi

    sleep 120
done
  • Next we need to make both of these scripts executable, by running the following commands:
  • chmod +x /usr/local/etc/OctoPrint/scripts/webcam
  • chmod +x /usr/local/etc/OctoPrint/scripts/webcamDaemon
  • And add the webcam daemon to rc.local by running sudo nano /etc/rc.local, and inserting the following before exit 0:
echo before-mjpg
/usr/local/etc/OctoPrint/scripts/webcam start
echo after-mjpg

Making OctoPrint Start Automatically

In addition to automatically starting mjpg-streamer and the webcam services, I also want OctoPrint to start automatically.

  • Edit the octoprint.init file by running sudo nano /usr/local/etc/OctoPrint/scripts/octoprint.init
  • Add new paths the PATH variable by appending to the end:
:/usr/local/etc:/usr/local/etc/OctoPrint
  • Copy octoprint.init by running sudo cp /usr/local/etc/OctoPrint/scripts/octoprint.init /etc/init.d/octoprint
  • Make /etc/init.d/octoprint executable by running sudo chmod +x /etc/init.d/octoprint
  • Edit the octoprint.default file by running sudo nano /usr/local/etc/OctoPrint/scripts/octoprint.default
  • Make changes noted below. Be sure to uncomment (remove the # at the start of the line) if you set a value:
# Configuration for /etc/init.d/octoprint

# The init.d script will only run if this variable non-empty.
OCTOPRINT_USER=ubuntu

# base directory to use
BASEDIR=/home/ubuntu/.octoprint

# configuration file to use
CONFIGFILE=/home/ubuntu/.octoprint/config.yaml

# On what port to run daemon, default is 5000
PORT=8080

# Path to the OctoPrint executable, you need to set this to match your installation!
DAEMON=/usr/local/etc/OctoPrint/venv/bin/octoprint

# What arguments to pass to octoprint, usually no need to touch this
DAEMON_ARGS="--port=$PORT"

# Umask of files octoprint generates, Change this to 000 if running octoprint as its own, separate user
UMASK=022

# Process priority, 0 here will result in a priority 20 process.
# -2 ensures Octoprint has a slight priority over user processes.
NICELEVEL=-2

# Should we run at startup?
START=yes
  • Copy octoprint.default by running sudo cp /usr/local/etc/OctoPrint/scripts/octoprint.default /etc/default/octoprint
  • Ensure that OctoPrint is added to rc.d for startup by running sudo update-rc.d octoprint defaults

First Reboot

Now that all the services are setup, we can reboot for the first time and validate that all of our services start.

  • Issue a sudo reboot from the terminal to reboot your Pine64.
  • Once the OS boots, wait 30 seconds or so for the services to all spin up, then try hitting OctoPrint in a browser, on the port we defined (in my case 8080): http://{pine64-ip}:8080
  • In another browser tab, attempt to view your webcam stream, on the port we defined (in my case 8088): http://{pine64-ip}:8088/?action=stream

Shutdowns & Reboots

Ideally, we never want to have to SSH into our Pine64 in the future, so we need to configure a way to shutdown the Pine64 or reboot it from inside the OctoPrint UI. Thankfully, OctoPrint gives us the ability to define custom actions, which can call scripts that you define.

First things first, we need our user (in this case ubuntu) to be able to issue shutdown commands without entering a password. To do this, perform the following steps:

  • Run sudo -s
  • Run cat > /etc/sudoers.d/octoprint-shutdown
  • Type ubuntu ALL=NOPASSWD: /sbin/shutdown and hit Enter
  • Press Ctrl + D twice

Now we'll create the actions inside of OctoPrint.

  • Open the OctoPrint config file by running nano ~/.octoprint/config.yaml
  • Scroll down to the system section, or create it if it doesn't exist
  • Define the actions section inside of system, and enter the following actions. Note that spaces and correct indentations here are critical, or they will not work.
system:
  actions:
    - name: Shutdown
      command: sudo shutdown -h now
      action: shutdown
      confirm: You are about to shutdown the system.
    - name: Reboot
      command: sudo shutdown -r now
      action: reboot
      confirm: You are about to reboot the system.
  • Save the file, and reboot by issuing a sudo reboot

When the system comes back up, navigate to OctoPrint in your browser, and login. You should now see a System menu at the top right of your screen with options to shutdown and reboot the system.

Final Updates & Package Installs

At this point, it's a good idea to run a sudo apt-getupdate && sudo apt-get upgrade to make sure there's no updates available for your system before we put it into production. I also took this opportunity to install the Arduino core just in case I need it in the future (by running sudo apt-get install arduino arduino-core).

Final Configuration

From here on out we'll do everything in the UI and no longer need our SSH session. Complete the final OctoPrint configuration by hitting the Settings button in the top bar of OctoPrint. Many of these settings will be specific to your 3D printer (including those on the Serial Connection, Printer Profiles, and Temperatures tabs), but some need to match things we've already setup, such as the webcam settings.

On the Webcam & Timelapse tab, set the Stream URL to http://{pine64-ip}:8088/?action=stream and set the Snapshot URL to http://{pine64-ip}:8088/?action=snapshot. Set the FFMPEG path to /usr/bin/ffmpeg. Decide if you want the OctoPrint watermark on your timelapse videos, and set a bitrate for your output videos.

On the API tab, set whether you want the API enabled or not. If you wish to use the Octo app on your phone to monitor your prints, this will need to be enabled, and the API key set inside the app.

On the Folders tab, remember back in Part 1, we created some specific network shares to store our files and timelapse output in. Configure those here, in my case:

  • Upload Folder: /media/RigidBot/Uploads
  • Timelapse Folder: /media/RigidBot/Timelapse
  • Timelapse Temp Fodler: /home/ubuntu/.octoprint/timelapse/tmp
  • Logs Folder: /media/RigidBot/Logs
  • Watched Folder: /media/RigidBot/Watched
  • Actively poll watched folder: Yes

Note that I'm not storing the timelapse temp files on the network share. Those will live on the Pine64 so that FFMPEG can process them more efficiently. Only the final videos will be set to the network share.

Lastly, click on the Software Update tab, then click the little wrench icon at the top right, and set the OctoPrint checkout folder to /usr/local/etc/OctoPrint. This allows OctoPrint to alert you when new versions of the software are available.

Your First Print

That's it. OctoPrint is now installed, configured, and ready to run. Maybe you should consider printing a new case for your OctoPrint Pine64 to test everything out!