By Eric Faulkner, Tony Northrup
Book Price: $29.95 USD
£20.95 GBP
PDF Price: $23.99
Cover | Table of Contents | Colophon
An X10 wall switch An X10 motion detector Two AAA batteries An X10 controller (optional) Replacement faceplate (optional) Circuit tester Screwdriver Wire nutsFor a list of specific parts used in this project, refer to Exhibit A at the end of this chapter.If you live in a home that's more than 20 years old, there's a very good chance that you have light switches in odd places, or that you need to cross a room in order to turn on a light. In my case, I have to walk across a dark and frighteningly cluttered basement, so I often end up leaving the light on and wasting energy. If I could automate this light switch so that it turns on when I enter the room and turns off when I leave it, I would save myself both money and frustration.Figure 1-1 illustrates the project's simple design, which includes a motion detector and a control mechanism. The motion detector is triggered simply by someone entering the room, and will then send a signal telling the control mechanism (an intelligent light switch) to turn on. Just as when you manually flip a light switch, the intelligent light switch will close a circuit and provide electricity to the light.
http://www.smarthome.com.|
Item
|
Quantity
|
Approximate cost
|
Part number
|
|---|---|---|---|
|
X10 wireless transceiver
|
1
|
$20 and up
|
4005X or 400s
|
|
X10 motion detector
|
1
|
$20 and up
|
MS14A-C or MS13A
|
|
X10 switch
|
1
|
$13 and up
|
2031 or similar
|
A load-bearing X10 wall switch An X10 motion detector (preferably an outdoor model) X10 Powerlinc Serial Controller Four AAA batteries An X10 controller (optional) Replacement faceplate (optional) Circuit tester Screwdriver Wire nutsFor a list of specific parts used in this project, refer to Exhibit A at the end of this chapter.I hate unlocking my front door in the dark. I'm never sure if I have the right key in my hand, if it's turned the right way, or where the keyhole is. The worst part is that I have a porch light right above the door. I can't unlock the door without the light, but I can't get to the light without unlocking the door. So, the light switch waits for me on the other side of the door, quietly mocking me. I'll teach that light to laugh at me.From now on, porch light, I'm the boss, and these are the rules. You will:
Turn on at dusk. Turn off at midnight. Turn on the entryway lights inside the house when someone approaches the door after dusk but before midnight. Turn on both the porch light and the floodlights when someone approaches the door between midnight and 6 A.M.For the project to accomplish all this, we'll need a logic mechanism that can determine when to turn the lights on and off, and keep track of their state. The logic mechanism will control the light switch and receive input from a timer, motion detectors, and conventional light switches. You can buy or build standalone logic mechanisms, but a computer is the simplest and least expensive way to control everything. We'll also need a light switch that can be remotely controlled by the computer, and a motion detector that can tell our computer when someone approaches the door. Figure 2-1 shows the components of this project.
|
Device
|
Address
|
|---|---|
|
Porch light
|
B1
|
|
Floodlights |
|
Event
|
Signal
|
|---|---|
my $lights_hc = "B"; my $porch_light_unit = "1"; my $floodlight_unit = "2"; my $interior_light_unit = "3"; my $motion_hc = "C";
|
Variable
|
Description
|
|---|---|
|
$lights_hc
|
The house code for your lights.
|
|
$porch_light_unit, $floodlight_unit, $interior_light_unit
|
The unit codes for your lights.
|
|
$motion_hc
|
The house code for your motion detector and wireless transceiver.
|
|
$porch_motion_unit
|
The unit code for your motion detector.
|
|
$porch_motion_on
|
The four-byte command string that the motion detector sends when it detects motion. This is created using the previously defined variables; by default it is "C9CJ".
|
|
$porch_motion_off
|
The four-byte command string that the motion detector sends when it hasn't detected motion for the time-out period. By default it is "C9CK". |
http://www.smarthome.com.|
Item
|
Approximate
|
Part num-
|
|---|---|---|
|
Serial Powerlinc computer inter- 1
|
$35 and up
|
CM11A
|
|
X10 wireless transceiver 1
|
$20 and up
|
4005X or 400s
|
|
X10 motion detector 1
|
$20 and up
|
MS14A-C or MS13A
|
|
X10 switch 1
|
$13 and up
|
2031
|
#!/usr/bin/perl
use lib './blib/lib','./lib';
# Configure user-modifiable codes. "hc" means "housecode"
my $lights_hc = "B";
my $porch_light_unit = "1";
my $floodlight_unit = "2";
my $interior_light_unit = "3";
my $motion_hc = "C";
my $porch_motion_unit = "9";
# These variables just increase readability
my $porch_motion_on = $motion_hc.$porch_motion_unit.$motion_hc."J";
my $porch_motion_off = $motion_hc.$porch_motion_unit.$motion_
hc."K";
my $dusk_detected = $motion_hc.($porch_motion_unit + 1).$motion_
hc."J";
my $dawn_detected = $motion_hc.($porch_motion_unit + 1).$motion_
hc."K";
my (@before, @now, $dusk, $night, $porch_light_on);
my ($floodlight_on, $interior_light_on, $data);
my ($OS_win, $serial_port);
# Load the proper SerialPort module based on platform
BEGIN { $| = 1;
$OS_win = ($^O eq "MSWin32") ? 1 : 0;
if ($OS_win) {
eval "use Win32::SerialPort";
die "$@\n" if ($@);
$serial_port = Win32::SerialPort->new ("COM1",1);
}
else {
eval "use Device::SerialPort";
die "$@\n" if ($@);
$serial_port = Device::SerialPort->new ("/dev/ttyS0",1);
}
}
die "Can't open serial port: $^E\n" unless ($serial_port);
$serial_port->error_msg(1);
$serial_port->user_msg(0);
$serial_port->databits(8);
$serial_port->baudrate(4800);
$serial_port->parity("none");
$serial_port->stopbits(1);
$serial_port->dtr_active(1);
$serial_port->handshake("none");
$serial_port->write_settings || die "Could not set up port\n";
use ControlX10::CM11;
while () {
# If it's midnight, turn the lights off
@now = localtime;
if (($now[2] == 0) && ($now[2] != $before[2])) {
print "Turning porch lights off because it is midnight.\n";
light_off($porch_light_unit);
$dusk = 0;
$night = 1;
}
@before = @now;
# Grab the data from the X10 controller
$data = $data.ControlX10::CM11::receive_buffer($serial_port);
# Motion detected on porch.
# Turn on porch and interior light, and possibly floodlight
if ($data =~ $porch_motion_on) {
print "Porch motion detected. Received: $data.\n";
$data = "";
light_on($porch_light_unit);
light_on($interior_light_unit);
# It is between midnight and dawn, so turn on the floodlights
if ($night) {
light_on($floodlight_unit);
}
}
# Motion detector on porch timed out. Turn off lights if necessary
if ($data =~ $porch_motion_off) {
print "No porch motion detected. Received: $data.\n"; # Turn off floodlights
if ( !$floodlight_on ) {
light_off($floodlight_unit);
}
$data = "";
# Turn off porch and interior lights if it's not dusk.
if ( !$dusk && !$porch_light_on ) {
light_off($porch_light_unit);
}
if ( !$interior_light_on ) {
light_off($interior_light_unit);
}
}
# Dusk was detected. Turn on porch lights.
if ( $data =~ $dusk_detected ) {
print "Dusk detected. Received: $data.\n";
$data = "";
light_on($porch_light_unit);
$dusk = 1;
}
# Dawn was detected. Turn off porch lights.
if ( $data =~ $dusk_detected ) {
print "Dawn detected. Received: $data.\n";
$data = "";
light_off($porch_light_unit);
$night = 0;
$dusk = 0;
}
# If someone manually turns the controlled lights on or off, makenote of it
if ( $data =~ ($lights_hc.$porch_light_unit.$lights_hc."J") ) {
$porch_light_on = 1;
$data = "";
}
if ( $data =~ ($lights_hc.$floodlight_unit.$lights_hc."J") ) {
$floodlight_on = 1;
$data = "";
}
if ( $data =~ ($lights_hc.$interior_light_unit.$lights_hc."J") ) {
$interior_light_on = 1;
$data = "";
}
if ( $data =~ ($lights_hc.$porch_light_unit.$lights_hc."K") ) {
$porch_light_on = 0;
$data = "";
}
if ( $data =~ ($lights_hc.$floodlight_unit.$lights_hc."K") ) {
$floodlight_on = 0;
$data = "";
}
if ( $data =~ ($lights_hc.$interior_light_unit.$lights_hc."K") ) {
$interior_light_on = 0;
$data = "";
}
}
# Release the serial port
$serial_port->close || die "\nProblem closing serial port\n";
undef $serial_port;
sub light_on {
print "Turning on: ".$lights_hc.$_[0]."\n";
sleep 1;
ControlX10::CM11::send($serial_port, $lights_hc.$_[0]);
ControlX10::CM11::send($serial_port, $lights_hc."J");
}
sub light_off {
print "Turning off: ".$lights_hc.$_[0]."\n";
sleep 1;
ControlX10::CM11::send($serial_port, $lights_hc.$_[0]);
ControlX10::CM11::send($serial_port, $lights_hc."K");
}
|
Description
|
Version
|
|---|---|
|
Operating System
|
Windows XP SP1
Mandrake 9.1
Red Hat 9.2
|
|
Perl
|
5.8.0
|
|
ControlX10::CM11
|
2.09
|
|
Win32::SerialPort
|
0.19
|
|
Device::SerialPort
|
0.22
|
Three X10 lamp modules or wall switches Three indoor X10 motion detectors Three wireless cameras A wireless video receiver (compatible with wireless cameras) An X10 wireless transceiver X10 Powerlinc Serial Controller Eight AAA batteries A stable Internet connection that allows inbound connections (broadband helps) A computer running Linux A video capture card with composite video input Sticky poster adhesive A screwdriverFor a list of specific parts used in this project, refer to Exhibit A at the end of this chapter.My wife, Erica, is an overprotective mother. We don't actually have any kids, though—just a cat. Sammy's not even the kind of cat that you really need to worry about; he's healthy, young, and built like a goat. But Erica still worries. Erica worries so much that we can't take an overnight trip without spending half the time wondering if the cat is okay.Erica and I got married a couple of years ago and went on a honeymoon cruise. We hired a pet sitter to come and feed the cat on a daily basis, and to reassure Erica that everything was okay, I set up a cheap webcam and some motion detection software. It worked terribly.Of course, it was still better than nothing—we were able to connect to the Internet from the very slow satellite link on the ship, and browse through a directory of webcam pictures to verify that Sammy was alive and that the pet sitter was feeding him. However, the motion detection software was very unreliable. The video from the webcam had so much noise that the motion detection software triggered almost constantly. It would even take pictures throughout the night, when there was total darkness and the camera couldn't capture an image. Worst of all, I actually
my $motion_hc = "C";
my @motion_ucs = ("2", "3", "4");
my $album_path = '/var/www/cgi-bin/ids/albums';
my $webcam_config = '/etc/petcam.config';
my $serial_port = Device::SerialPort->new("/dev/ttyS0",1);
my $min_bright = 0.07; # Minimum brightness acceptable
my $min_color = 0.15; # Minimum brightness before forcing B&W
my $min_raw = 0.25; # Minimum brightness to not equalize
my $apix = 200; # Number of pixels to analyze (squared)
my $crop = 10; # Number of pixels to crop off each side
|
Variable
|
Description
|
|---|---|
|
$motion_hc
|
The house code for your motion detectors, wireless transceiver, wireless cameras, and lights. |