http://www.perlmonks.org?node_id=65361
Category: Miscellaneous
Author/Contact Info James Mancini
Description: This is a simple Perl control script for the X10 Firecracker module (http://www.x10.com/firecracker/fc_x10_cm17a_br1.htm).

Useful for simple crontab timer applications. The Options are overly wordy to make for easy crontab reading later on.

Requires the ControlX10::CM17 module and Device::SerialPort module from CPAN. Serial port dependancy means that this code is probably not portable to Windows platforms without some modifications; other portability unknown.
#!/usr/bin/perl
#
# master_timer
#
# Perl control script for X10 Firecracker module
# Useful for simple crontab timer applications. Options are overly wor
+dy
# to make for easy crontab reading later on.
#
# Requires the ControlX10::CM17 module and Device::SerialPort module f
+rom
# CPAN. Not portable to Windows platforms; other portability unknown.
#
# 18-Mar-2001 by James Mancini - released into public domain

use vars qw( $module $secure $action);
use Device::SerialPort;
use ControlX10::CM17 qw( send_cm17 0.05 );
use Getopt::Long;
use strict;

my %opt;

$opt{fullcmd} = "$0 ".(join " ", map {$_ =~ /[ \[\]\*\{\}\;\>\<\&]/ ? 
+"'$_'" : $_ } @ARGV);
options(\%opt);

my $port = $opt{port} || "/dev/ttyS0";
my $serial_port = Device::SerialPort->new ($port,1);
die "Darn! I Can't open serial port $port: $^E\n" unless ($serial_port
+);

# These are for the pass-through port on the Firecracker
$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 "Failed to set serial params.\n";


if ($opt{secure})
    {
    my $sleeptime = int(rand (31) * 60);
    print "\nSleeping $sleeptime seconds..\n" if $opt{verbose};
    sleep $sleeptime;
    }

my $action = "";
if ($opt{action} =~ /^off$/)
    { $action = "K" } 
elsif ($opt{action} =~ /^dim([+-][\d]+)$/)    #dim can be + or -
    { $action = "${1}" }
elsif ($opt{action} =~ /^bright([+-][\d]+)$/)    #really the same as d
+im
    { $action = "${1}" }
elsif ($opt{action} =~ /^dim$/)
    { $action = "-14" }
elsif ($opt{action} =~ /^bright$/)
    { $action = "+14" }
elsif ($opt{action} =~ /^allon$/)          # All lights on
    { $action = "O"; $opt{module}=""; } 
elsif ($opt{action} =~ /^alloff$/)        # All lights off
    { $action = "N"; $opt{module}=""; }
elsif ($opt{action} =~ /^masteroff$/)        # All modules off
    { $action = "P"; $opt{module}=""; }
else     # Default action = turn module on 
    { $action = "J" }

$opt{module} =~ s/^[^0-9a-g]$//i;
$opt{hcode} =~ s/^[^a-zA-Z]$|^[\w].+//;
$opt{hcode} = "A" unless $opt{hcode};
$opt{hcode} =~ tr/a-z/A-Z/;
my $cmd = "$opt{hcode}$opt{module}${action}";

print "\nSending $cmd...\n" if $opt{verbose};
send_cm17($serial_port, $cmd);

$serial_port->close || die "\nclose problem with $port\n";
undef $serial_port;


sub options () {
   my $opt = shift;
   GetOptions( $opt,
        'action=s',
        'hcode=s',
        'module=s',
        'secure',
        'verbose',
        'port=s',
            ); 
   unless ($opt{module}) #print usage 
    {
     print <<ECHO;

Usage:

master_timer [options]

  --module=[1-9a-g]
    *REQUIRED* Specify which module to send the command to. 
    16 modules are allowed per house code, numbered 1-9 then a-g
    (i.e, 10 = a, 16 = g).

  --action=opt
    {optional} 'opt' must be one of the following: 
    [on|off|dim{-1-100}|bright{+1-100}|alloff|allon|masteroff] 
    'allon' and 'alloff' refer to all LIGHT MODULES,
    'masteroff' turns off ALL MODULES. Default action is ON.

  --hcode=[a-z]
    set housecode for command. Defaults to housecode "A".

  --secure
    {optional} Add a random delay between 0 and 30 minutes before 
    executing command. Useful for timer applications. Set the command
    to run at the EARLIEST time you want it to happen.

  --port=device
    'device' should be the full path to the port, e.g. "/dev/ttyS1".
    Optional. If not specified, defaults to /dev/ttyS0 (COM1). 

  --verbose
    {optional} Print status messages.

ECHO
     exit (1);
    }
}
Replies are listed 'Best First'.
Re: X10 Timer script...
by myocom (Deacon) on Mar 19, 2001 at 11:45 UTC

    And, of course, no discussion of Perl and home automation would be complete without a mention of our good friends over at MisterHouse. I use it, and I'm pleased with it.

Re: X10 Timer script...
by jfroebe (Parson) on Oct 10, 2004 at 03:05 UTC

    Thanks!!

    I was looking for a simple example perl script to get started on my home automation project. I type in X10 and walla! The answer arrives in under a second!

    I looked at MisterHouse as it was really a home based application server that a chunk of it was for X10. It was definitely overkill and not at all friendly for configuration. Maybe the developer will add user friendly configuration in the future. Looks good though once it is configured

    Jason L. Froebe

    No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1