Whiteboard photo snapper
Six people live in my house. We don't have strong technology overlap (some folks in the house only use simple phones and others aren't keen on things like slack or similar). We've addressed this by centralizing around a large whiteboard in our kitchen space. This holds things like grocery lists, house announcements, and similar. I often do grocery shopping on my way home, but rarely remember to snap a photo of the list before leaving for work.
The compromise is a little raspberry pi which periodically sends photos of the whiteboard up to our house website. There were three main aspects of this project: capturing an image, putting it on the website, then setting it up to happen on a recurring basis.
Capturing the photo
For photo snapping, a roommate gave me an old webcam to use. I learned
that you can use lsusb
to list the USB entries. The output looks
like this:
$ lsusb Bus 001 Device 006: ID 046d:081b Logitech, Inc. Webcam C310 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
You can get more information on a device by specifying the bus and device. The verbose flag dumps out tons of output, but you can grep for width and height.
$ lsusb -s 001:006 -v | egrep "(Width|Height)"
...
wWidth 1024
wHeight 576
wWidth 1184
wHeight 656
wWidth 1280
wHeight 720
wWidth 1280
wHeight 960
...
This told me the maximum resolution for the webcam was 1280x960.
From here, we needed to snap a photo. I tried commands with vlc
, guvcview
and ffmpeg
.
VLC
VLC had the benefit of popping up a live video feed of the webcam,
which allowed me to validate it worked. This command didn't seem to
stop on its own (which I believe it should have done with the
vlc://quit
directive..), which wasn't a good fit for my usecase.
vlc \ -I dummy \ v4l2:///dev/video0 \ --video-filter scene \ --no-audio \ --scene-path /tmp/testing-for-video \ --scene-prefix img_prefix \ --scene-format png \ vlc://quit \ --run-time=1
guvcview
guvcview was good and supported doing the timing work on its own. This would mean I could keep it running as a daemon and have it dump files. Unfortunately, it kept popping up with a GUI frame, even though I didn't want one.
guvcview \ --resolution 800x600 \ --image /tmp/testing-for-video/my-test.png \ --photo_timer 5 \ --photo_total 1 \ --gui=none
ffmpeg
ffmpeg seemed to do the simple thing of taking a photo of the webcam and dumping it into the place I asked it to.
ffmpeg -y \ -f video4linux2 \ -i /dev/video0 \ -vframes 1 \ -vf scale=1280x960 \ /home/pi/kitchen-webcam-snaps/whiteboard_photo/latest.jpg
Getting the photo to the server
I made a new directory in the webroot for my server. I made a little 'whiteboard uploader' account on it and set up the necessary ssh keypair trusts. Originally, I was looking to save the image on disk and have a periodic rsync to the remote server. Given the lifespan of the SD card in my raspberry pi (notoriously short), we should try to write as little as possible.
To solve this, I mounted my uploader's home folder on the remote
server to the local disk. The follow_symlinks
portion is important
because there is a symlink in that user's home directory to the
webroot where the image should live.
sshfs -o follow_symlinks upload-user@pdxgrouphouses.org:/home/upload-user $PWD/kitchen-webcam-snaps
Putting it together
I have a simple crontab entry which runs every 4 hours.
0 */4 * * * /home/pi/webcam-snap.sh
This executes the script which will mount the remote folder locally if it's not done, then take a snap of the webcam.
#!/bin/bash # Mount file system if it's not already mounted (df | grep pdxgrouphouses.org) || \ sshfs -o follow_symlinks upload-user@pdxgrouphouses.org:/home/upload-user /home/pi/kitchen-webcam-snaps ffmpeg -y \ -f video4linux2 \ -i /dev/video0 \ -vframes 1 \ -vf scale=1280x960 \ /home/pi/kitchen-webcam-snaps/whiteboard_photo/latest.jpg