Sunday, July 20, 2008

CM15A X10 Home Automation with Linux

A lot of the information and source code is slightly out of date on the topic of X10 on Linux. Certain changes in the latest kernels prevent the code from compiling out of the box. The machine I did this on is Kubuntu with the 2.6.24-16 kernel. Neil Cherry did a lot of good work on this subject. His page is full of a lot of detail that you probably think you don't need. Read through it anyway if you are actually trying to get the CM15A working in Linux.

First you will need the driver and the daemon. Download and unpack both. To get either to compile you need to change a few lines and comment out some others. You have to do the same thing in both packages. Find the line that reads, "#include linux/config.h" and change it to "#include linux/autoconf.h" Then comment out any line that starts with "MODULE_PARM". Next, in the cm15a-driver package in the cm15a.c file find the usb_class_driver struct and comment out the line that begins with "mode:" and do the same for the line in the next struct that begins with "owner:". Save everything and then run ./configure;make;make install.

Once everything is installed you'll need to run these commands:

mkdir /dev/usb
mknod --mode=a=rw /dev/usb/iplc0 c 180 240

then go into ./iplc/driver/linux-2.6/ and run:

insmod iplc.ko

then into cm15a-driver/driver/linux-2.6/ and run:

insmod cm15a.ko

That should be it. Here is a simple perl script that will turn on or off A1 depending on which line is uncommented.

#!/usr/bin/perl
use Fcntl;

sysopen( cm15a, "/dev/usb/iplc0", O_RDWR |O_NOCTTY | O_NONBLOCK )
|| die "Cannot find $!";
syswrite cm15a, pack( "CC", 4, 0x66), 2;
sleep 1;

# Turns on
syswrite cm15a, pack( "CC", 6, 0x62 ), 2;

# Turns off
#syswrite cm15a, pack( "CC", 6, 0x63 ), 2;
close( CM15A );

Now for some explanation of the script. The sysopen line creates a pointer of "cm15a" to the device file we made earlier. This gives perl an easy name to send future data. The first syswrite line is what tells the cm15a what device we are sending a signal to. In this case it is A1. We have to wait about 1 second because an ACK packet is sent back. The next syswrite sends the 'turn on' signal and the commented out syswrite sends 'turn off'. The last line closes the pointer for a graceful exit. The '4' part of the syswrite is what tells the unit that you are sending a Unit address (A1, C3, etc). The '6' means you are sending a Function code (on, off, dim, etc). Below is a cheet sheet for the A codes. If you look on Neil Cherry's page you'll see his chart of whole break down of the codes. The codes are not in binary order and seemed to have been chosen randomly. I made this just to help myself out and not have to decifer the right code everytime I'm writing a script. For the other house codes like B and up, just change the 6 to whatever Neil's chart says it should be.

A1 0x66
A2 0x6E
A3 0x62
A4 0x6A
A5 0x61
A6 0x69
A7 0x65
A8 0x6D
A9 0x67
A10 0x6F
A11 0x63
A12 0x6B
A13 0x60
A14 0x68
A15 0x64
A16 0x6C

I hope this helps!

9 comments:

Neil Cherry said...

If you've loaded the cm15a.ko file you shouldn't need to do a mknod iplc. The device /dev/cm15a0 should automatically (dynamically) be made for you. You can still do the mknod and no damage will be done. The iplc package uses the same source for the cm19a, cm15a, the Lego IR tower (where the original code came from), the Labjack and the Insteon USB IPLC (hence the name). When you type make you're actually doing the make all. I'll work on updating the documentation so the whole thing is less confusing and I'll get it moved over to SourceForge under the Linux Home Automation project where it really belongs. Thanks

Neil Cherry said...

The driver has moved, it's now at here. Sorry about moving things around.

I really need to get these drivers under a version control system (later, hopefully I'll get time).

Michael J Kormendy said...

Yeah so how about that update?
I have been using the CM15a on my box for quite a while with Win,Apache,PHP,MYSL but unfortunately the system was getting too bogged down and I just altogether decided to move everything over to Ubuntu Server.

Anyhow, I've been playing around with this, and was wondering if there's any progress on the documentation for the CM15a .. I have PHP code in my fingers waiting to come out.

Michael J Kormendy said...

Scott,
Can you contact me on my website?

somethinginteractive.com

I'd like to ask you some questions about getting this to work as I am trying to build a php connect to this and need some simple help.

Thanks,
// mike

Michael J Kormendy said...

I got it all working and with updated code from Jim and his libusb library and controller. It's really up to date and quite useful!

esquilo_observador said...

hi!
i'm using CM15 whith linux-debian and whith a lot's of problems finnaly it works. I´m sending command's in hexa but i can´t define the dim.. i need some help...
thank for all
francisco

Landi said...

Hi Neil,
I wonder if you could update the iplc driver to compile on kernels >2.6.29.
The problem is that the info() warn() and soon err() macros are removed completely from the kernel tree in 2.6.29 and replaced by dev_* functions.
I was able to patch it for myself, but I guess a lot of us are still using this driver, so it would be nice to correct that.

regards,
Greg

Unknown said...

I second that. And maybe Landi, if you could point me at something to tutor me in patching that myself the way you did, that might help. I'm about to integrate X10, ZoneMinder and my CM15A on a spare Ubuntu box and I could use whatever help is available. I think I've gotten as far as I can with what's out there. I'm stuck at the point mentioned in the last post, in a post-2.6.29 kernel.

Anonymous said...

yesterday i got my cm15pro (eu-version)
thx to you and neil its now connected to a xen-domU and i can turn on/off my light through a beautiful webinterface :)
gr8 work!!

but.. as seen here: https://rcbi.rochester.edu/users/vanooste/weblog/b1860/
i had to create the device node with c 180 252