Spx10 is a software for asynchronous raw serial port communication with the X10 CM17A Computer Interface.
The default port is /dev/ttyS0 at 9600 baud. The default semaphore lock file is /var/lock/LCK..ttyS0, which has an fcntl(2) advisory lock applied. The serial port is controlled through termios(3), and is restored to original values on exit. The serial port child read process is created by fork(2) from the parent write process, and both processes respond to SIGINT = ^C and SIGTERM signals. Asynchronous serial port control is implemented with select(2). The input file, (usually stdin for commands,) uses canonical input for flow control. The X10 device and transmission codes are cross indexed in a binary search database using mmap(2), which also contains a command sequence field, (including shell calls,) that are executed in response to a specific transmission code. Variable names and states are supported via a hash lookup table.
The database file is a Unix tab delimited field file, in lexical order, (i.e., constructed with sort(1),) consisting of four fields:
The X10 transmission code.
The device code and command.
A user defined alias.
A command sequence to execute in response to the transmission code.
d5 aa 64 00 ad a9 on porch motion a11 on;
isset ix exec echo "motion detected"
| mailx -s "motion detected" email@example.com
would turn on device A11, and then, send a message to my cell phone if motion was detected on my front porch, but only if the variable "ix" was set, (e.g., the variable "ix" enables transmission to my cell phone.) The motion detector is on house code A, device code 9, which has the transmission sequence, "d5 aa 64 00 ad." (The reason for including the transmission sequence in the database was for extensibility with other devices and products-the program will print unknown transmission sequences received for future inclusion in the database-or take evasive action in jamming or collision situations, etc.)
The language in field 4:
[a-p][1-9][0-6]?: house code and unit code, i.e., "b12"
on: turn a device on, i.e., "b12 on"
off: turn a device off, i.e., "b12 off"
dim ([0-9][0-2]?)?: dim a device, i.e., "b12 dim" or "b12 dim 5"
bright ([0-9][0-2]?)?: brighten a device, i.e., "b12 bright" or "b12 bright 5"
all_off: all devices off in a house, i.e., "b all_off"
all_on: all devices on in a house, i.e., "b all_on"
all_lamps_off: all lamps off in a house, i.e., "b all_lamps_off", (actually an alias for all_off)
all_lamps_on: all lamps on in a house, i.e., "b all_lamps_on", (actually an alias for all_on)
quit: stop the program
exit: alias for "quit"
set < variable >: set a variable, i.e., "set x123", (a variable is either set, or it isn't)
reset < variable >: reset a variable, i.e., "reset x123", (a variable is either set, or it isn't)
unset: alias for "reset"
isset < variable > < action >: test if a variable is set, i.e., "isset x123 b12 on", (a variable is either set, or it isn't)
isnotset < variable > < action >: test if a variable is not set, i.e., "isnotset x123 b12 on", (a variable is either set, or it isn't)
exec < command >: execute a command
system: alias for "exec"
variable: any alphanumeric string not one of the above keywords
';': command delimiter, i.e., "isset x123 b12 on; isset abc b11 off"
Note that the isset and isnotset commands allow simple constructs-the main function is to inhibit spawning a shell for every instance of a state change, (like a motion detector in a room,) for example:
isset x123 exec myfile; isset abc exec myprogram
would invoke a shell process only if x123, (or abc,) is set; any more complicated constructs should be handled by the shell interpreter in a batch file.