Monday, October 13, 2014

A #RaspberryPi Webcam / Trick or Pi Redux!

I see it is time for my annual post, so I have decided to redo and (hopefully) improve on last year's time lapse Halloween Door Cam.

As I didn't include it in the last episode, here is a recap of the materials used:


  • Raspberry Pi Model B (of course!)
  • MicroSoft HD LifeCam
  • Edimax WiFi USB dongle
  • Lexar 32GB USB drive
  • Generic 4GB SD card. 
  • Powered USB hub
For some reason, I had an install of RaspBMC already on this SD card, so I decided to go with it (read: lazy). I am pondering setting a small monitor by the window, and playing some sort of atmospheric videos on it for the kids, but for now I'm going to focus on the cam. 

First order of business was to install Nginx, a webserver. 
sudo apt-get install nginx
Next, I mounted the 32GB USB drive as a subdirectory under the web server's default directory. So edit the fstab, and set /dev/sda1 as /usr/share/nginx/www/cam, so that I wouldn't fill the poor lil SD card with a lot of pics. Inside the 'cam' directory, I created a small index file as follows:

(html)(head)
(meta http-equiv="refresh" content="90")
(title)Testing Cam 1.6(/title)
(/head)
(body bgcolor=black text=white)
(h1)Halloween cam 1.6(/h1)
(P)
Front door view: Click (a href=daily/)here
for daily videos
(br)
(img src=cam.jpg)
(/body)(/html)

 


This of course refreshes the page every 90 seconds, and as we will see later, this produces either a brand new picture, or an error message. Now on to the more interesting bits.

Building on last year's work, I have used fswebcam. Again I will take 4 frames every minute, and write it to a cam.jpg that is mentioned in the web page code. So I have a small shell script that takes the current cam.jpg, renames it with a date stamp, and moves it to another directory for later. After that, it fires up fswebcam and takes a snap, naming it cam.jpg. I run this every minute in cron. 

Here is that code

#!/bin/bash
# Timelapse controller for USB webcam

DIR=/usr/share/nginx/www/cam/

x=1
while [ $x -le 4 ]; do

filename=$(date +"%d%m%Y_%H%M-%S").jpg

mv /usr/share/nginx/www/cam/cam.jpg /usr/share/nginx/www/cam/pics/$filename

# fswebcam -q -d /dev/video0 -r 800x600 --flip v,h --set brightness=100$ --font /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf --top-banner --title "Door Cam Mark 1.6" /usr/share/nginx/www/cam/cam.jpg
fswebcam -q -d /dev/video0 -r 1280x720 -S 10 --flip v,h --font /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf --top-banner --title "Door Cam Mark 1.6" /usr/share/nginx/www/cam/cam.jpg
 x=$(( $x + 1 ))

 sleep 10;


 done;

The most important setting, turned out to be -S  to skip a few frames and allow the white balance/brightness to adjust. Before I rediscovered this option, from just after dawn to dusk was just a white box. 

And now to the "for later" mentioned before. If I didn't want to do this next step, I could just leave the script creating a new cam.jpg every minute or so, available at check in. This would also greatly reduce the likelihood of having an error image when trying to load the picture as fswebcam is creating it. However, my next fun trick is to create a time lapse video, using all the pictures of the day. This code is here for the MP4 version. 


