A Raspberry Pi Kiosk
After writing a simple kiosk of rotating quotes and images, I wanted to set up a Raspberry Pi to run the kiosk automatically, without needing a keyboard or any on-site configuration.
The Raspbian Desktop: Too Hard to Configure
Unlike my usual Raspberry Pi hacks, the kiosk would need a monitor and a window system. So instead of my usual Raspbian Lite install, I opted for a full Raspbian desktop image.
Mistake. First, the Raspbian desktop is very slow. I intended to use a Pi Zero W for the kiosk, but even on a Pi 3 the desktop was sluggish.
More important, the desktop is difficult to configure. For instance, a kiosk needs to keep the screen on, so I needed to disable the automatic screen blanking. There are threads all over the web asking how to disable screen blanking, with lots of solutions that no longer apply because Raspbian keeps changing where desktop configuration files are stored.
Incredibly, the official Raspbian answer for how to disable screen blanking in the desktop — I can hardly type, I'm laughing so hard — is: install xscreensaver, which will then add a configuration option to turn off the screensaver. (I actually tried that just to see if it would work, but changed my mind when I saw the long list of dependencies xscreensaver was going to pull in.)
I never did find a way to disable screen blanking, and after a few hours of fighting with it, I decided it wasn't worth it. Setting up Raspbian Lite is so much easier and I already knew how to do it. If I didn't, Die Antwort has a nice guide, Setup a Raspberry Pi to run a Web Browser in Kiosk Mode, that uses my preferred window manager, Openbox. Here are my steps, starting with a freshly burned Raspbian Lite SD card.
Set Up Raspbian Lite with Network and SSH
I wanted to use ssh on my home network while debugging, even though the final kiosk won't need a network. The easiest way to do that is to mount the first partition:
sudo mount /dev/sdX1 /mnt(sdX is wherever the card shows up on your machine, e.g. sdB) and create two files. First, an empty file named ssh
touch /mnt/ssh
Second, create a file named wpa_supplicant.conf with the settings for your local network:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="MY-WIFI-SSID" psk="MY-WIFI-PASSWORD" priority=10 }
Then unmount that partition:
sudo umount /mnt
Copy the Kiosk Files into /home/pi
The second partition on a Raspbian card is the root filesystem,
including /home/pi, the pi user's home dictory. Mount
/dev/sdX2, copy your kiosk code into /home/pi, and
chown
the code to the pi user. If you
don't know what that means or how to do that, you can skip this step
and load the code onto the Pi later once it's up and running, over the
network or via a USB stick.
Unmount the SD card and move it to the Raspberry Pi.
Raspbian First-boot Configuration
Boot the Pi with a monitor attached, log in as the pi user,
run sudo raspi-config
, and:
- set the locale and keyboard,
- change the password for user Pi,
- in Boot Options, choose “Desktop / CLI” and “Console Autologin” so the pi user will be logged in automatically.
So the installation won't become too bloated, I like to create the file /etc/apt/apt.conf containing:
APT::Install-Recommends "false"; APT::Install-Suggests "false";(That's the equivalent of the --no-install-recommends in the Die Antwort guide.)
Update the OS, and install the packages needed to run X, the Openbox window manager, a terminal (I used xterm), and a text editor (I used vim; if you're not familiar with Linux text editors, pico is more beginner-friendly). If you're in a hurry, you can skip the update and dist-upgrade steps.
$ sudo apt update $ sudo apt dist-upgrade $ sudo apt install xserver-xorg x11-xserver-utils xinit openbox xterm vim
I was surprised how little time this took: even with all of the X
dependencies, the whole thing
took less than twenty minutes, compared to the several hours it had
taken to dist-upgrade
all the packages on the full Raspbian
desktop.
Install any Kiosk-specific Packages
Install any packages you need to run your kiosk. My kiosk was based on Python 3 and GTK 3:
sudo apt install python3-cairo python3-gi python3-gi-cairo \ libgirepository-1.0-1 gir1.2-glib-2.0 python3-html2text(This also pulled in gir1.2-atk-1.0, gir1.2-freedesktop, gir1.2-gdkpixbuf-2.0, gir1.2-pango-1.0, and gir1.2-gtk-3.0, but I don't think I had to specify any of them explicitly.)
Configure Openbox
Create the Openbox configuration directory:
mkdir -p .config/openboxCreate .config/openbox/autostart containing:
# Disable screen saver/screen blanking/power management xset s off xset s noblank xset -dpms # Start a terminal xterm &
Save the file, and test to make sure you can run X:
$ startx
You should see a black screen, a mouse pointer, and after a few seconds, a small xterm window in the center of the screen. You can use the xterm to fiddle with things you want to change, or you can right-click anywhere outside the xterm window to get a menu that will let you exit X and go back to the bare console.
Test Your Kiosk
With X running, you can run your kiosk command. Don't change directories first; the pi user will be /home/pi ($HOME) after automatically logging in, so make sure you can run from there. For instance, I can run my kiosk with:
$HOME/src/scripts/quotekiosk.py $HOME/100-min-kiosk/slideshow/* $HOME/100-min-kiosk/quotes/*.html
Once the command works, edit .config/openbox/autostart and add your command at the end, after the xterm line, with an ampersand (&) after it. Keep the xterm line in place so you'll have a way to recover if things go wrong.
Configure X to Start When the Pi User Logs In
You've already set up the Pi user to be logged in automatically when the machine boots, but pi needs to start X upon login. Create the file .bash_profile containing:
[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && startx
You should be ready to go. Reboot, and the Pi should boot up in kiosk mode.
Run in a Loop
Everything working? For extra security, you might want to tweak the autostart file to run your kiosk in a loop. That way, even if the kiosk code crashes for some reason, it will be restarted.
while : do $HOME/src/scripts/quotekiosk.py $HOME/100-min-kiosk/slideshow/* $HOME/100-min-kiosk/quotes/*.html done
Don't do this until after you've tested everything else; it's hard to debug with the kiosk constantly popping up on top of other windows.
Get Rid of that Pesky Cursor
You might also want to remove that annoying mouse pointer arrow in
the middle of the screen.
Editing that startx
line you just added to .bash_profile:
[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && startx -- -nocursor
This step comes last — because once you've disabled the cursor, it will be difficult to use the machine interactively since you won't be able to see where your mouse is. (If you need to make changes later, you can ssh in from another machine, mount the Raspbian SD card on another machine, or use Ctrl-Alt-F2 to switch to a console window where you can edit files.)
... But It's Still Not Quite Hands-Off
The Pi is now set up to work automatically: just plug it in. The problem was the monitor. Someone contributed a TV, but it turned out to be a "smart TV", and it had its own ideas about what it would connect to. Sometimes the HDMI ports worked, sometimes it refused to display anything, and even when it worked, it randomly brightened and dimmed so that the screen was often too dim to see.
So I contributed my old 20" monitor. Everything worked fine at the demo the night before, and I handed it off to the people who were going to be there early for setup. When I arrived at the Roundhouse the next day, there was my monitor, displaying "No Signal". Apparently, while setting it up, someone had bumped the monitor's "Input Source" button; and of course no one there was up to the task of diagnosing that difficult problem. And no one bothered to call me and ask.
Once I arrived, I pressed the Source button a couple of times and the kiosk display was up and running for the rest of the day. Sigh. I can write kiosk software and set up Raspberry Pis; but predicting potential issues non-technical users might encounter is still beyond me.
[ 11:08 Feb 12, 2020 More tech | permalink to this entry | ]