|
|
Raspberry Pi Kiosk Project
IntroMy wife asked me to get a clock for the kitchen so I went to Amazon and was left with the choice of a crappy analog clock which would break in a couple of years or an overpriced digital one. Then it struck me: I had a 17" monitor in the closet with a VESA mounting backet doing nothing. I'd make a clock with a raspberry pi and it would be able to display more than just the time. Here's what it currently does:
Here's what it ends up looking like from the kitchen (click to embiggen):
Physical BuildThis is a pretty easy build, frankly. I did have to install an outlet and some blocking between the studs so the monitor would have power and be securely mounted. Luckily there was already a wire right behind the wall I was planning to mount this thing on with enough slack in it that I could get a box installed pretty easily. The blocking is a piece of scrap wood with pocket-hole screws attaching it to the studs. I didn't use a 2x4 because it needs to be taller than that to accommodate the VESA mount and I didn't have a 2x6.
I ended up velcroing the monitor's 14 volt power supply and the rpi itself to the back of the monitor, you can see them from the side but it's not too ugly. They're invisible from the front and no one seems to notice this stuff. I used a USB wifi adapter for network and a spare micro USB plug from the phone to power the rpi. Here's what it looks like from the side:
I actually ordered a 1-foot DVI cable and used a spare HDMI->DVI adapter for the video. In retrospect, the short cable doesn't really make the backside of the monitor any cleaner; just go with a long one coiled up. I also bought a 1-foot standard power cable to run the monitor's AC->DC power brick. Again, maybe not necessary. I wish the monitor had an integrated USB hub and speakers but it has neither requiring me to run the rpi from the other plug in the outlet I installed and meaning that I had to stuff a speaker up behind the monitor if I wanted any sound. I had a speaker they gave out at work (for some reason) so I used that. But it makes for kinda a mess behind the monitor. All invisible from the front, though.
Software SetupI thought about various ways to do the software and concluded that I'd just run a javascript capable browser in full screen mode and point it at a URL with a periodic refresh via javascript. A separate process would change what was at that URL periodically too. Unfortunately, there's no stable accellerated X Window server for rpi (yet) so I was concerned with the speed of rendering pictures. The default browser (Epiphany) does ok but I noticed the rpi Chromium port seemed faster at rendering my Google maps and full screen pictures so I went with that. To boot directly into X and fire up a browser in full screen mode I just chose to not wait for a login in the installer (sudo raspi-config) and then edited /etc/xdg/lxsession/LXDE/autostart. Google is your friend. Here are some links:
On the other side, I wrote a python script responsible for two things: choosing the next page to display and periodically rendering pages. It has one thread devoted to each task:
I decided to keep the time/date on the top line of each page so the kiosk is useful as a clock no matter what page it's currently displaying. In the end, I also decided to mix in the analog clock page frequently with the chooser thread. I did have some problems keeping the wifi up and stable on the Rpi. I used a little Edimax USB wifi adapter which turned out to be a Realtek chipset. It worked ok but cut out from time to time. I stole a script to ping a nearby machine and, if it doesn't work, up/down the wifi interface which I then ran in a cronjob which seemed to do the trick:
#!/bin/bash wlan='wlan0' pingip='10.0.0.13' # Perform the network check and reset if necessary /bin/ping -c 2 -I $wlan $pingip > /dev/null 2> /dev/null if [ $? -ge 1 ] ; then /usr/bin/logger -p daemon.info "Network is DOWN. Perform a reset." echo "Network is DOWN. Perform a reset." /sbin/ifdown $wlan sleep 5 /sbin/ifup --force $wlan exit 1 else exit 0 fi Finally, I found a thread about how to turn the monitor on/off with power management commands on the HDMI port and added a cronjob to power off the monitor when no one was around:
#!/bin/bash -e # Script to enable and disable the HDMI signal of the Raspberry PI # Inspiration: http://www.raspberrypi.org/forums/viewtopic.php?t=16472&p=176258 CMD="$1" function on { /opt/vc/bin/tvservice --preferred # Hack to enable virtual terminal nr 7 again: chvt 6 chvt 7 } function off { /opt/vc/bin/tvservice --off } function must_be_root { if [ $USER != root ]; then echo "ERROR: Script must be executed as the root user" exit 1 fi } function main { must_be_root if [ "$CMD" == "on" ]; then on elif [ "$CMD" == "off" ]; then off else echo "Usage: $0
AcknowledgementsThank you to Toby Pitman for posting this really cool article (and javascript / css / image) explaining how to make a running analog clock webpage. See: http://css-tricks.com/css3-clock Thank you to Guy Carpenter for putting his gdata Oauth module on github. I stole and and modified it a bit. I understand the motivation is in keeping user data secure but I do wish that Google had not made the Oauth model for interacting with their APIs so cumbersome. I'd rather hardcode an app-specific password with limited capabilities, thank you. To do what I've done with fetching photos, Google docs, etc... you will need to set up a project on the Google developer console and configure it to request read access to your calendar, docs, photos, etc... basically anything it needs to show on the kiosk. When you fire up the kiosk python script for the first time it will give you a URL to type into your web browser and permit access to your data. If all goes well, you won't have to do it again. Thanks also to everyone who has taken the time to write up guides for configuring the rpi. It may be old hat for you linux people but I'm a FreeBSD guy which makes figuring out simple things on the pi sometimes more difficult. Especially "pjc" on this thread from whom I stole the script to fix my flaky wifi and "simlun" on this thread. All of my kiosk code (minus the secret API keys) is available on my local git repository. Hopefully helpful, no warranties, no copyright, use as your own risk. And let me know if you end up using the python code for anything or find any bugs. |