date=$(date +"%d%m%Y")
ls /usr/share/nginx/www/cam/pics/*.jpg > /usr/share/nginx/www/cam/list.txt

mencoder -nosound -of lavf -lavfopts format=mp4 -ovc x264 -sws 9 -x264encopts nocabac:level_idc=30:bframes=0:bitrate=512:threads=auto:turbo=1:global_header:threads=auto:subq=5:frameref=6:partitions=all:trellis=1:chroma_me:me=umh -vf scale=-8:-8,harddup -o /usr/share/nginx/www/cam/daily/$(date +"%d%m%Y").mp4 -mf type=jpeg:fps=10 mf://@/usr/share/nginx/www/cam/list.txt


rm /usr/share/nginx/www/cam/pics/$date*.jpg

I create a list of all the jpg files, put this in a txt file, and run it through mencoder to create an avi file. I am experimenting with creating mp4/x264 instead, as it will be playable on a few more devices. 

I believe I will eventually opt to offload the video encoding to another machine, as the Pi is not exactly a CPU powerhouse. Using mp4/x264, it took the poor lil Pi about 5-6 hours to create the video. 

Obligatory sample pic from the cam:


Epic mounting and duct tape:



Link to youtube video coming soon!

Wednesday, October 16, 2013

A #RaspberryPi Webcam / Trick or Pi

*Please note, this is not intended as a full HOWTO. If my kludging along helps you, awesome. If I have confused you more, apologies. As is the case with the rest of this blog, this is mostly so I can look things up for myself. *

It is almost Halloween, and while standing in my kitchen, I was looking at my door thinking about the kids that will be trick or treating there soon. I also thought about my Raspberry Pi. How nice it would be if I could see who is at the door from my computer or tablet? Very nice indeed, and not only for this holiday, but to check for deliveries and general security.

I had bought a discount MicroSoft web cam earlier this year, as I had intended to set up a "kitty cam", but being the professional procrastinator I am, that didn't happen. I've checked it with the Linux video HCL, and it is supported.

Motion

Doing some research on this subject, the most popular software package to use is Motion. So after downloading NOOBS from raspberrypi.org, I booted up and chose Rasbian. (I do want to learn about Arch at one point, but that is for another day). I had earlier in the day chosen to boot to desktop GUI, however I saw the CPU meter being maxed out.
What I am finding about the Motion package, is that it is not compatible with any browser other than FireFox, and occasionally Safari on my iPhone. This is a bit problematic, as I prefer Chrome on both my desktop and my mobile platforms. Added to that issue, it seems to work for a while, and randomly cut out. Either it will stop responding to requests from the browser, or it will put up an error of "unable to open video device". When it works, it works amazingly well.
I like what motion does, and unfortunately it is not going to meet my needs for this project.

fswebcam

I searched around for a more custom and scripted way to have a steady webcam, and found this post from James Bruce describing how he set up a Pi with attached camera(s) to snap a pic every minute for a given counter. I tried his script and it worked with my MicroSoft cam, so I set about modifying it for my needs.




#!/bin/bash
# Timelapse controller for USB webcam

DIR=/home/pi/timelapse

x=1
while [ $x -le 4 ]; do

filename=$(date +"%d%m%Y_%H%M-%S").jpg

mv /var/www/test.jpg /var/www/camarch/$filename

 fswebcam -d /dev/video0 -r 800x600 --flip v --flip h --top-banner --title "Door Cam Mark 0.5" /var/www/test.jpg

x=$(( $x + 1 ))

sleep 10;

done;

Based on James' code, I changed down from 1440 or so to 4, and added a cron job to fire it every minute. This produces 4 pictures per minute. Next, I grab the date/time to attach to the file name that I am going to move. Then I move the file "test.jpg" to an archive folder, renaming it to that minute, with a counter. (This does however, create wrong file names, with a file actually taken at 13:11 having a file name of 13:12 for example. To be fixed in later versions.)

The next line is the actual capture command, which I have modified by making the image size larger, and adding the --flip for both vertical and horizontal, as my cam will be mounted upside down in the top corner of the door's window. Also, I moved the banner to the top of the image, and titled it with "Door Cam Mark 0.5" (I'm lookin' at you Tony Stark ;) )

Then it increments the counter and sleeps for 10 seconds. (I chose 4 pictures to ensure that the process would not overlap the 1 minute cron job, as it sometimes takes fswebcam a few seconds to process the picture)

As you can imagine, taking 4 frames a minute for 24 hours creates a major amount of files. I decided that to deal with this, I would make time lapse videos of the day. So I created a cron job at 23:59 daily, that creates a list the JPG files in the "camarch" directory, then runs a mencoder command. This creates a nice AVI file of the events in the time lapse, looking exactly like all the other time lapse videos you've ever seen. After this video is created, I delete the JPG files from the previous day. 
date=$(date +"%d%m%Y)
ls /var/www/camarch/*.jpg > /var/www/camarch/list.txt

mencoder -nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=16/9:vbitrate=8000000 -vf scale=640:480 -o /var/www/camarch/$(date +"%d%m%Y").avi -mf type=jpeg:fps=10 mf://@/var/www/camarch/list.txt

rm /var/www/camarch/$date*.jpg
I intend to set a weekly cron job to combine the week's daily videos and name it something like "week-of-DDMM-DDMM". 

I have learned a few interesting things during this experiment, and I want to be able to use the motion package in a semi-interactive Halloween/other holiday video system. I may need to actually learn programming in order to do this, however. 

Currently, this project is 90% working, however that last 10% is a fairly vital part: the WiFi connection. I know this WiFi dongle works, and works under Linux, as it was running my RaspBMC. With the Pi being nice and small, only needing the power cable and the webcam's USB cable, it isn't a "big deal" right now to pick it up and put it back on my workbench to copy the day's files, though it does create a hole. I am going to install RaspBMC on my other Pi and then replicate the fswebcam setup after verifying it does in face connect to WiFi. Bonus for this; the layout of my apartment is such that I will be putting the Pi next to my projector/Xbox so I could use the XBMC features again, while maintaining the "who's there" webcam. :)

I will update this post at some point in the future with a few pictures of the "professional level" mounting I will be doing :)


Sample pic:

Sunday, October 21, 2012

iPhone 5 first week

I have moved up the "smart/super phone" food chain, to what is arguably the top. I started this race with a Nokia N97, which was not even a "clever phone". I obtained a second hand Samsung Galaxy S to replace the N97. I actually quite liked the experience that it provided, though I couldn't "legally" update the OS on it. Now with the iPhone 5 in my hands for the last week, I'm impressed with some things, and not so much with others.

First off, the phone feels great in my hand. I originally thought the box shape would be uncomfortable, though it is quite nice. I have larger hands than some people, and my thumb not only reaches all the screen, but also the buttons on the opposite side. I admit I was a bit disappointed with the screen size only increasing to 4", also disappointed that it wasn't a standard 720p (1280x720) resolution opting for 1136x640 instead. I am slowly getting over these disappointments as I get used to the device.

iOS 6 preforms better on the iPhone than on the iPad 2, which is as promised with the increase in RAM and CPU power. Even with many apps "open", switching between them and opening more apps has been very seamless. The on screen keyboard in iOS is better than the one in Android 2.3 that my Galaxy S has, though neither match my work BlackBerry's hardware keyboard for accuracy with my particular thumbs. Coming from the Galaxy S, I find myself trying to push the back and menu buttons that were on either side of the "home" button in the hardware. Autocorrect has been an annoyance off and on, especially with slang terms or txt specific spellings. Just when I think I've trained it, the next time I type it autocorrects to something completely wrong.

I'm not sure if it is because in my area there is no LTE coverage yet, but Siri seems slow to respond, and every once in a while it feels like playing the telephone game with MicroSoft Bob. iMessage and FaceTime work very well, and the "HD" FaceTime camera looks great. I haven't fully explored the camera yet, but the few test shots, videos and panoramas I took are starting to rival the basic shots I take with my Canon T1i.

The GPS seems to be a bit off as well, showing me as across the street from where I am in most cases, and once showing me a good 5 minute drive across the river from where I was. My girl tells me that where she lives, the GPS is spot on, so I think this might have something to do with why people have issues with the Apple Maps program.  I was hoping I could use the geofencing features to do things like turn the WiFi off and on when I leave/get home. To date I haven't found out how to do that.

What can I say about iTunes that hasn't already been complained about more eloquently somewhere else? I'm disappointed that in this "post PC era" I still have to connect to to the computer and use iTunes to transfer my non iTunes store bought music, audiobooks, etc to the device. (I know there are various iTunes alternatives out there, but that still defeats the "post PC era" rhetoric) There is supposed to be a new iTunes "in October", so Apple has 10 days left to release, and hopefully this will help.

The inability to mount the device as a USB mass storage and drag/drop things, not (as of yet) being able to go even to a gas station or dollar store and pick up a spare charge cord , and having to be in OS X to develop are my only major complaints.

Overall I'm very happy with the iPhone, granted I haven't had access to the major competition. There are enough things right with the phone that I am looking forward to the next 3 years or so with the device.

Saturday, June 2, 2012

My #OpenBSD Adventure: Part 3

Life is very disrespectful of projects isn't it?

For those just joining the program, I currently have my OpenBSD machine with base PF rules (pass all) and a D-Link WiFi-N base station. I have two major points on the todo list, hoping to achieve at least one today.
1. Install Squid ( http://www.squid-cache.org ) and set up as a transparant proxy, with ad/spam blocking.
2. Install and enable third NIC to separate the WiFi segment.

Tackling the first point, I've downloaded the Squid source. I'm going to use

./configure --enable-pf-transparent 

I have a feeling I'm going to need to use --enable-auth-helpers="(something)" in the future for the captive portal part of the project, but for now I will just try to get things running.

I forgot how long things take to compile from source. Even on a fairly hefty machine, Squid took about 20 minutes start to finish. There seems to be an issue on OpenBSD. The Squid user by default does not have write access to the var/log or var/cache directories.

Appending the lines


pass in on em0 proto tcp from any to any port 80 rdr-to 127.0.0.1 port 3128


pass in on em0 inet proto tcp from any to 127.0.0.1 port 3128 keep state
pass out on xl0 inet proto tcp from any to any port www keep state


forced all the web traffic from my machines through Squid, which I was able to verify by way of an ACL in squid.conf that blocked reddit. It is worth noting here that in the newest PF, the syntax has changed quite a bit. The old way was to

rdr on $if ....

and the new way is

pass in on $if ....rules... rdr-to ....

This had me scratching my head for a while this afternoon, as every guide for exactly transparent Squid/PF was using the old syntax.

In squid.conf, I put these lines

acl badurls url_regex "/usr/local/squid/etc/block.txt"
http_access deny badurls


/usr/local/squid/etc/block.txt contained the single line of "reddit" for now, I will be filling this with ad/annoying web urls at a later time.

Right now, if the browser is set to use 10.0.0.1/3128 as the proxy, all works well. If browser has no proxy set, Squid returns an error about malformed URLs. For now, I have disabled the rdr line.
Well that was easy as reading a little bit. Adding "transparent" to the line in squid.conf got it up and running.

http_port 3128 transparent

Next up, tackling the authentication bits. Plan is to have the WiFi segment require authentication and have rules based on device/user, and the hard wired lan be open. (Only people I know will be plugging in)


Wednesday, May 23, 2012

My #OpenBSD Adventure: Part 2

I woke up this morning to be greeted by

Write failed: Broken pipe
cvs [checkout aborted]: end of file from server (consult above messages if any)

So like the true Windows admin I let myself become, I decided to download a -current iso, in the hopes that the patch for the Belkin USB would be applied. 

5.1-current, 5/21/12, installed and Belkin recognized and available as urtwn0! Ah the joys of living on the edge. I apparently did not read quite well enough. In my excitement to see an actual USB device in my hand, I did not notice the lack of (AP) next to the urtw in http://www.openbsd.org/faq/faq6.html#Wireless  so it is back to the store to exchange the USB for a low end WiFi router. 

I now have a D-Link DIR-601 for about $12 less (tax in) than the Belkin, and will be using the Prosys/3Com 10/100 extra NIC to control wireless. I may have to write a review/rant on the oddities of consumer network hardware, as that wizard is a bit crazy. 

Command to enable forwarding:

echo net.inet.ip.forwarding=1 >>/etc/sysctl.conf

My quick dhcpd.conf to just get it up and running

#       $OpenBSD: dhcpd.conf,v 1.2 2008/10/03 11:41:21 sthen Exp $
#
# DHCP server options.
# See dhcpd.conf(5) and dhcpd(8) for more information.
#

# Network:              192.168.1.0/255.255.255.0
# Domain name:          my.domain
# Name servers:         192.168.1.3 and 192.168.1.5
# Default router:       192.168.1.1
# Addresses:            192.168.1.32 - 192.168.1.127
#
option  domain-name "mynet";
option  domain-name-servers 10.0.0.1;

subnet 10.0.0.0 netmask 255.255.255.0 {
        option routers 10.0.0.1;

        range 10.0.0.40 10.0.0.90;

        host static-client {
                hardware ethernet 22:33:44:55:66:77;
                fixed-address 192.168.1.200;
        }

        host pxe-client {
                hardware ethernet 02:03:04:05:06:07;
                filename "pxeboot";
                next-server 10.0.0.1;
        }
}

Quick pf.conf to just get up and running

pass out on xl0 from em0:network to any nat-to (xl0)

(epic eh? ;) )

Well, this is it for tonight. I hope to move the DIR-601 to NIC #3 and set it on its own subnet tomorrow.