Motion Sensor System with Mobile Notifications and NFC Activation

I call the project things2c or "things to see" - a reference to both the video recording aspect and the Internet of Things (IoT). Basically, I had a solution looking for a problem (a couple Raspberry Pis, some NFC gadgetry, etc.) and was inspired by an article describing how to use a Raspberry Pi as low-cost HD surveillance camera.

What does it it do?

The system sends me alerts on my phone when motion is detected in my apartment unless the NFC tag on my keychain is close to the sensor inside my front door. Once the NFC tag is detected and the motion detection is turned off, a nice calming green LED flashes periodically. Video clips/previews are uploaded to Amazon S3 or ownCloud where they may be synced to a mobile device.

What is it not?

I do not claim this is a serious security appliance. There are various ways to thwart the system and I haven't given any serious thought to hardening it. For me, it was just a fun project.

Hardware

Software

Cloud Services

Design Diagram

things2c design

Usage

$ python things2c.py --help
Usage:
  things2c [options] nfc_scan
  things2c [options] motionctl
  things2c [options] watchdog
  things2c [options] blinkctl
  things2c [options] notify <notify_text>
  things2c [options] publish
  things2c [options] snoop
  things2c [options] filemanager
  things2c version

Sub-commands:
  nfc_scan          NFC scan/report
  motionctl         Control motion sensor
  watchdog          Watchdog for motion control
  blinkctl          Control status blink(1)
  notify            Send notifications
  publish           Publish topic/payload to MQ
  snoop             Output all MQTT traffic
  filemanager       Upload/delete video files
  version           Display version and exit

Options:
  -h --help         Print usage
  -c --config=FILE  Configuration file [default: /etc/things2c/things2c.ini]
  -v --verbose      Verbose/debug output
  -t --topic=TOPIC  Topic to publish
  -p --payload=PL   Payload for publish
  -e --encode       Encode payload

Build Notes

To build a standalone binary using pyinstaller, refer to Dockerfile_things2c for x86. To build for the Raspberry PI, I used the following after installing the needed Python modules (requirements.txt):

$ pyinstaller --hidden-import nfc.clf.pn533 --onefile ./things2c.py

Deployment Notes

I deploy with Ansible - refer to playbook.yml.

License for things2c

MIT

UMR college dormitory floor web page from 2000

For those of you who don't know, I'm a bit of a digital pack rat. When perusing some of my old archives, I came across the web page I built for our college dormitory floor back in 2000: Thomas Jeffereson South 4th floor (TJ4S) at University of Missouri - Rolla (now known as Missouri University of Science and Technology).

For your viewing pleasure, I've uploaded the TJ4S webpage from 2000. Aren't those JavaScript rollover images amazing? To keep things historically accurate I've uploaded the page as-is. Therefore, some links (such as those to www.umr.edu) are broken. At least I knew enough at the time to use relative paths for all the TJ4S page links.

Back in the Day: Static Line Jump

Perhaps this is more suited for throwback Thursday, but I came across this old video from college and thought I'd put it on the blog while I was thinking about it. Of course, I had to use that as an excuse to write a Jenkins job to upload videos to s3 (incorporating what I learned from posting the duet by Kenton and Duane). It's Tuesday so at least #TBT still works :P

I used aproxacs/s3sync to upload to S3. To make everything readable by the public by default in the video bucket, I used an example from amazon.com: Granting Read-Only Permission to an Anonymous User.

It was pretty straight forward - the only hiccup was that s3sync doesn't want to upload individual files - I had to create a directory and then call s3sync like:

s3sync ./${SYNC_DIR}/ nathangraham.info.videos:


Here's Jenkins build step (shell command) - UPLOADED_FILE and PREVIEW_FILE are file parameters.

# Can't get s3sync to work without copying directory contents!
SYNC_DIR=upload

mkdir -p ${SYNC_DIR}

mv UPLOADED_FILE ${SYNC_DIR}/${UPLOADED_FILE}
mv PREVIEW_FILE ${SYNC_DIR}/${PREVIEW_FILE}

NEW_FILE_NAME=${UPLOADED_FILE}.mp4
ffmpeg -i ${SYNC_DIR}/${UPLOADED_FILE} -c:a libfdk_aac -c:v h264 -preset medium -crf 25 ${SYNC_DIR}/${NEW_FILE_NAME}

