package ControlX10::CM15A; #----------------------------------------------------------------------------- # Written by Paul DeMarco # Aug 28, 2005 # An X10 ActiveHome interface, used by Misterhouse ( http://misterhouse.net ) # # Uses the USB driver by Neil Cherry #----------------------------------------------------------------------------- use strict; use vars qw($VERSION $DEBUG @ISA @EXPORT @EXPORT_OK); require Exporter; @ISA = qw(Exporter); @EXPORT= qw(); @EXPORT_OK= qw( send_cm15a ); $VERSION = '0.01'; $DEBUG = 0; my %table_hcodes = qw( A 0110 B 1110 C 0010 D 1010 E 0001 F 1001 G 0101 H 1101 I 0111 J 1111 K 0011 L 1011 M 0000 N 1000 O 0100 P 1100 ); my %table_devcodes = qw( 1 0110 2 1110 3 0010 4 1010 5 0001 6 1001 7 0101 8 1101 9 0111 10 1111 11 0011 12 1011 13 0000 14 1000 15 0100 16 1100 ); #J = 2 my %table_cmds = qw( J 0010 K 0011 O 0001 N 0110 P 0000 M 0100 L 0101 ); my %table_humancmds = qw( ON 0010 OFF 0011 DIM 0101 BRIGHT 0100 ALL_LIGHTS_ON 0001 ALL_LIGHTS_OFF 0110 ALL_UNITS_OFF 0000 ); #ALL_UNITS_OFF 1 #ALL_LIGHTS_ON 2 #ON 3 #OFF 4 #DIM 5 #BRIGHT 6 #ALL_LIGHTS_OFF 7 #EXTENDED_CODE 8 #HAIL_REQUEST 9 #HAIL_ACKNOWLEDGE 10 #PRESET_DIM_1 11 #PRESET_DIM_2 12 #EXTENDED_DATA_TRANSFER 13 #STATUS_ON 14 #STATUS_OFF 15 #STATUS_REQUEST 16 sub send_cm15a { return unless ( 2 == @_ ); return ControlX10::CM15A::send (@_); } sub send { my ($serial_port, $house_code) = @_; # 3 pieces 1.house code 2. possible device 3. cmd my ($house, $device, $command ) = $house_code =~ /(\S)(\d*)(\S+)/; if (defined $main::config_parms{debug}) { $DEBUG = ($main::config_parms{debug} eq 'X10') ? 1 : 0; } print "CM15A: $serial_port house=$house device=$device code=$command \n" if $DEBUG; my $data = $table_hcodes{$house}; unless ($data) { print "CM15A.pm error. Invalid house code: $house\n"; return; } # if you are defining a device if (length( $device ) <= 0 ) { undef $device; } if ( defined $device ) { my $dev = $table_devcodes{$device}; unless ($dev) { print "CM15A.pm error. Invalid device code:$device:\n"; return; } } # Check for +-## brighten/dim commands (e.g. 7+5 F-95) # Looks like it takes 7 levels to go full bright/dim (14%). if ($command =~ /(\S)([\+\-])(\d+)/) { my $device= $1; my $dir = $2; my $level = $3; my $ok; print "Running CM15A dim/bright loop: device=$device $dir=$dir level=$level\n" if $DEBUG; # The CM17 dim/bright has not device address, so we must first # address the device (need to make sure it is on anyway) &send($serial_port, $house . $device . 'J'); my $command = ($dir eq '+') ? 'L' : 'M'; while ($level >= 0) { $ok = &send($serial_port, $house . $command ); $level -= 14; } return $ok; } # Check for #J/#K or L/M/O/N my $data2 = $table_cmds{$command }; $data2 = $table_cmds{substr($command , 1)} unless $data2; unless ($data2) { print "CM15A.pm error. Invalid command code: $command .\n"; return; } #is this a device specific command? if ( defined $device ) { syswrite $serial_port, pack( "CB8", 4, $table_hcodes{$house} . $table_devcodes{$device} ), 2; sleep 1; } syswrite $serial_port, pack( "CB8", 6, $table_hcodes{$house} . $table_cmds{$command} ), 2; return 1; } 1; # for require __END__ =head1 NAME ControlX10::CM15A - Perl extension for 'ActiveHome Pro' RF Receiver/Transmitter =head1 SYNOPSIS #!/usr/bin/perl use Fcntl; use ControlX10::CM15A qw( send_cm15a 0.00 ); sysopen( CM15A, "/dev/usb/cm15a0", O_RDWR |O_NOCTTY | O_NONBLOCK ) || die "Cannot open device $!"; send_cm15a( \*CM15A, "A5J" ); # turn A5 ON send_cm15a( \*CM15A, "A5K" ); # turn A5 OFF send_cm15a( \*CM15A, "A3J" ); # turn A3 ON send_cm15a( \*CM15A, "A3K" ); # turn A3 OFF send_cm15a( \*CM15A, "AN" ); # turn all lights on house code A OFF send_cm15a( \*CM15A, "AO" ); # turn all lights on house code A on send_cm15a( \*CM15A, "AP" ); # turn all units on house code A OFF close( CM15A ); =head1 DESCRIPTION The ActiveHome Pro (CM15A) is a X10 controller that connects to a USB port and transmits & recieves commands via RF and X10 transceivers. The ActiveHome Pro is a USB device and requires a USB driver to be installed in your kernel. This can be done after initial configuration. Follow the directions in Neil Cherry's driver. This module follows the standard for MisterHouse. The codes that can be passed follow: $operation FUNCTION L Brighten Last Light Programmed 14% M Dim Last Light Programmed 14% N All Lights Off O All Lights On P All Units Off =head1 EXPORTS Nothing is exported by default. Current the only function of value is send_cm15a. use ControlX10::CM15A qw( send_cm15a 0.00 ); send_cm15a( \*CM15A, "A1J" ); =head1 AUTHORS Paul DeMarco horked_noodle@yahoo.com http://misterhouse.net =head1 SEE ALSO mh can be download from http://misterhouse.net You can subscribe to the mailing list at http://www.onelist.com/subscribe.cgi/misterhouse You can view the mailing list archive at http://www.onelist.com/archives.cgi/misterhouse perl(1). =head1 COPYRIGHT Copyright (C) 2005 Paul DeMarco. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. 28 August 2005. =cut