Insteon on Linux    Feb. 22, 2006

This is a bunch of experimental code to try and utilize the Insteon USB
PLC from Linux. The primary goal at this point is to be able to manipulate
the device link tables progmaticlly and avoid having to run around the
house setting up links.  It would also be nice to have a backup of the
links and an easy way to replace a failed device.  The current version
does this and more.

How to build:
	Building the program is pretty simple. Typing 'make' should build the
	ilink executable.  You can look at the Makefile to see what options
	are currently being used.

	There is also a utility program included, called detach, that will
	detach the PLC from the HID driver. This can be built by typing
	make detach.


How to install:
	This program needs a USB driver in order to communicate with the PLC.
	It currently uses the USB driver created by Neil Cherry. You can get
	a copy of his driver from www.linuxha.com. A slightly modified 
	version for later 2.6 kernels is included here.  

	Steps to get the driver installed and working.

	1. Compile the driver, type "make" in the iplc directory and it should
	   create the driver. Note that you need kernel include files for this
	   to work.

	2. Create the device node needed by the driver, type "make node" and
	   it should create the proper device node in /dev. You need to be 
	   root for this to work.

	3. Detach the PLC from the HID driver. Do this by running the detach
	   program created above. This is only needed if you are actually 
	   running the HID driver. You need to be root to do this.

	4. Install the driver. Type "insmod ./iplc.ko" again, you need to be root
	   to do this.
	
	You can check /var/log/messages to make sure the driver installed
	correctly.


The device and scene definition file.

	ilink uses a simple text file to store information about the various
	INSTEON devices you have and the scenes you want to create.  A sample
	file is included in the distribution.

	A scene can be something as simple as one switch controlling one lamp
	module or as complicated as one button on a KeypadLinc controlling
	every device you have.  A scene is described from the controlling
	devices point of view. The attributes of a scene are:

	1.  A scene name.  This can be anything you want it to be.
	2.  A master. This is the device that will be controlling the scene.
	3.  A group number.  This is the group number that will be used to
	    activate the scene
    4.  At least one responder. These are the devices you want controlled
	    by the master. The number of responders is only limited by the
		amount of memory a device has to hold scenes. The responder line
		has space separated fields:
		
		<device id> <on level> <ramp rate> <group*>

		*KeypadLincs require the last field to match the button number,
		for all other devices this field is ignored.

	For links to work effectivly, you'll need to create scenes for every
	link group you want because Links will overwrite the link table in
	any device listed, master or responder.  The only exception is
	PowerLinc V2 devices (device type 0000 or 0001) will not currently
	get updated.

	Copy the sample_scenes.inf file to ilink_scene.inf and edit it with your
	favorite text editor.

	

About the code.

First, remember this is experimental code. There is a lot of functionallity
here but not everything is hooked up or controlled in an intuitive way. The
GUI was created using GLADE and the glade files are included.

The main code is in ilink.c. This file reads the GLADE xml file, hooks up
the signal handlers, and creates all the GUI widgets. It has functions that
manipulate some of the widgets, specificly it populates the combo boxes.

ilink_signals.[ch] has all the GTK widget signal handlers. This is where a
lot of the really high level code is. Every button press and menu item event is handled here.

scenes.[ch] has the code and data structures for device and scene managment.
Here you'll find the functions that read/write the scene file and functions
that build the in-memory link tables prior to programming the devices.

All of the PLC/remote device communication is handled in other files. These
files are described below.

	insteon_msg.[ch]
	================

	These files contain functions for sending Insteon messages and 
	receiving replies. A couple of helper functions are also in here.
	
	send_insteon_msg() -  writes the message to the IBIOS area and
	flips a bit that tells IBIOS to send the message.

	salad_send_msg() - uses a SALad event to send the message.  

	write_insteon_msg() - write the message into the PLC's memory but
	don't send it.
	
	send_extended_insteon_msg() - send extended messages (that doesn't work).

	send_insteon_ping() - ping a device and return the device identification
	information.


	idrv.[ch]
	=========

	This is the low level communication interface to the PLC. Most of the
	important IBIOS commands are implemented (write memory, read memory,
	events, masks, reset, get_version). This also has the functions that
	communicate with the PLC USB driver. This handles all the timing
	and handshaking required by the PLC.

	This requires Neil Cherry's USB driver for the PLC. A version for 
	later 2.6 kernels is included in the iplc directory. 

There are a couple of utility programs.

	detach.c

	This program uses libusb to detach the PLC from the Linux Kernel HID
	driver. This must be run as root and run prior to inserting the PLC
	USB device driver. An alternative is to add the PLC's vendor/product
	id's to the HID driver's blacklist so that it doesn't claim ownership
	of the device. (requires re-compiling the Linux kernel)

	link.c

	This is a command line version of the code. It can't do everything the
	GUI can and it can do somethings the GUI can't. It links with scenes,
	insteon_msg and idrv so all the high/mid/low level functions are shared
	with the GUI version.