s3sync ./${SYNC_DIR}/ nathangraham.info.videos:

cat << EOF > URLs.txt
URLS for setting up JWPlayer for your account:
https://s3.amazonaws.com/nathangraham.info.videos/${UPLOADED_FILE}
https://s3.amazonaws.com/nathangraham.info.videos/${PREVIEW_FILE}
EOF

Duet by Kenton and Duane

Kenton and Duane were nice enough to perform a duet for us!



I had some trouble rotating the video without cropping - I used a solution I found: Correct Smartphone Orientation. Though, I used avconv not ffmpeg.

Then, I found that with the original version, the audio didn't work on an iPhone 5. Why not? Well, it appears that iOS supports a very few options when it comes to audio/video codecs.

According to ios-video-encoding (link now broken, see also how-to-play-mp4-on-ipad):

> - H.264 video codec up to 1080p, 30 frames per second FPS, High Profile level 4.1 with AAC-LC audio codec up to 160 Kbps, 48kHz, stereo audio with .m4v, .mp4, and .mov video container;
> - MPEG4 video codec up to 2.5 Mbps, 640 by 480 pixels, 30 frames per second, Simple Profile with AAC-LC audio codec up to 160 Kbps per channel, 48kHz, stereo audio with .m4v, .mp4, and .mov video container;
> - Motion JPEG (M-JPEG) up to 35 Mbps, 1280 by 720 pixels, 30 frames per second, audio in ulaw, PCM stereo audio with .avi as video container.

For the video I posted, VLC says I'm using "MPEG Audio layer 1/2/3 (mpga) 44100 Hz, 256 kb/s"

Oh, so no problem, right? I just re-encode the video with the appropriate codec. Well, not so fast. According to Encoding AAC on the libav site:

> Libav provides an experimental native encoder for aac and wraps higher quality third party libraries.
> ...
> The native encoder is experimental and known to have serious flaws, help on improving it is welcome. Do not use it in production.

According to the FFMPEG page about AAC, those 3d-party codecs aren't free:

> The licenses of libaacplus, libfaac, and libfdk_aac are not compatible with the GPL, so the GPL does not permit distribution of binaries containing code licensed under these licenses when GPL-licensed code is also included. Therefore these encoders have been designated as "non-free", and you cannot download a pre-built ffmpeg that supports them.

Back over to Libav, I can apparently use the AAC codec - it's just that the binary program containing the codec cannot be distributed:

> fdk-aac custom license is non-free, Libav compiled with it results being not redistributable.

Sigh...well...it looks like the Fraunhofer codec is the best choice:

> The VisualOn AAC encoder is rather spartan, supports up to 2 channels and the only setting supported is bitrate. It is suggested mainly because it is free-software compatible and redistributable. To achieve best results use the Fraunhofer one.

Hmm...well, I suppose I'll build ffmpeg myself and include the non-free stuff (installing the binary to my home directory). So, following FFMPEG Install Guide, I installed the necessary packages and codecs.

Then, to configure:

PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --prefix="$HOME/ffmpeg_build" \
  --extra-cflags="-I$HOME/ffmpeg_build/include" \
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
  --bindir="$HOME/bin" \
  --enable-gpl \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libtheora \
  --enable-libvorbis \
  --enable-libx264 \
  --enable-nonfree \
  --enable-x11grab

And the usual make, make install stuff...

Now, to give it a try:

njgraham@mercury /tmp/codec $ ~/bin/ffmpeg -i kenton_duane_duet.mp4 -c:a libfdk_aac -c:v h264 -preset medium -crf 25 kenton_duane_duet_for_apple_babies.mp4

That seems to have worked! VLC now says The video codec is H264 - MPEG-4 AVC and the audio codec is MPEG AAC!

Also, it's a _lot_ smaller.

njgraham@mercury /tmp/codec $ ls -lh
total 25M
-rw-r--r-- 1 njgraham njgraham 1.9M Dec 30 14:21 kenton_duane_duet_for_apple_babies.mp4
-rw-r--r-- 1 njgraham njgraham  23M Dec 28 15:15 kenton_duane_duet.mp4