The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

ControlX10::CM11 - Perl extension for X10 'ActiveHome' Controller

SYNOPSIS

use ControlX10::CM11;

  # $serial_port is an object created using Win32::SerialPort
  #     or Device::SerialPort depending on OS
  # my $serial_port = setup_serial_port('COM10', 4800);

$data = &ControlX10::CM11::receive_buffer($serial_port);
$data = &ControlX10::CM11::read($serial_port, $no_block);
$percent = &ControlX10::CM11::dim_level_decode('GE');	# 40%

&ControlX10::CM11::send($serial_port, 'A1'); # Address device A1
&ControlX10::CM11::send($serial_port, 'AJ'); # Turn device ON
  # House Code 'A' present in both send() calls

&ControlX10::CM11::send($serial_port, 'B'.'ALL_OFF');
  # Turns All lights on house code B off

DESCRIPTION

The CM11A is a bi-directional X10 controller that connects to a serial port and transmits commands via AC power line to X10 devices. This module translates human-readable commands (eg. 'A2', 'AJ') into the Interface Communication Protocol accepted by the CM11A.

send command

This transmits a two-byte message containing dim and house information and either an address or a function. Checksum and acknowledge handshaking is automatic. The command accepts a string parameter. The first character in the string must be a House Code in the range [A..P] and the rest of the string determines the type of message. Intervening whitespace is not currently permitted between the House Code and the Operation. This may change in the future.

STRING	ALTERNATE_STRING	FUNCTION
 1..9				Unit Address
 A..G				Unit Address
   J		ON		Turn Unit On
   K		OFF		Turn Unit Off
   L		BRIGHT		Brighten Last Light Programmed 5%
   M		DIM		Dim Last Light Programmed 5%
   O		ALL_ON		All Units On
   P		ALL_OFF		All Units Off

There are also functions without "shortcut" letter commands:

ALL_LIGHTS_OFF	EXTENDED_CODE	EXTENDED_DATA
HAIL_REQUEST	HAIL_ACK	PRESET_DIM1
PRESET_DIM2	STATUS_ON	STATUS_OFF
STATUS

Dim and Bright functions can also take a signed value in the range [-95,-90,...,-10,-5,+5,+10,...,+90,+95].

ControlX10::CM11::send($serial_port,'A1'); # Address device A1
ControlX10::CM11::send($serial_port,'AJ'); # Turn device ON
ControlX10::CM11::send($serial_port,'A-25'); # Dim to 25%
read

This checks for an incoming transmission. It will return "" for no input. It also tests for a received a "power fail" message (0xa5). If it detects one, it automatically sends the command/data to reset the CM11 clock. If the $no_block parameter is FALSE (0, "", or undef), the read will retry for up to a second at 50 millisecond intervals. With $no_block TRUE, the read checks one time for available data.

$data = &ControlX10::CM11::read($serial_port, $no_block);
receive_buffer

This command handles the upload response to an "Interface Poll Signal" message (0x5a) read from the CM11. The module sends "ready" (0xc3) and receives up to 10 bytes. The first two bytes are size and description of the remaining bytes. These are used to decode the data bytes, but are not returned by the receive_buffer function. Each of the data bytes is decoded as if it was a send command from an external CM11 or equivalent external source (such as an RF keypad).

$data = &ControlX10::CM11::receive_buffer($serial_port);
    # $data eq "A2AK" after an external device turned off A2

Multiple house and unit addresses can appear in a single buffer.

if ($data eq "B1BKA2AJ") {
    print "B1 off, A2 on\n";
}
dim_level_decode

When the external command includes dim/bright information in addition to the address and function, the dim_level_decode function converts that data byte (as processed by the receive_buffer command) into percent.

$data = &ControlX10::CM11::receive_buffer($serial_port);
    # $data eq "A2AMGE" after an external device dimmed A2 to 40%
$percent = &ControlX10::CM11::dim_level_decode("GE");
    # $percent == 40

A more complex $data input is possible.

if ($data eq "B1B3B5B7B9BLLE") {
    print "House B Inputs 1,3,5,7,9 Brightened to 85%\n";
}

The conversion between text_data and percent makes more sense to the code than to humans. The following table gives representative values. Others may be received from a CM11 and will be properly decoded.

Percent	Text		Percent	Text
    0	 M7		   50	 AA
    5	 ED		   55	 I6
   10	 EC		   60	 NF
   15	 C7		   65	 N2
   20	 KD		   70	 F6
   25	 K4		   75	 DB
   30	 O7		   80	 D2
   35	 OA		   85	 LE
   40	 G6		   90	 PB
   45	 AF		   95	 P8

EXPORTS

Nothing is exported by default. The send_cm11, receive_cm11, read_cm11, and dim_decode_cm11 functions can be exported on request with the tag :FUNC. They are identical to the "fully-qualified" names and accept the same parameters.

use ControlX10::CM11 qw( :FUNC 2.03 );
send_cm11($serial_port, 'A1');		    # send() - address
send_cm11($serial_port, 'AJ');		    # send() - function
$data = receive_cm11($serial_port);		    # receive_buffer()
$data = read_cm11($serial_port, $no_block);	    # read()
$percent = dim_decode_cm11('GE');		    # dim_level_decode()

AUTHORS

Bruce Winter bruce@misterhouse.net http://misterhouse.net

CPAN packaging by Bill Birthisel wcbirthisel@alum.mit.edu http://members.aol.com/bbirthisel

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).

Win32::SerialPort and Device::SerialPort

CM11A Protocol documentation available at http://www.x10.com

COPYRIGHT

Copyright (C) 1999 Bruce Winter. All rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. 29 September 1999.