-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Welcome to the x10-dev wiki!
Beyond the basic introduction to the project, this section is intended to explain more of how this project came about and why certain choices were made.
- **Q: Since SmartHome has discontinued the PowerLinc version 1
transceivers and is no longer selling them, when will you have
drivers for the PowerLinc v2 transceivers?
A: **This has to be my most frequently asked question. When I hacked the protocol for the SmartHome PowerLinc version 1 transceivers, it seemed to surprise SmartHome and the licensing information for the transceiver did not prevent me from reverse engineering the protocol. But, when SmartHome released the version 2 hardware, they included a licensing agreement that stipulates that the transceivers cannot be reverse engineered. SmartHome has a SDK for sale that would make development of the drivers very easy, but the SDK also contains a licensing agreement that prevents release of any derivitives in source form. While I completely disagree with what SmartHome has done, I can understand why they would do it and since I neither want to get involved in any legal battle nor have the financial means to defend myself legally, I have chosen to not pursue the SmartHome PowerLinc v2 at all. Note, I have contacted SmartHome on numerous occasions requesting permission to develop the open-source drivers, but they have not responded. I am very much aware of Nick Cherry's work, but I am not about to make a derivitive work from Nick's work that would expose me to the legal problems with SmartHome. Most users note that the drivers seem to get signals and negotiate with the PowerLinc v2 transceivers and indeed the protocol appears to be very similar to the v1 hardware. I believe it would be simply a matter of updating the translation table with the new binary codes and thus adapting the drivers to the v2 hardware should be very simple.
My only recommendation here is that users either hammer SmartHome to allow me to develop the drivers or use an alternative transceiver. - **Q: I am using Ubuntu (or some other linux distribution) and the
/dev/x10 devices are not deleted when the system restarts?
A: **Some of the distributions do not come delivered with /etc/udev/devices. When the installation script runs, it checks for the existance of this directory and if it does exist, it will create the devices in /etc/udev/devices/x10 which causes the Linux UDEV system to automatically create the devices when the system boots. A solution that seems to work is to create /etc/udev/devices before installing the x10dev drivers as Ubuntu will use this area to create the devices. Another option that I have seen work is to do the installation, and then copy the directory /dev/x10 to /lib/udev/devices (cp -arp /dev/x10 /lib/udev/devices). - **Q: Why do I have to compile the kernel and boot from it before
installing the wish drivers?
A: **As of version 2.1.0, you no longer have to compile your kernel in order to install and use the drivers thanks to some help from Michael H. Warfield. - Q: Why is the USB daemon not compiled when the drivers are built
on a 2.4 system?
A: Kernel 2.4 does not support bi-directional multi-byte USB communications. As a result the drivers cannot communicate with the USB X10 controllers. -
Q: Can't you make the PowerLinc USB work with wish-2.0 and kernel
2.4?
A: No. Prior to kernel 2.6.7, the USB subsystem of the kernel could only handle single byte transactions that are typical of keyboards and mice. The PowerLinc USB device requires that an 8 byte message be sent and received for every transaction. Therefore kernels prior to 2.6.7 cannot support the PowerLinc USB. Note that there is a patch for kernel 2.6.1 through 2.6.6 (included in the wish-2.0 distribution) and the patch was incorporated into 2.6.7. - **Q: Why the architecture change?
A: **The largest reason is to gain stability and simplicity in the drivers. Every version of the kernel resulted in significant changes to the USB core which caused lots of "#ifdef" blocks of code and constantly chasing the kernel to make the USB drivers work when a new revision came out. Also, RedHat has a habit of taking the standard kernel and modifying it to add enhancements which further complicated the drivers. Version 2.6 of the kernel changed portions of the serial interface causing a rewrite of the serial code as well as the USB code.
So, rather than continuing to chase the changes in the kernel, I extracted those things that have been stable across the kernels and put them into the kernel module. The rest is in the userspace portion of the driver in the form of a daemon. The userspace handles communications with the transceiver and simulates the X10 network in order to update the state of each device in the kernel module. A big side effect of moving the state simulator to userspace, if the userspace program crashes or the transceiver is changed, the state of the network devices is still maintained. - **Q: What happened to the CM17A driver?
A: **The CM17A requires direct access to the hardware of the machine so the driver for the CM17A requires low level drivers in the kernel. The architecture for Version 2.0 relies on using standard USB and Serial device drivers to make the X10 transceivers work on all hardware that is supported with the Linux Kernel. After Version 2.0 is in use for a wide audience, and if there is sufficient demand for it, I will work on a device driver for the kernel that makes the CM17A look like a serial port. - **Q: What are non-blocking writes?
A: **A number of people complained that the system was slow and that they wanted to send commands without having to wait for the system to complete each command. If you issue commands in blocking mode (typically with the echo command) the driver behaves the same as before. But, if you issue the command in non-blocking mode, the driver will queue the command up and let it execute serially. To facilitate this a new utility called "nbecho" has been provided in the distribution. Also, I learned a few lessons in the development of the 1.x series and figured out how to do handshaking with the transcievers more efficiently. The CM11A has a notable speedup due to these changes. -
Q: What happened to the unidev interface?
A: I have focused on the more popular interface first. Unidev will be moved over later. -
Q: How to I know when new drivers have been released?
A: The drivers are all on sourceforge.net/projects/wish. Sourceforge has a couple of facilities that are used to notify users of the driver updates.
The first is the "Monitor" feature. If you look at the primary page, for each download group there is a little picture of a mail envelope. If you click on this you can set yourself up to get notifications whenever new files are placed on the site. When you "Monitor" the drivers you will get a notification that a version was released but no details on what the release does.
The second method is through the mailing list. If you scroll down to the bottom of the primary page you will find an item that says "Mailing Lists". Clicking on this link will allow you to subscribe to the list. Whenever a new version of the driver is put on sourceforge, a detailed message of the changes is sent to the mailing list. This allows you to decide if you really need to update or not. For instance, if the changes were all related to the USB driver and you are using the CM11A, you do not need to update your drivers. - **Q: Why did you remove support for DEVFS?
A: **Version 2.6 of the kernel removes DEVFS support. Some minor DEVFS capability is still there, but for the most part it has been rendered unusable in 2.6. -
Q: Sometimes my transceiver works, and sometimes it doesn't.
**A: **This is a difficult one to solve. Some transceivers such as the CM11A do not reliably handshake without a small delay. This has also been experienced by users with some USB PCI cards. If your transceiver occasionally will not start, try setting the delay option in small increments. For example, for the PowerLinc on a generic USB PCI card, I have to use a value of 4. -
Q: Aren't there already drivers for transceivers?
**A:**Yes, and no. There are drivers for older transceivers like the CM11A (heyu) and even the newer FireCracker/CM17A which have well documented programming manuals. But, there are no Linux drivers for the PowerLinc Serial or the PowerLinc USB. Worse yet, the PowerLinc USB doesn't even have any released information for how to communicate with the device in the first place. But each of these transceivers that has a control program for Linux has its own unique user interface. There are also projects on http://www.sourceforge.net that are crating standard APIs to the transceivers for libraries. But, none of these make the devices universally available to shell scripts and programs with a common API. So, this project is trying to fill that gap by creating that common API with a simple, human readable command structure that makes it equally useable for shell scripts, command line usage, and programming. -
Q: Why are you taking up two major character devices and so many
minor devices?
A: This is the $10 million question and the issue that kept the 1.0 drivers from making it into the kernel source. The concept behind the standard API is to create a set of devices in /dev that represent the devices in the house. Since you have 16 housecodes and 16 units per housecode, you have just used up 256 minor numbers which is a full major number. That still leaves you without the ability to have a log, status, or a control interface to the driver. You could also argue (as some have) that I could have used IOCTL calls for the status and controls or used only 16 minor numbers for the housecodes and used IOCTL for management of the units. But, using IOCTL makes the driver useless to shell scripts and would relegate the driver to being just an API to programmers. The basic philosophy is that all of the management of the X10 network should be fully accessible from the command line as well as be accessible from a programming API. - **Q: What happened to x10attach?
A:**x10attach was a userspace program that connected the line discipline for the serial system to the drivers for X10. With the introduction of version 2.0 of the x10 drivers, the userspace portion of the driver does the communications with the physical transceiver eliminating the need to talk to the Line Discipline portion of the kernel. - **Q: Why was extended data and extended code removed from the
driver?
A: **I do not have a single X10 device that transmits or receives extended data or codes and the approach used in version 1.0 was cumbersome. I have built in hooks to add this functionality to version 2, but I haven't seen any user requests that need the functionality. If there is sufficient demand for extended data/code, I will look to adding the functionality to the version 2 drivers. -
Q: Why does "echo on > /dev/x10/a" inconsistently turn on
lights?
**A: **A couple of people have asked this question so it is worth explaining. This question implies that the user doesn't fully understand the X10 protocol. Don't take that as an insult if you asked the question. It took me a couple of weeks of reading and testing to understand the X10 protocol and there is likelihood that I still don't fully understand it. Joe User likely hasn't spent that much time reading through the X10 standard so this is a valid question. The answer is that the protocol allows you to gang devices together by sending their addresses on the line without a command. Every device that hears its address will then start listening for a command on the line. Once a command is received, if another address is seen, the devices will all reset and stop listening for a command and start listening for their address again. As a result, you can send A1, A2, A5, AON, A3, A4, A6, A8, AOFF to turn A1, A2, and A5 on, then turn A3, A4, A6, and A8 off. This would be equivalent to the following:
# echo null > /dev/x10/a1
# echo null > /dev/x10/a2
# echo null > /dev/x10/a3
# echo on > /dev/x10/a
# echo null > /dev/x10/a3
# echo null > /dev/x10/a4
# echo null > /dev/x10/a6
# echo null > /dev/x10/a8
# echo off > /dev/x10/a
The exact same results could be obtained by sending A1, AON, A2, AON, A5, AON, A3, AOFF, A4, AOFF, A6, AOFF, A8, AOFF. This would be equivalent to the following:
# echo on > /dev/x10/a1
# echo on > /dev/x10/a2
# echo on > /dev/x10/a5
# echo off > /dev/x10/a3
# echo off > /dev/x10/a4
# echo off > /dev/x10/a6
# echo off > /dev/x10/a8
Notice that using the first approach of grouping the devices, you only send 9 signals on the line. If you do it explicitly, you end up sending 14 signals on the line. Each signal takes about 1 second (the driver automatically adds delay to make sure that the signal gets out on the line) so you are looking at a time difference in what it takes to send the signal. The second approach has fewer user space commands and is easier to understand but takes longer to perform since the commands in the grouping example take 1 second, and the commands in the second example take 2 seconds each. -
Q: Why is the status out of synch with the actual X10 units?
**A: **One of the goals of the driver was to simplify the monitoring of the X10 network. At the same time, I didn't want to hide any of the protocol from the user. So, I implemented a software version of the X10 protocol (the userspace portion) which interprets any X10 commands that are seen on the line and simulates what should have happened to the units in the house. Unfortunately, there are situations where units do not receive the command, may have been manually turned on or off, or the unit doesn't respond to that particular command. For instance, wall receptacles rarely support dim/bright, or ALL_LIGHTS_ON/OFF. The x10 interpreter doesn't know which devices are lights and which are receptacles so it assumes that everything is a light and responds to every X10 command. Another example is that florescent lighting switches rarely support bright/dim commands but the driver doesn't know that they are florescent so it goes ahead and updates the status table as if a bright/dim actually occurred. The status table is nothing more than an approximation of the network based on treating everything as a full featured light. -
Q: How do I get a more accurate software status of the X10
units?
**A: **The simplest answer is that you can build user level software that watches /dev/x10/log and creates its own implementation of the X10 status but with awareness of the type of device for each unit in the house. This will require reading and understanding the X10 protocol. A second approach would be to buy two-way devices and send a status request (with the command "echo status > /dev/x10/<unit>") to the desired X10 unit. The unit will then respond with a status answer and the driver will update the state table accordingly. The added advantage of two-way devices is that whenever they change state, they send a notice to the network that they have changed. Replacing your switches with two-way switches is currently pretty expensive considering that two-way X10 switches cost about 4 times as much as a traditional X10 switch. -
Q: Why doesn't "cat" return when reading the X10 devices?
**A: **When the program "cat" opens a file to read, it opens it in blocking mode. Since the driver continually receives information, there is no real end-of-file, therefore, when you read the device in blocking mode, the read will wait for more data to arrive for the device. Since most scripts need to just read the current value and then exit, a utility called "nbread" (non-blocking read) has been provided in the utils directory. This utility opens the device with the flag O_NONBLOCK so that when the driver has no more data it returns 0 bytes causing the read() request to return. -
Q: What about the timers and macros for the CM11A?
A: While the timers and macros are really neat features of the CM11A, they aren't part of the standard X10 protocol. It would be fairly easy to add some IOCTL calls to control these features but I just haven't spent the time. My CM11A is somewhat flaky in that it locks up a good bit and has some issues with sending me information when it receives it so I have focused on the other drivers more. -
Q: What if I find a bug?
A: If you think you have found a bug in the drivers, by all means send me an email. Please try to send me enough information to repeat your situation. If it is fully repeatable, turn on debugging by loading the module with debug=1 on the command line of the kernel module and -debug on the userspace driver and then send me the output of your /var/log/messages (or wherever your kernel logs KERN_INFO messages). -
Q: Does it work with an SMP machine?
A: Version 2.X of the driver has been extensively tested with a SMP machine with no problem. -
Q: What X10 features are supported?
A: All drivers support Single Unit On, Single Unit Off, Bright, Dim. All drivers except the Firecracker (one-way), support All Units OFF, All Lights On, All Lights Off, Status request, Status=on response, Status=off response, hail request, hail response. The PowerLinc Serial and the CM11A support Extended Data. The PowerLinc Serial, PowerLinc USB, and CM11A support Preset Dim High/Low. None support Extended Code. - **Q: My switch won't respond to the preset dim commands?
A: **Most X10 switches do not respond to preset dim commands. You must buy a switch that is explicitly designed to respond to the commands. Sometimes they are called switches with "scenes capability". They typically cost significantly more than common X10 switches. -
Q: I have an X10 device that requires that I program it by
sending electronic signals. How do I program it?
A: Manufacturers have moved away from using dials to set the X10 address in switches. Many switches are now set up to respond to a unit code by electronically programming them through the X10 network. SmartHome advises getting Maxi Controller because it can send unitcodes without commands and housecodes without unitcodes. If the WiSH device drivers are installed, the switches can be programmed without purchasing the Maxi Controller. The device driver makes programming these devices simple because it has the capability to let the userspace program send raw commands onto the line.
Programming usually involves putting the switch into a program mode by holding in or pulling out a button on the device. For Leviton switches it is the green button on the top of the switch. For SmartHome devices it is usually a small reset button. The instructions will tell you to put the device into programming mode by manipulating the switch and then sending the device's address on the X10 line. Sending the address is accomplished by issuing the command:
# echo null > /dev/x10/<housecode><unitcode>
For example, if you wanted to program a LampLink (SmartHome product 2000STW) to respond to unit E16 and turn on the feature for recognizing local load, you would press the small black button on the side and hold for 5 seconds. The lamp would come on. You then issue the commands:
# echo null > /dev/x10/e15
# echo on > /dev/x10/e
The first command programs the switch as E15, and the second one tell it to turn on local load detection.
Similarly, to transmit the clear sequence of "O16, N16, M16, P16, M16" to a LampLink, you would issue the following commands:
# echo null > /dev/x10/o16
# echo null > /dev/x10/n16
# echo null > /dev/x10/m16
# echo null > /dev/x10/p16
# echo null > /dev/x10/m16 -
Q: Why isn't Manufacturer X's transceiver supported?
A: My intention is to write drivers for every transceiver that would fit with the philosophy of the project. Things like the Othello or Timecommander don't really make sense for this project. Also, I am paying for this out of my pocket so if the transceiver is overly expensive or there are is no programming documentation, the chances of me buying one are slim. If you are a manufacturer of a transceiver and would like to have it supported in this project, I would be happy to work on the device provided a couple of things can happen. 1) I need 2 of the transceivers so that I can test the send and receive simultaneously. 2) protocol and programming information to allow me to write the drivers. And 3) if possible example code for communicating with the device under whatever OS currently supports it. Programming for the PowerLinc USB was a unique situation in that I was out of work and had the time to spend a week coaxing the protocol out of the device. But, fortunately, I have a job now and don't have the time to dissect the device. -
Q: Have you tested the drivers with Manufacturer X's switch?
A: Again, I am limited in budget and can't afford to buy every switch that is out there. SmartHome was very kind and gave me a couple of two way switches to do testing. This enabled me to complete the preset dim/bright portion of the drivers. -
Q: I keep seeing X10 codes, but I am not sending them?
A: These messages likely existed before the driver was installed but now that you are seeing everything that is on your X10 network, you are seeing this noise. There are a couple of things that can cause this. On my system, when a florescent light begins to reach its end of life, before I can visibly notice the flickering, the X10 network starts getting flooded with "STATUS J" messages. Mine have always been very consistent when the florescent lights wither. Another common cause for it is one of your neighbors using X10. One of the reasons that so many housecodes were provided was so that neighbors on the same line can coexist. If you are seeing the same housecode that you are using, change to a different housecode so that you and your neighbor can coexist. If you are really set on using the housecode that you have, you could talk to your neighbor about changing. -
Q: All of your examples are run as the user "root". Isn't that
unsafe?
A: It is potentially unsafe so you might want to run your X10 network from a less privileged user. You must change the permissions on the files in /dev/x10/ so that the user can read and write to the device files. By default the files are created with write capability only for "root". The userspace program can run as a user or as root without any problems but the kernel modules must be loaded as root. -
Q: Can I load two transceivers at the same time on the same
machine?
*** A: Yes you can provided that you load the second drivers with the data_major and control_major parameters set to something other than what is used by the first driver. You will need to set up different character devices for each x10 device that you intend to control. makedev.sh will accept 3 parameters to override the defaults. The first must be the major character device for data, the second the major character device for control, and the third must be the directory for the devices. For example, to set the system up to have both the Firecracker and the CM11A loaded at the same time on ttyS0, the following commands can be used:
# scripts/makedev.sh 120 121 /dev/cm11a
# scripts/makedev.sh 122 123 /dev/cm17a
# insmod x10_cm17a.o data_major=122 control_major=123 port=0x3f8
# insmod x10_cm11a.o data_major=120 control_major=121
# utils/x10attach -11a /dev/ttyS0
To turn on e15 through the cm11a, execute the command:
# echo 1 > /dev/cm11a/e15
To turn off e15 through the cm17a, execute the command:
# echo 0 > /dev/cm17a/e15 -
Q: How do I set up aliases for my X10 devices?
A: This is one of the primary advantages to the standard interface. By creating symbolic links to the device, you can write scripts or programs to control and watch the devices and can just change the links whenever you want to change the configuration of the house. For instance, with the following commands exectuted:
# mkdir /automation
# ln -s /dev/x10/e1 /automation/frontflood
# ln -s /dev/x10/e2 /automation/backflood
# ln -s /dev/x10/e3 /automation/extbreakfast
# ln -s /dev/x10/e4 /automation/frontgarage
# ln -s /dev/x10/e5 /automation/backgarage
# ln -s /dev/x10/e6 /automation/frontporch
# ln -s /dev/x10/e7 /automation/backporch
# ln -s /dev/x10/e8 /automation/extbasement
# ln -s /dev/x10/e9 /automation/gym
# ln -s /dev/x10/e10 /automation/foyer
# ln -s /dev/x10/e11 /automation/familyroom
# ln -s /dev/x10/e15 /automation/curio
# ln -s /dev/x10/e16 /automation/lightsensor
# ln -s /dev/x10/g1 /automation/garagestatus
# ln -s /dev/x10/g11 /automation/statusgaragedouble
# ln -s /dev/x10/g12 /automation/statusgaragesingle
You could now execute the following command to turn on the light in the foyer:
$ echo 1 > /automation/foyer
If you want to have the light sensor turn on the flood lights, use the x10watch utility as follows:
$ x10watch /automation/lightsensor -1 "echo on > /automation/frontflood" -0 "echo off > /automation/frontflood" &
$ x10watch /automation/lightsensor -1 "echo on > /automation/backflood" -0 "echo off > /automation/backflood" & -
Q: What is wishweb?
A: To demonstrate the ease of programming to the X10 device drivers, a small client and server have been created. Combined they are called wishweb. The client is written in Java as an applet but it can run as a standalone Java application on any machine with the java 1.4 or higher runtime environment. A precompiled version of the Java applet is provided in x10web.jar. The applet looks almost identical to the SmartHome Synapse software and provides a very simple interface to controlling the X10 devices. It runs in Netscape Navigator or in Internet Explorer and will automatically request to download the Java runtime environment if the environment has not been installed on the local client. -
Q: Um, wishweb is kinda dorky. Why something so simple?
A: Dude, you gotta crawl before you can walk. I modeled wishweb after the user interface from the SmartHome Synapse software and yes, it is a very limited subset of what the SmartHome software can do. But, it is a very good representation of the raw protocol. Prior to this project, the most complex Java application I had written was a News Client a year ago when I happened across a Java programming book called "Learning Java" and decided to learn Java. Getting it all to work together was a pretty big challenge. As with the entire history of this project, I build things by generating the concept, prototyping something and getting it working for proof of concept, and once all works, I start expanding. So, wishweb is the proof of concept. x10home is the more advanced Java interface that you may want to consider if you find x10web to simple. -
Q: Why does the x10log show that commands were transmitted even
though the command timed out?
A: This is a tradeoff of either having the state machine reflect the order of transmission or reflect the ability to transmit. The problem that is being traded off here is that when sending the status command, some transceivers respond only with their status (rather than with their address followed by their status). The protocol specification isn't clear on what the transmitter must do in this case. In the case where the two-way switch is sending only its status, it is assuming that since the original status request was sent with a specific address, any response will be for that same address. Regarding the drivers, the reception of the status from the network always comes back before the transmit function can complete resulting in the state machine thinking that it received something before it transmitted something. The transmitter only updated the state machine if the transmit function completed. The reasons for it not completed would include the transceiver being unavailable or the transmitter being blocked by a noisy line. Prior to version 1.6.3, the driver took the safe method of only updating the state machine if the transmitter completed. But, starting with version 1.6.3, the state machine is updated regardless of the completion of the transmitter to make sure that the state machine reflects the optimistic or expected state of the network. -
Q: I am just getting into X10. What transceiver and switches
would you recommend?
A: In writing the drivers I have tried to stay neutral in my comments and support for the various transceivers. I have all 3 that are supported and have used all 3 for a significant length of time and they all work. So, I will not recommend one over the other. I will tell you that I use the PowerLinc USB and PowerLinc Serial for my own home automation so you will tend to see that I release new features on these first.
As for switches, the drivers were written to work with all standard X10 switches and devices. Devices that require the extended analog data have not been tested with the drivers so your mileage may vary when buying these devices.
So, for your initial setup, start small and learn as you go. No need to drop $1000 on a bunch of equipment if you aren't ready to use it yet. Get a transceiver (PowerLinc USB, PowerLinc Serial, or CM11A) and get a switch module that plugs into the wall (something like the LampLinc 2-way from Smarthome). Get your Linux system set up properly, install the kernel source, and build the drivers. The X10 hardware for this will cost about $70. If you are an avid Linux user and administrator, this will take you all of an hour to get going. If you are new to Linux, this could take days or weeks depending on how fast you learn and how good you are at following directions. Once you have the drivers working, tackle getting the WEB interface going so that you have GUI control of the switch. After you have mastered that, buy more switches depending on what you want to do. -
Q: What are some projects or examples of uses of the WiSH
drivers?
A: Before I put out some examples, let me just say that I wrote the drivers to provide as much flexibility as possible so the limits to the projects are only your budget and imagination.
Garage Door alarm and night light: Get an X10 Chime module (SmartHome Item 2045), an X10 IOLinc 4-termina two way sensor (SmartHome Item 1624), garage door sensors (SmartHome Item 7456), and a LampLinc Module (SmartHome Item 2000S). The garage door sensor model 7456 has both NO and NC wires. Connect the NO wires to the IOLinc terminals and mount the sensor on the wall with the magnet on the garage door. When the door is closed the light on the IOLinc will be off. When the door is open, the light will turn on. Program the IOLinc to send its signal on a housecode (I use G for garage) and a unit (such as 10). Now, set the computer up to use x10watch to listen for G10 to change state. When G10 is off, turn off the LampLinc. When G10 turns on, turn on the LampLinc and turn on the Chime module. Set the x10watch program to delay for 5 minutes after the signal is heard so that the light stays on to give you time to walk in the house and then turns off after 5 minutes when the door is closed.
Automatic garage closer: Get an X10 IOLinc 4-termina two way sensor (SmartHome Item 1624), and a garage door sensor (SmartHome Item 7456) [same as above]. Program the first channel of the IOLinc as input and wire it to the garage door sensor. Program the second channel of the IOLinc as an output and connect it to the wires that are used by the button to open and close the garage door from the wall. Now, write a C program or shell script to watch the first channel of the IOLinc for the door to open, count down a timer, and if the door isn't already closed, send an ON then OFF signal to the second channel of the IOLinc to get the garage door motor to close the door. If you want to get really fancy, use the NO circuit of the sensor to prevent the system from opening the garage door. (Note, I was initially concerned that the IOLinc might never get the off signal with the effect of holding the button down. If you do the fancy version, this won't be a problem at all. But, if you don't use the door sensor to complete the circuit, you can still just send numerous off signals to make sure that it gets it.)
Alarm automation: I have a DSC32 alarm in the house that can produce X10 signals. Every light in the hall and public rooms in the house have X10 light switches. The alarm is wired so that each individual door is a single zone so when the alarm goes off, it can send an X10 signal to indicate the entry point. Using x10watch, the computer can watch for the DSC codes on the X10 network and turn the lights on throughout the house in a sequence such that it appears that someone is walking through the house turning lights on as the person enters the room.
Dusk/Dawn light control: Get a Leviton Dusk/Dawn sensor (SmartHome Item 4235) and wire it either permanently to the outside of the house or set it in a window where it can sense the outside light. Set x10watch up to listen for the signal from the sensor and turn the outside lights for the house on and off based on the light. Extend this just a tad by using the sensor to have x10watch turn on the flood lights, porch lights, and garage lights. At bedtime, say around 11:00pm, use a cron job to turn off the flood lights so that you can sleep without the room being filled with light, turn off the outside lights, and turn on the low level lights over each of the outside doors. At dawn, use the signal from the sensor to have x10watch turn off all lights.
**Well flood control: ** If you live out in a rural area and have a well, you can have the well pump turn off if there is flooding in the house. Get a WaterBug (SmartHome Item 7160), a PowerFlash interface (SmartHome Item 4060), and a 220 V heavy duty X10 switch (SmartHome Item 2210). Wire the WaterBug up so that it can sense water on the floor in the basement and wire the bug to the powerflash interface. Now use x10watch to watch for a signal from the powerflash indicating that there is water. When the indicator is seen, turn off the well pump with the 220 V switch.
This section is going to talk about the technical details of how the code is written and how the X10 protocol works. Only read this section if you are interested in writing code for a transceiver or you are trying to debug what is happening. The details will start with a generic look at the environment for the drivers and how it relates to the X10 protocol. The details will then dig into how the 3 files for each driver fit together.
For each device on the X10 network, each housecode, and the entire network, character devices are created in the /dev/x10 directory. The major and minor numbers for the devices communicate with dev.c which creates the generic interface. All individual units are controlled by a single major character device. The default is 120. To access the housecodes without the specific units, a second major character device is used. The default is 121.
Access to the individual units is done through the data_major device. The default major number for this device is 120. The housecode is encoded into the upper nibble of the minor number and the unitcode is encoded into the lower nibble of the minor number. While X10 references the unitcodes as 1 through 16, to make things more Unix like, the unitcodes are mapped as 0 through 15. Following is a table with the mapping of the housecodes and unitcodes.
Housecode upper nibble Unitcode lower nibble A 0000 0000 (0x00) 1 0000 0000 (0x00) B 0001 0000 (0x10) 2 0000 0001 (0x01) C 0010 0000 (0x20) 3 0000 0010 (0x02) D 0011 0000 (0x30) 4 0000 0011 (0x03) E 0100 0000 (0x40) 5 0000 0100 (0x04) F 0101 0000 (0x50) 6 0000 0101 (0x05) G 0110 0000 (0x60) 7 0000 0110 (0x06) H 0111 0000 (0x70) 8 0000 0111 (0x07) I 1000 0000 (0x80) 9 0000 1000 (0x08) J 1001 0000 (0x90) 10 0000 1001 (0x09) K 1010 0000 (0xa0) 11 0000 1010 (0x0a) L 1011 0000 (0xb0) 12 0000 1011 (0x0b) M 1100 0000 (0xc0) 13 0000 1100 (0x0c) N 1101 0000 (0xd0) 14 0000 1101 (0x0d) O 1110 0000 (0xe0) 15 0000 1110 (0x0e) P 1111 0000 (0xf0) 16 0000 1111 (0x0f)
As a result, the A1 is minor 0x00 or 0, A2 is minor 0x01 or 1, B1 is minor 0x10 or 16, and B4 is 0x13 or 19.
**Housecodes, status, and control interface: **The control interface provides additional access beyond the individual units on the house. The encoding of the minor code depends on the function being accessed. The upper nibble is the action and the lower nibble is the target.
Housecode control: Commands can be sent to all units on a housecode or a subset of the units on the housecode. Further, the status of the entire housecode can be read in both a raw format and a prettier format which includes headers. The upper nibble (action) identifies if headers are to be displayed and the lower nibble (target) specifies the actual housecode as follows:
action upper nibble target lower nibble header 0000 0000 (0x00) A 0000 0000 (0x00) no header 0001 0000 (0x10) B 0000 0001 (0x01) C 0000 0010 (0x02) D 0000 0011 (0x03) E 0000 0100 (0x04) F 0000 0101 (0x05) G 0000 0110 (0x06) H 0000 0111 (0x07) I 0000 1000 (0x08) J 0000 1001 (0x09) K 0000 1010 (0x0a) L 0000 1011 (0x0b) M 0000 1100 (0x0c) N 0000 1101 (0x0d) O 0000 1110 (0x0e) P 0000 1111 (0x0f)
If /dev/x10/e is mapped to minor code 0x04 (4), the following command will result in the shown output:
$cat /dev/x10/e
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
E: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
Similarly if /dev/x10/eraw is mapped to minor code 0x14 (20), the following command will result in the shown output:
$cat /dev/x10/eraw
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
Status control: The upper nibble of the minor number is set to 0x02 to get the status of all housecodes and units in the X10 network. The lower nibble specifies what status is returned and the format. The rightmost bit specifies whether headers are to be added. The second bit from the right specifies if it is to be the actual value (percent from 0 to 100) or just the change status. This is summarized as follows:
action upper nibble target lower nibble status 0010 0000 (0x20) value wo/hdr 0000 0000 (0x00) value w/hdr 0000 0001 (0x01) change wo/hdr 0000 0010 (0x02) chane w/hdr 0000 0011 (0x03)
If the device /dev/x10/status is mapped to minor number 0x20 (32), the following command results in the associated output:
$ cat /dev/x10/status
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
A: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
B: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
C: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
D: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
E: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
F: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
G: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
H: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
I: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
J: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
K: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
L: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
M: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
N: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
O: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
P: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
When the /dev/x10/change device is read, the table shows a 1 for every device that has been changed since the last status of that device was read. When the status of a device is read through a single unit, a housecode, or the status device, the change status is reset to 0. This allows a user program to know what devices have changed since the last time the data was read.
The device driver module is comprised of 2 files. The individual files provide a level of abstraction for a particular function as defined in the following description.
- dev.c: Creates the /dev/x10/* character devices, the command processing, activity logging, and userspace API queueing. This file contains the module __init() function which calls the initialization functions for the other two files. The data for the log is actually stored as 32 bit entries which are broken into 8 byte fields in a structure. The log takes up little space in memory and is expanded to a readable format whenever it is read from the device driver.
- strings.c: Parses strings passed to the device files to generate commands to the API queues. The strings processor is also used to create the text for displaying the log.
The daemons for each transceiver are comprised of 2 source files. The individual files provide isolate the protocol simulator from the transceiver management interface. The protocol simulator requires that the transceiver management interface conform to a specific API so that the simulator does not have to be modified when a transceiver is added. The following is a description of the individual files:
- main.c: This is the protocol simulator and contains the main() function as well as the code to detach the program, launch the receiver thread, and start up the transceiver. It expects the transceiver code to contain an xmit_init() function which is expected to connect to the transceiver, initialize the device, and fill in a structure with a pointer to the function used to transmit. An argument is passed to the xmit_init() function which contains a callback routine for the receiver to call whenever a command has been received. The protocol simulator requires that the transceiver interface pass normalized values representing the standard x10 protocol. It is up to the transceiver interface to translate the native information into the normalized data.
- <transceiver>_xcvr.c: Each transceiver will have a unique file associated with it. The file must have a function called xmit_init() and will receive a single parameter which contains a pointer to a memory structure with information needed for initialization. This information includes the unix device name for the transceiver (e.g. /dev/ttyS0, /dev/usb/hiddev0, /dev/modem, etc.). The transceiver interface has the responsibility of conforming to the protocol of the hardware transceiver and translating the hardware protocol to the normalized X10 protocol required by main.c.