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!

Pine64 & OctoPrint (Part 1)

I had a couple Pine64 boards sitting in a drawer, and decided it was finally time to replace that old Raspberry Pi running OctoPrint (err, OctoPi) for my 3D printer. The Raspberry Pi has served admirably, but it was definitely time for an upgrade, and a chance to improve a lot of my overall printing workflow.

The Pine64

If you're unfamiliar, the Pine64 is a 64-bit, single board computer. I'm using the A64+ 2GB board, which comes with a quad core ARM Cortex A53 processor operating at 1.2 Ghz, 2Gb of DDR3 memory, dual core graphics, and gigabit ethernet. With double the memory of the Raspberry Pi 3, plus gigabit ethernet, the Pine64 is a steal at just $29.

Downloading an Image

If you're used to a Raspberry Pi, the initial configuration of the Pine64 is going to feel nice and familiar. Start off by grabbing the image of your choice from the Pine64 Wiki. I didn't want a desktop environment, so I'm using the July 16, 2016 Longsleep image. It has to be said that the downloads from the Pine64 Wiki are painfully slow, so even at just ~170Mb, plan ahead a little. Some of the images listed in the wiki are available via torrent, so if go that route, you'll likely see much better download performance.

Creating the SD Card

Identical to the Raspberry Pi process, you'll want to use something like SD Card Formatter to prep your card, then "burn" the image to it using Win32 Disk Imager. If you happen to be using a Pine64 for another project, you'll notice that the Android images are "burned" using PhoenixCard. Note that these processes are not interchangeable; you cannot make a Linux SD card using PhoenixCard.

Powering Up

Once you've got your SD card ready to go, insert it into the Pine64. For my initial setup, I plugged in a local keyboard and mouse, monitor (via HDMI port), and a network cable. The Pine64 is a bit more power hungry than a Raspberry Pi, and consequently you must use a decent quality USB power adapter that puts out a nice clean 2A. I'm using a Power-over-Ethernet splitter for mine, which splits apart a POE network cable into standard gigabit ethernet and a micro-USB for power. Whatever method you choose will work, don't just grab an old mid-2000s USB adapter from a drawer and expect to be successful.

Logging In

Once you've seen a clean boot, login with the default password for the image you've chosen (credentials will be listed on the Wiki with the download). Any time you've downloaded an image from the community, step 1 should always be to run passwd and change the password! Once you've done that, be sure to expand the root partition to use your full SD card. For my image, a script was included to perform this, so it was as simple as running sudo /usr/local/sbin/resize_rootfs.sh and just watch it do its thing. Now is also a great time to grab and install any updates, since your image may be out of date. Simply run sudo apt-get update && sudo apt-get upgrade.

Mounting Shares

One of the things I always wanted to do with my Raspberry Pi, was point OctoPrint at a network share for logs, timelapse videos and uploads. This gets these files off of my OctoPrint machine, allows me to back them up easier, and makes transferring those files between OctoPrint and my Windows machines much easier. With the limited processing and network bandwidth of the Raspberry Pi, this never really worked well, but it works just fine on a Pine64! I went ahead and created a new user on my Windows network, a network share for my "RigidBot" 3D Printer, and gave that user full control over the share, now we just have to mount it.

  • Start by installing the CIFS utilities by running sudo apt-get install cifs-utils.
  • Create a new file to store your network credentials. It's important that you use a credential file to avoid storing plain text credentials in our mount definition later. Create this file by running sudo nano ~/.smbcredentials.
  • Enter your credentials in this file. It is important that your file is structured the same way as the example below (username on one line, password on the next, etc.). If your user is affiliated with a domain, include the domain line.
    username=myUsername
    password=myPassword
    domain=myDomain
  • Once you've created your file, we need to set the appropriate permissions on it by running chmod 600 ~/.smbcredentials
  • Before we define our mount point, run id and make note of the output. This is likely something like 1000, but we'll need this number to ensure OctoPrint can correctly read and write to our share.
  • Now we're ready to define our mount point and tell the system how to connect. To do this, open up /etc/fstab by running sudo nano /etc/fstab. Here we'll enter a new row that defines the path to our share, the path to our local mount point, the file system type, and our credentials. Be sure to replace SERVERIP, SHARE, USERNAME and ID with your own values. Note that for this step, USERNAME is your Linux logon username, not the network credential. //SERVERIP/SHARE /media/SHARE cifs credentials=/home/USERNAME/.smbcredentials,sec=ntlm,uid=ID 0 0
  • Now, run sudo mount -a to tell the OS to process the changes to our fstab file. If all goes well, you'll now be able to cd /media/SHARE and see any content from your Windows share.

More to Come

In Part 2 we'll look at how to install and configure OctoPrint on the Pine64, setup webcam streaming to OctoPrint, and make our first print!