This project turns the ASUS EEE V4L2 integrated (in the lid) webcam into a security monitoring system, which will automatically take a snapshot of the best picture it sees, draws a box around the motion it detected, uploads that picture to Twitter, and then send an SMS message to my phone telling me about the event. Since I have Twitter on my phone, I can look right at the picture which was uploaded, even while I'm on the road, to see what the motion was.
OK, to get started, I took most of this from http://www.i-hacked.com/content/view/277/1/
Some necessary notes: motion cannot be obtained correctly from a synaptic update (I tried). You need a motion version of 3.2.11 or better, which, as the above URL states, can be obtained by the below. But in order for the below to work, you first need all the libraries. The easiest way to do this for me was to install motion with Synaptic, which installed all the dependent libraries, and then remove JUST motion, leaving all the libraries. Then run the below.
mkdir ~/motioncd ~/motion
wget http://prdownloads.sourceforge.net/motion/motion_3.2.11-1.ubuntu.hardy_i386.deb?download
sudo dpkg -i motion_3.2.11-1.ubuntu.hardy_i386.deb
Don't worry, the Hardy version works with Gutsy.
Then, you'll need to change the motion.conf file that they suggested to
minimum_frame_time 0 # I tried to make this something higher than zero, but only 0 worked for me
ppm off # not sure if this was needed, but adding it allowed video to be uploaded
That's about it! Here are the necessary files (I can't include them as attachments, as stupid GoDaddy won't let me upload executable scripts.) But before the files, here is a screenshot!
Here's the same pic from my iPhone:
OK, to get started, I took most of this from http://www.i-hacked.com/content/view/277/1/
Some necessary notes: motion cannot be obtained correctly from a synaptic update (I tried). You need a motion version of 3.2.11 or better, which, as the above URL states, can be obtained by the below. But in order for the below to work, you first need all the libraries. The easiest way to do this for me was to install motion with Synaptic, which installed all the dependent libraries, and then remove JUST motion, leaving all the libraries. Then run the below.
mkdir ~/motioncd ~/motion
wget http://prdownloads.sourceforge.net/motion/motion_3.2.11-1.ubuntu.hardy_i386.deb?download
sudo dpkg -i motion_3.2.11-1.ubuntu.hardy_i386.deb
Don't worry, the Hardy version works with Gutsy.
Then, you'll need to change the motion.conf file that they suggested to
minimum_frame_time 0 # I tried to make this something higher than zero, but only 0 worked for me
ppm off # not sure if this was needed, but adding it allowed video to be uploaded
That's about it! Here are the necessary files (I can't include them as attachments, as stupid GoDaddy won't let me upload executable scripts.) But before the files, here is a screenshot!
Here's the same pic from my iPhone:
# TwitterSecuritySystem motion.conf
# This config file was created for motion 3.2.11
# This config file was created for motion 3.2.11
############################################################
# Daemon
############################################################
# Daemon
############################################################
# Start in daemon (background) mode and release terminal (default: off)
daemon on
daemon on
# File to store the process ID, also called pid file. (default: not defined)
process_id_file /var/run/motion/motion.pid
process_id_file /var/run/motion/motion.pid
###########################################################
# Capture device options
############################################################
# Capture device options
############################################################
# Videodevice to be used for capturing (default /dev/video0)
videodevice /dev/video0
v4l2_palette 8
videodevice /dev/video0
v4l2_palette 8
# The video input to be used (default: 8)
# Should normally be set to 0 or 1 for video/TV cards, and 8 for USB cameras
input 8
# Should normally be set to 0 or 1 for video/TV cards, and 8 for USB cameras
input 8
# The video norm to use (only for video capture and TV tuner cards)
# Values: 0 (PAL), 1 (NTSC), 2 (SECAM), 3 (PAL NC no colour). Default: 0 (PAL)
norm 1
# Values: 0 (PAL), 1 (NTSC), 2 (SECAM), 3 (PAL NC no colour). Default: 0 (PAL)
norm 1
# Rotate image this number of degrees. The rotation affects all saved images as
# well as mpeg movies. Valid values: 0 (default = no rotation), 90, 180 and 270.
rotate 0
# well as mpeg movies. Valid values: 0 (default = no rotation), 90, 180 and 270.
rotate 0
# Image width (pixels). Valid range: Camera dependent, default: 352
width 320
width 320
# Image height (pixels). Valid range: Camera dependent, default: 288
height 240
height 240
# Maximum number of frames to be captured per second.
# Valid range: 2-100. Default: 100 (almost no limit).
framerate 2
# Valid range: 2-100. Default: 100 (almost no limit).
framerate 2
# Minimum time in seconds between capturing picture frames from the camera.
# Default: 0 = disabled - the capture rate is given by the camera framerate.
# This option is used when you want to capture images at a rate lower than 2 per second.
minimum_frame_time 3
# Default: 0 = disabled - the capture rate is given by the camera framerate.
# This option is used when you want to capture images at a rate lower than 2 per second.
minimum_frame_time 3
auto_brightness off
brightness 0
contrast 0
saturation 0
hue 0
brightness 0
contrast 0
saturation 0
hue 0
############################################################
# Motion Detection Settings:
############################################################
# Motion Detection Settings:
############################################################
# Threshold for number of changed pixels in an image that
# triggers motion detection (default: 1500)
threshold 1500
# triggers motion detection (default: 1500)
threshold 1500
# Automatically tune the threshold down if possible (default: off)
threshold_tune off
threshold_tune off
# Noise threshold for the motion detection (default: 32)
noise_level 32
noise_level 32
# Automatically tune the noise threshold (default: on)
noise_tune on
noise_tune on
# Despeckle motion image using (e)rode or (d)ilate or (l)abel (Default: not defined)
# Recommended value is EedDl. Any combination (and number of) of E, e, d, and D is valid.
# (l)abeling must only be used once and the 'l' must be the last letter.
# Comment out to disable
despeckle EedDl
# Recommended value is EedDl. Any combination (and number of) of E, e, d, and D is valid.
# (l)abeling must only be used once and the 'l' must be the last letter.
# Comment out to disable
despeckle EedDl
# Ignore sudden massive light intensity changes given as a percentage of the picture
# area that changed intensity. Valid range: 0 - 100 , default: 0 = disabled
lightswitch 0
# area that changed intensity. Valid range: 0 - 100 , default: 0 = disabled
lightswitch 0
# Picture frames must contain motion at least the specified number of frames
# in a row before they are detected as true motion. At the default of 1, all
# motion is detected. Valid range: 1 to thousands, recommended 1-5
minimum_motion_frames 1
# in a row before they are detected as true motion. At the default of 1, all
# motion is detected. Valid range: 1 to thousands, recommended 1-5
minimum_motion_frames 1
# Specifies the number of pre-captured (buffered) pictures from before motion
# was detected that will be output at motion detection.
# Recommended range: 0 to 5 (default: 0)
# Do not use large values! Large values will cause Motion to skip video frames and
# cause unsmooth mpegs. To smooth mpegs use larger values of post_capture instead.
pre_capture 0
# was detected that will be output at motion detection.
# Recommended range: 0 to 5 (default: 0)
# Do not use large values! Large values will cause Motion to skip video frames and
# cause unsmooth mpegs. To smooth mpegs use larger values of post_capture instead.
pre_capture 0
# Gap is the seconds of no motion detection that triggers the end of an event
# An event is defined as a series of motion images taken within a short timeframe.
# Recommended value is 60 seconds (Default). The value 0 is allowed and disables
# events causing all Motion to be written to one single mpeg file and no pre_capture.
gap 60
# An event is defined as a series of motion images taken within a short timeframe.
# Recommended value is 60 seconds (Default). The value 0 is allowed and disables
# events causing all Motion to be written to one single mpeg file and no pre_capture.
gap 60
############################################################
# Image File Output
############################################################
# Image File Output
############################################################
# Output 'normal' pictures when motion is detected (default: on)
# Valid values: on, off, first, best, center
# When set to 'first', only the first picture of an event is saved.
# Picture with most motion of an event is saved when set to 'best'.
# Picture with motion nearest center of picture is saved when set to 'center'.
# Can be used as preview shot for the corresponding movie.
output_normal center
# Valid values: on, off, first, best, center
# When set to 'first', only the first picture of an event is saved.
# Picture with most motion of an event is saved when set to 'best'.
# Picture with motion nearest center of picture is saved when set to 'center'.
# Can be used as preview shot for the corresponding movie.
output_normal center
# The quality (in percent) to be used by the jpeg compression (default: 75)
quality 75
quality 75
############################################################
# Text Display
# %Y = year, %m = month, %d = date,
# %H = hour, %M = minute, %S = second, %T = HH:MM:SS,
# %v = event, %q = frame number, %t = thread (camera) number,
# %D = changed pixels, %N = noise level, \n = new line,
# %i and %J = width and height of motion area,
# %K and %L = X and Y coordinates of motion center
# %C = value defined by text_event - do not use with text_event!
# You can put quotation marks around the text to allow
# leading spaces
############################################################
# Text Display
# %Y = year, %m = month, %d = date,
# %H = hour, %M = minute, %S = second, %T = HH:MM:SS,
# %v = event, %q = frame number, %t = thread (camera) number,
# %D = changed pixels, %N = noise level, \n = new line,
# %i and %J = width and height of motion area,
# %K and %L = X and Y coordinates of motion center
# %C = value defined by text_event - do not use with text_event!
# You can put quotation marks around the text to allow
# leading spaces
############################################################
# Locate and draw a box around the moving object.
# Valid values: on, off and preview (default: off)
# Set to 'preview' will only draw a box in preview_shot pictures.
locate on
# Valid values: on, off and preview (default: off)
# Set to 'preview' will only draw a box in preview_shot pictures.
locate on
# Draws the timestamp using same options as C function strftime(3)
# Default: %Y-%m-%d\n%T = date in ISO format and time in 24 hour clock
# Text is placed in lower right corner
text_right %Y-%m-%d\n%T-%q
text_event %Y%m%d%H%M%S
# Default: %Y-%m-%d\n%T = date in ISO format and time in 24 hour clock
# Text is placed in lower right corner
text_right %Y-%m-%d\n%T-%q
text_event %Y%m%d%H%M%S
# Draw characters at twice normal size on images. (default: off)
text_double off
text_double off
############################################################
# Target Directories and filenames For Images And Films
# For the options snapshot_, jpeg_, mpeg_ and timelapse_filename
# you can use conversion specifiers
# %Y = year, %m = month, %d = date,
# %H = hour, %M = minute, %S = second,
# %v = event, %q = frame number, %t = thread (camera) number,
# %D = changed pixels, %N = noise level,
# %i and %J = width and height of motion area,
# %K and %L = X and Y coordinates of motion center
# %C = value defined by text_event
# Quotation marks round string are allowed.
############################################################
# Target Directories and filenames For Images And Films
# For the options snapshot_, jpeg_, mpeg_ and timelapse_filename
# you can use conversion specifiers
# %Y = year, %m = month, %d = date,
# %H = hour, %M = minute, %S = second,
# %v = event, %q = frame number, %t = thread (camera) number,
# %D = changed pixels, %N = noise level,
# %i and %J = width and height of motion area,
# %K and %L = X and Y coordinates of motion center
# %C = value defined by text_event
# Quotation marks round string are allowed.
############################################################
# Target base directory for pictures and films
# Recommended to use absolute path. (Default: current working directory)
target_dir ~/motion/
# Recommended to use absolute path. (Default: current working directory)
target_dir ~/motion/
# File path for snapshots (jpeg or ppm) relative to target_dir
# Default: %v-%Y%m%d%H%M%S-snapshot
# Default value is equivalent to legacy oldlayout option
# For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-snapshot
# File extension .jpg or .ppm is automatically added so do not include this.
# Note: A symbolic link called lastsnap.jpg created in the target_dir will always
# point to the latest snapshot, unless snapshot_filename is exactly 'lastsnap'
snapshot_filename %v-%Y%m%d%H%M%S-snapshot
# Default: %v-%Y%m%d%H%M%S-snapshot
# Default value is equivalent to legacy oldlayout option
# For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-snapshot
# File extension .jpg or .ppm is automatically added so do not include this.
# Note: A symbolic link called lastsnap.jpg created in the target_dir will always
# point to the latest snapshot, unless snapshot_filename is exactly 'lastsnap'
snapshot_filename %v-%Y%m%d%H%M%S-snapshot
# File path for motion triggered images (jpeg or ppm) relative to target_dir
# Default: %v-%Y%m%d%H%M%S-%q
# Default value is equivalent to legacy oldlayout option
# For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-%q
# File extension .jpg or .ppm is automatically added so do not include this
# Set to 'preview' together with best-preview feature enables special naming
# convention for preview shots. See motion guide for details
jpeg_filename %v-%Y%m%d%H%M%S-%q
# Default: %v-%Y%m%d%H%M%S-%q
# Default value is equivalent to legacy oldlayout option
# For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-%q
# File extension .jpg or .ppm is automatically added so do not include this
# Set to 'preview' together with best-preview feature enables special naming
# convention for preview shots. See motion guide for details
jpeg_filename %v-%Y%m%d%H%M%S-%q
############################################################
# Live Webcam Server
############################################################
# Live Webcam Server
############################################################
# The mini-http server listens to this port for requests (default: 0 = disabled)
webcam_port 0
webcam_quality 50
webcam_motion off
webcam_maxrate 1
webcam_localhost on
webcam_limit 0
webcam_port 0
webcam_quality 50
webcam_motion off
webcam_maxrate 1
webcam_localhost on
webcam_limit 0
############################################################
# HTTP Based Control
############################################################
# HTTP Based Control
############################################################
# TCP/IP port for the http server to listen on (default: 0 = disabled)
control_port 0
control_localhost on
control_html_output on
control_port 0
control_localhost on
control_html_output on
############################################################
# External Commands, Warnings and Logging:
# You can use conversion specifiers for the on_xxxx commands
# %Y = year, %m = month, %d = date,
# %H = hour, %M = minute, %S = second,
# %v = event, %q = frame number, %t = thread (camera) number,
# %D = changed pixels, %N = noise level,
# %i and %J = width and height of motion area,
# %K and %L = X and Y coordinates of motion center
# %C = value defined by text_event
# %f = filename with full path
# %n = number indicating filetype
# Both %f and %n are only defined for on_picture_save,
# on_movie_start and on_movie_end
# Quotation marks round string are allowed.
############################################################
# External Commands, Warnings and Logging:
# You can use conversion specifiers for the on_xxxx commands
# %Y = year, %m = month, %d = date,
# %H = hour, %M = minute, %S = second,
# %v = event, %q = frame number, %t = thread (camera) number,
# %D = changed pixels, %N = noise level,
# %i and %J = width and height of motion area,
# %K and %L = X and Y coordinates of motion center
# %C = value defined by text_event
# %f = filename with full path
# %n = number indicating filetype
# Both %f and %n are only defined for on_picture_save,
# on_movie_start and on_movie_end
# Quotation marks round string are allowed.
############################################################
# Do not sound beeps when detecting motion (default: on)
# Note: Motion never beeps when running in daemon mode.
quiet on
# Note: Motion never beeps when running in daemon mode.
quiet on
# Command to be executed when a picture (.ppm|.jpg) is saved (default: none)
# To give the filename as an argument to a command append it with %f
# on_picture_save echo I would have said on save %f
on_picture_save perl ~/motion/updateTwitter.pl --username YOURUSERNAME --password YOURPASSWORD --message "At %H:%M:%S Motion Was Detected" --picture %f
# To give the filename as an argument to a command append it with %f
# on_picture_save echo I would have said on save %f
on_picture_save perl ~/motion/updateTwitter.pl --username YOURUSERNAME --password YOURPASSWORD --message "At %H:%M:%S Motion Was Detected" --picture %f
# Command to be executed when a camera can't be opened or if it is lost
# NOTE: There is situations when motion doesn't detect a lost camera!
# It depends on the driver, some drivers don't detect a lost camera at all
# Some hang the motion thread. Some even hang the PC! (default: none)
on_camera_lost perl ~/motion/updateTwitter.pl --username YOURUSERNAME --password --message "WARNING Camera Was Not Detected"
# NOTE: There is situations when motion doesn't detect a lost camera!
# It depends on the driver, some drivers don't detect a lost camera at all
# Some hang the motion thread. Some even hang the PC! (default: none)
on_camera_lost perl ~/motion/updateTwitter.pl --username YOURUSERNAME --password --message "WARNING Camera Was Not Detected"
#!/usr/bin/perl
use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
use Getopt::Long;
use LWP::UserAgent;
use HTTP::Request::Common;
use Getopt::Long;
# Values to use when uploading to TwitPic
# You can change these defaults and you can
# override them with the command line options
my $picture;
my $username = 'USERNAME'; # This has to be your twitter username, not your email
my $password = 'PASSWORD'; # Twitter password
my $message = 'New Motion Detected'; # message you'd like to post
my $uploadOnly = 0; # Upload only, don't update Twitter
my $verbose = 0;
# You can change these defaults and you can
# override them with the command line options
my $picture;
my $username = 'USERNAME'; # This has to be your twitter username, not your email
my $password = 'PASSWORD'; # Twitter password
my $message = 'New Motion Detected'; # message you'd like to post
my $uploadOnly = 0; # Upload only, don't update Twitter
my $verbose = 0;
# These can be changed if the TwitPic API
# locations change
my $uploadAndPostSite = "http://twitpic.com/api/uploadAndPost";
my $uploadOnlySite = "http://twitpic.com/api/upload";
# locations change
my $uploadAndPostSite = "http://twitpic.com/api/uploadAndPost";
my $uploadOnlySite = "http://twitpic.com/api/upload";
GetOptions( "help|h|?" => sub { Usage() && exit( 0 ) },
"picture=s" => \$picture,
"username=s" => \$username,
"password=s" => \$password,
"uploadOnly" => \$uploadOnly,
"verbose" => \$verbose,
"message=s" => \$message ) or Usage() && exit( -1 );
"picture=s" => \$picture,
"username=s" => \$username,
"password=s" => \$password,
"uploadOnly" => \$uploadOnly,
"verbose" => \$verbose,
"message=s" => \$message ) or Usage() && exit( -1 );
if( !$picture || !$username || !$password )
{
print "ERROR: Please provide all required arguments\n";
Usage() && exit( -1 );
}
{
print "ERROR: Please provide all required arguments\n";
Usage() && exit( -1 );
}
if( ! -e $picture || ! -f $picture )
{
print "ERROR: The picture you specified $picture doesn't seem to exist\n";
exit( -1 );
}
{
print "ERROR: The picture you specified $picture doesn't seem to exist\n";
exit( -1 );
}
if( $verbose )
{
print "Attempting to upload pic to TwitPic with the following options:\n";
print "Picture: $picture\n";
print "Username: $username\n";
print "Password: $password\n";
print "Message: $message\n";
print "Upload only: ";
if( $uploadOnly )
{
print "Yes";
}
else
{
print "No";
}
print "\n\n";
}
{
print "Attempting to upload pic to TwitPic with the following options:\n";
print "Picture: $picture\n";
print "Username: $username\n";
print "Password: $password\n";
print "Message: $message\n";
print "Upload only: ";
if( $uploadOnly )
{
print "Yes";
}
else
{
print "No";
}
print "\n\n";
}
my $response;
my $ua = LWP::UserAgent->new( env_proxy => 1,
keep_alive => 1,
timeout => 30 );
if( $verbose )
{
print "Uploading picture to TwitPic.com...\n";
}
my $ua = LWP::UserAgent->new( env_proxy => 1,
keep_alive => 1,
timeout => 30 );
if( $verbose )
{
print "Uploading picture to TwitPic.com...\n";
}
if( $uploadOnly )
{
$response = $ua->request( POST $uploadOnlySite,
Content_Type => 'multipart/form-data',
Content => [
media => ["$picture"],
username => $username,
password => $password ] );
}
else
{
$response = $ua->request( POST $uploadAndPostSite,
Content_Type => 'multipart/form-data',
Content => [
media => ["$picture"],
username => $username,
password => $password,
message => $message ] );
}
{
$response = $ua->request( POST $uploadOnlySite,
Content_Type => 'multipart/form-data',
Content => [
media => ["$picture"],
username => $username,
password => $password ] );
}
else
{
$response = $ua->request( POST $uploadAndPostSite,
Content_Type => 'multipart/form-data',
Content => [
media => ["$picture"],
username => $username,
password => $password,
message => $message ] );
}
if( !$response->is_success )
{
print "ERROR: There was a problem while trying to contact to TwitPic\n";
die $response->status_line;
}
{
print "ERROR: There was a problem while trying to contact to TwitPic\n";
die $response->status_line;
}
if( $verbose )
{
print "Done trying to uploading picture, checking response for errors\n";
}
{
print "Done trying to uploading picture, checking response for errors\n";
}
# I guess we could actually use XML:arser to parse this, but it's kind of
# over kill in this situation
if( $response->content =~ /stat="fail"/ )
{
$response->content =~ /msg="(.*)"/;
print "\nERROR: There was an error uploading your picture to TwitPic\n";
print "INFO: $1\n";
exit( -1 );
}
# over kill in this situation
if( $response->content =~ /stat="fail"/ )
{
$response->content =~ /msg="(.*)"/;
print "\nERROR: There was an error uploading your picture to TwitPic\n";
print "INFO: $1\n";
exit( -1 );
}
# If verbose, print out the response, so the user can access the picture
if( $verbose )
{
print "\nUploade successful, here are the details:\n";
$response->content =~ /(.*)<\/mediaid>/;
print "Media id: $1\n";
$response->content =~ /(.*)<\/mediaurl>/;
print "Media url: $1\n";
if( $verbose )
{
print "\nUploade successful, here are the details:\n";
$response->content =~ /(.*)<\/mediaid>/;
print "Media id: $1\n";
$response->content =~ /(.*)<\/mediaurl>/;
print "Media url: $1\n";
}
sub Usage()
{
print "\n";
print "updateTwitter.pl --username user --password pass --picture pathToPicture [--message messageToTwitter] [--uploadOnly]\n\n";
{
print "\n";
print "updateTwitter.pl --username user --password pass --picture pathToPicture [--message messageToTwitter] [--uploadOnly]\n\n";
print "--username\tYour Twitter.com username\n";
print "--password\tYour Twitter.com password\n";
print "--picture\tPath to the picture you want to post\n";
print "--message\tOptional message to Tweet with your picture\n";
print "--uploadOnly\tUpload to TwitPic.com only and don't Tweet. This will ignore any message passed in\n";
}print "--password\tYour Twitter.com password\n";
print "--picture\tPath to the picture you want to post\n";
print "--message\tOptional message to Tweet with your picture\n";
print "--uploadOnly\tUpload to TwitPic.com only and don't Tweet. This will ignore any message passed in\n";
Comments
Post a Comment