campbell@maynard.UUCP (Larry Campbell) (09/14/86)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # REVIEW # Makefile # x10.1 # x10.h # This archive created: Sat Sep 13 22:38:50 1986 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \SHAR_EOF > 'README' DESCRIPTION x10 is a little program for hacking a BSR X10 "Powerhouse" home control device. This gizmo, currently sold by DAK (a discount mail order house) for $49.95, can remotely control lights and appliances in your house by signaling over the house wiring. Since most people know what the X10 system does (see the DAK catalog for details; Radio Shack also sells X10 stuff) I won't describe it in detail here. The gizmo comes with software for IBM PCs, Apples, or Commodores, but I wanted to hang it off my UNIX box. So I wrote this program. The BSR X10 Powerhouse connects to a computer with an RS232 interface. It can store up to 128 events; each event can turn on, turn off, or dim up to sixteen slave units. The X10 box has a battery backed up clock which the computer can read, which turned out to be one of its biggest uses for me -- my computer doesn't have a battery clock. Each slave unit has a one-letter housecode ranging from A to P (for 16 different codes) and a number from 1 to 16. x10's command structure is pretty primitive. See the man pages for details. INSTALLATION Hopefully, the only file that needs to be configured for your system is the makefile. You may need to review x10.h and tty.c if you experience any trouble. Change BIN to the location of your favorite directory. Change OWNER to whichever login you want. Keep the GROUP set to sys. the DFLAGS line in the makefile needs to be configured as follows: add -DVENIX if you are using Venix add -DSYSV if you are using System III or V add -DMINIEXCH if you are using the DEC mini-exchange add -DVIOD if your compiler doesn't have type void add -DXDIR=\"fullpath_name/x10\" if you don't want to use the default path of the current directory After changing the makefile for your system, do 'make'. Next, cd as 'root' to /dev and link the root filesystem and tty port connected to the 'X10' as follows: ln root_fs_special_device x10fs ln tty_port x10 The port connected to the x10 should not have a getty running. The root filesystem needs to be set to group 'sys' and mode 440. ('x10 date' is the only command that requires this. If you do not want to do it because you're worried about security, do not create /dev/x10fs. All other features of x10 will work.) The tty port connected to the x10 needs to be changed to the owner of the 'X10 device', and the mode needs to be set to 600. Finially, do 'make install' as root to install x10 in the proper location, with the proper owner and the proper permissions. PORTABILITY This has been tested under VENIX/Rainbow, which is basically V7 (thus there are no short-identifier problems), and on System V, Release 3.0. It should run OK under BSD-flavor UNIX. NOTES I'm running my X10 through a DEC Mini-Exchange, which is a dumb little 8-port programmable port selector. (My computer has only one, count 'em, serial port with modem control, which is why I use the Mini-Exchange.) There are two VENIX-specific hacks in x10. First, my routine hangup() depends on a modification I made to the VENIX tty driver that causes it to drop DTR if you set the baud rate to zero, and raise it again when you set the baud rate to a nonzero number. Most modern flavors of UNIX have an ioctl or something to do this. Second, there are a number of occurrences of: sleep(SMALLPAUSE); where SMALLPAUSE is #defined to be -10. This is a VENIX-specific hack that means sleep for 10 60ths of a second, or 1/6th of a second. This isn't critical; if VENIX is not defined in the makefile, SMALLPAUSE is set to 1. EXAMPLES Example contents of an id file: 1 Bedroom switched table lamp 2 Office switched floor lamp 3 Living room ceiling lights 4 Front porch and garrage lights 5 Family room hanging lamp 6 Family room portable radio 7 Thermostat 8 Bedroom protable tv Example output of the 'x10 dump all' command using the above id file: SLOT UNIT STATE ID DESCRIPTION 0 c1 Off 001 Bedroom switched table lamp 1 c2 Off 002 Office switched floor lamp 2 c3 Off 003 Living room ceiling lights 3 c4 Off 004 Front porch and garrage lights 4 c5 Off 005 Family room hanging lamp 5 c6 Off 006 Family room portable radio 6 c7 Off 007 Thermostat 7 c8 Off 008 Bedroom protable tv EVENT STATE MODE DAYS TIME UNITS 0 On Normal Everyday 21:00 c5 1 Off Normal Everyday 22:30 c1-8 2 Dim 8 Normal Everyday 21:15 c3 3 Off Normal Everyday 21:45 c3 4 On Today 21:33 c1 5 Dim 4 Security Weekdays 20:15 c2 6 Off Normal Weekend 1:00 c1-2,6-7 - Larry Campbell (maynard!campbell) with help from John Chmielewski (rogue!jlc) September 1, 1986 SHAR_EOF fi if test -f 'REVIEW' then echo shar: "will not over-write existing file 'REVIEW'" else cat << \SHAR_EOF > 'REVIEW' =========================================================================== X10 PowerHouse Product Review Joseph M. Newcomer =========================================================================== [I gather from reading this several times that the X10 Powerhouse is a BSR controller which allows one to turn on and off various electrical outlets in your house by sendigh digital radio signals through the power lines to remote switches. -wab] I bought an X10 PowerHouse with IBM-PC software a while back from the nice folks at DAK. I couldn't get it to work, so hadn't reported on it. What I can now report is success. The basic problem was the interface was dead. This was hard to determine, since pushing an on/off key actually sent data to the machine, and the machine was clearly sending data to the PowerHouse controller, but the controller never responded to the computer. I finally got around to calling them, and got their technical guy on the line. He had me do a couple experiments and determined that it was dead. Within a week I received a new unit with a return letter to return the old (dead) one. It took a bit more experimental computer science to get it working. The documentation told me how to install DOS on my X10 disk, but not how to install X10 software on my hard disk. So of course I got it wrong; I failed to install "X10.DAT". I'm not sure what this does but it is critical; without it, the interface still appears to be dead. (The differences was that 'local control' at the interface would actually activate devices!) The error message is definitely misleading. Anyway, I installed X10.DAT and it worked. The user interface is rather tasteful. No silly little house icons with 5 bedrooms and no libraries or computer rooms (as the Radio Shack product) and you can assign any house/unit code to any device (unlike Radio Shack where you have to artificially use up all the "A" units to be able to use a "B" unit, and you can't have multiple assignments to the same code). I'd have done a few things differently, but at least they got it really well done. You can save configurations on disk files, and load the files, so I now have "normal" and "away" modes. You can temporarily "freeze" a request so it is effectively "turned off" without actually losing the data, although on the whole I prefer to use different files for this. It comes with three manuals, all rather detailed but certainly not complete. There is an owner's manual which tells how to install controllers and configure them. There is the software manual, which tells how to use the software they deliver with it. Finally, there is the programming guide, which gives in nearly-infinitesimal detail all of the async protocols for actually communicating with it. This detail, alas, misses a few key questions and isn't entirely clear anyway, but most of it appears to be there. If you have a compulsion to program it yourself, which I think is largely unnecessary given the not-bad-at-all software, you may end up on the phone to New Jersey. On the other hand, they seem anxious to help. A Good Buy, in my estimation. joe =========================================================================== Re:DAK BSR X10 Powerhouse Interface Larry Campbell =========================================================================== One small contradiction to Joe Newcomer's otherwise accurate review of the BSR X10 Powerhouse in Info-IBMPC Digest V5 #68. He said that it looked like the protocol manual was incomplete, and that anyone trying to actually write software for the thing would probably have to make a few phone calls to New Jersey. (He also wondered why anyone would want to write such software since the program shipped with the box was so good.) I had to write my own software since I am not using an IBM PC running MS-DOS, but rather a DEC Rainbow running VENIX. I was able to get my software working without any calls to New Jersey. Actually there were a couple of omissions in the manual, but I was able to figure them out without any trouble. All in all, I think the protocol manual is pretty good. Another nifty feature of the BSR box that I think Joe failed to mention is that it contains a battery backed up clock. Since there isn't a reasonable way to get a clock into a Rainbow (there are some hacks on the market at about $125, or more than twice the cost of the BSR box), I also hacked up a way for my system to query the BSR box at boot time for the date and time. All in all, I agree with Joe: the box is nifty and a bargain at $49.90. Larry Campbell The Boston Software Works, Inc. 120 Fulton Street, Boston MA 02109 UUCP: {alliant,wjh12}!maynard!campbell (617) 367-6846 SHAR_EOF fi if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \SHAR_EOF > 'Makefile' HOME = /usr/campbell BIN = $(HOME)/bin GROUP = sys OWNER = bin # set DFLAGS equal to: # -DVENIX if using VENIX # -DSYSV if using SYSTEM V # -DVOID if compiler doesn't understand 'void' # -DMINIEXCH if using the DEC mini-exchange # -DXDIR=\"fullpath_name/x10\" if not using default of "." DFLAGS = -DVENIX -DXDIR=\"$(HOME)/X10\" -DMINIEXCH CFLAGS = -O $(DFLAGS) LDFLAGS = -z -i #LIBS = -lc_s # uncomment if using shared libraries SRCS = data.c date.c delete.c diagnostic.c dump.c fdump.c \ finfo.c fload.c info.c getslot.c message.c miniexch.c \ monitor.c prints.c readid.c reset.c schedule.c setclock.c \ tty.c unit.c x10.c xread.c OBJS = data.o date.o delete.o diagnostic.o dump.o fdump.o \ finfo.o fload.o info.o getslot.o message.o miniexch.o \ monitor.o prints.o readid.o reset.o schedule.o setclock.o \ tty.o unit.o x10.o xread.o x10: $(OBJS) cc $(LDFLAGS) -o x10 $(OBJS) $(LIBS) if [ -f /usr/bin/mcs ]; then mcs -c x10; fi chgrp $(GROUP) x10 chmod 2755 x10 chown $(OWNER) x10 $(OBJS): x10.h install: x10 mv x10 $(BIN) lint: lint $(DFLAGS) $(SRCS) shar: x10.shar.1 x10.shar.2 x10.shar.1: shar README REVIEW Makefile x10.[1h] >x10.shar.1 x10.shar.2: shar $(SRCS) > x10.shar.2 clean: rm -f *.o clobber: clean rm -f x10 SHAR_EOF fi if test -f 'x10.1' then echo shar: "will not over-write existing file 'x10.1'" else cat << \SHAR_EOF > 'x10.1' .TH X10 1 local .SH NAME .B x10\^ - control program for the BSR X10 Powerhouse .SH SYNOPSIS .B x10 data \fIunit-name\fP \fIbinary-state\fP \fIid\fP .br .B x10 date .br .B x10 delete \fIrequest-type\fP \fIitem-numbers\fP .br .B x10 diagnostic .br .B x10 dump \fIrequest-type\fP .br .B x10 fdump \fIrequest-type\fP .br .B x10 finfo \fIrequest-type\fP .br .B x10 fload \fIrequest-type\fP .br .B x10 info .br .B x10 unit \fIunit-specifier\fP \fIstate\fP .br .B x10 monitor .br .B x10 reset [\fIhousecode\fP] .br .B x10 schedule \fIunit-specifier\fP \fIday-specifier\fP \fItime\fP \fIstate\fP .br .B x10 setclock .SH DESCRIPTION .I x10 is a little program for controlling a BSR X10 "Powerhouse" home control device. The BSR X10 can remotely control lights and appliances in your house by signalling over the house wiring. .PP The BSR X10 Powerhouse connects to a computer with an RS232 interface. It can store up to 128 events; each event can turn on, turn off, or dim up to sixteen slave units. The X10 box has a battery backed up clock which the computer can read. .PP Slave units are identified by a one-letter housecode ranging from A to P (for 16 different codes) and a number from 1 to 16, for a total of 256 possible unit codes. .PP You could just put a bunch of "x10 unit" commands in your crontab, but this doesn't work if your system is down for backups, or has crashed, or if someone's tripped over the RS232 cable and unplugged it, and it clutters up your crontab something awful. For most uses, it's much easier to just load the events into the X10. You can dump the schedule into a file (with the \fBx10 fdump\fP command), and you can have different files for different times of the year, for before and after Daylight Savings Time, etc. .PP X10 unit descriptions are kept in a file called \fBid\fR. Each line contains a number (1-255) and a unit description (0-39 characters), separated by a tab. The number represents a code that can be stored in the X10 along with a unit id using the \fBx10 data\fR command. If the \fBid\fR file exists, the \fBx10 dump data\fR or \fBx10 dump all\fR commands will print descriptions for each unit code contained in the file. .SH COMMANDS .IP \fBdata\fP \fIunit-name\fP \fIbinary-state\fP \fIid\fP Loads data into "graphics" storage in X10 box. Currently used to record correspondence between id file identifier and unit code, and current state of unit. This stuff is incomplete at present. .PP .IP \fBdate\fP Gets current date and time from X10 and displays it in a form suitable for feeding to \fIdate(1)\fP as input. Thus, you can set your system clock by saying "date `x10 date`". .PP .IP \fBdelete\fP \fIrequest-type\fP \fIitem-numbers\fP Deletes the request of type \fIrequest-type\fP with item number \fIitem-number\fP from X10 memory. .PP .IP \fBdiagnostic\fP Runs the X10 diagnostic and reports the result. \fBCaution:\fP running the diagnostic scrambles X10 memory, losing all downloaded events and data. .PP .IP \fBdump\fP \fIrequest-type\fP Writes a readable description of all events of type \fIrequest-type\fP on standard output. .PP .IP \fBfdump\fP \fIrequest-type\fP Writes an unreadable description (binary data) of all events of type \fIevent-type\fP on standard output. If you redirect this stuff to a file, you can subsequently feed it to a \fBx10 fload\fP command. .PP .IP \fBfinfo\fP \fIrequest-type\fP Like \fBdump\fP, but reads binary data in \fBfdump\fP format from standard input, rather than reading data from the X10. .PP .IP \fBfload\fP \fIrequest-type\fP Loads the X10 memory with requests of type \fIrequest-type\fP from data on standard input in \fBx10 fdump\fP format. .PP .IP \fBinfo\fP Displays current setting of X10's clock and housecode. .PP .IP \fBunit\fP \fIunit-specifier\fP \fIstate\fP Sets the specified unit to the specifed state. .PP .SH ARGUMENTS Most X10 commands require arguments. They are as follows: .TP 5 \fIhousecode\fP housecode is a letter from a-p .TP 5 \fIid\fP The identification number of the unit (1-255). It is used to associate a description string from the ID file to a specific unit. .TP 5 \fIitem-number\fP An X10 event-numbers (0-127) or id-slot (0-255). .TP 5 \fIbinary-state\fP id-state is either \fBon\fR or \fBoff\fR .TP 5 \fIday-specifier\fP mode-day is in the form: (mode) ([day]) .br Modes: .RS 5 \fBn\fRormal (days) .br \fBse\fRcurity (days) .br \fBtod\fRay .br \fBtom\fRorrow .RE Days: .RS 5 \fBm\fRonday, \fBtu\fResday, \fBwed\fRnesday, \fBth\fRursday, \fBf\fRriday, .br \fBsa\fRturday, \fBsu\fRnday, \fBweekd\fRay, \fBweeke\fRnd, \fBe\fRveryday .RE .TP 5 \fIunit-name\fP A name for a single unit in the form: (housecode)(unit-number) .RS 5 housecode is a letter from a-p unit-number is a number from 1-16 .RE .TP 5 \fIunit-specifier\fP A specifier for one or more units, in the form (housecode)(unit-number[,unit-number...]) .RS 5 housecode is a letter from a-p .br unit-number is a number from 1-16 or a '*' to indicate all units .RE 3 .TP 5 \fIrequest-type\fP request is \fBevents\fR or \fBdata\fR for delete, fdump, finfo, and fload commands .br request is \fBevents\fR or \fBdata\fR or \fBall\fR for dump command .TP 5 \fIstate\fP state is in the form: (function) ([value]) .RS 5 .B on .br .B off .br .B dim (value) .RS 5 value is a number from 1-16 .RE 3 .TP 5 \fItime\fP Time is in 24 hour format of the form HH:MM .SH EXAMPLES .TP 5 x10 unit a5 on Turns slave unit A5 on. .TP 5 x10 unit b7 dim 8 Sets unit B7 to dim level 8 (levels run from 0 to 15, bright to dim) .TP 5 x10 info Displays X10 clock time and base housecode .TP 5 x10 setclock Sets X10's clock to current time of day (from UNIX) .TP 5 x10 schedule a3,5 security everyday 17:30 off Enters an event to turn units A3 and A5 off every day about 17:30 .TP 5 x10 schedule a2 normal wed 5:00 on Enters an event to turn unit A2 on every Wednesday at 5:00 .TP 5 x10 schedule b8 today 9:00 dim 9 Enters an event to dim unit B8 to level 9 today at 9:00 .TP 5 x10 dump all Displays all events and data in X10's memory .TP 5 x10 delete event 12 Deletes event 12 from X10's memory .TP 5 x10 reset Clears X10 memory, deletes all events and sets housecode A .br (does not clobber clock) .TP 5 x10 reset c Clears X10 memory, deletes all events and sets housecode C .br (does not clobber clock) .TP 5 x10 diagnostic The X10 performs its internal diagnostic routine .br (clobbers memory and clock, but not housecode) .TP 5 x10 fdump data > datafile Dumps X10 id data into file .TP 5 x10 fload events <eventfile Loads X10 event data from file .TP 5 x10 finfo events < eventfile Displays events in file produced by x10 fdump .TP 5 x10 date Displays date in date(1) input format. .SH FILES id - X10 unit description file .SH AUTHORS Originally written by Larry Campbell (maynard!campbell). System V port, ID file, improved display formats, and other cleanup by John Chmielewski (rogue!jlc). .SH SEE ALSO X10 POWERHOUSE computer interface model no. CP290 programming guide .br date(1) SHAR_EOF fi if test -f 'x10.h' then echo shar: "will not over-write existing file 'x10.h'" else cat << \SHAR_EOF > 'x10.h' /* * Copyright 1986 by Larry Campbell, 73 Concord Street, Maynard MA 01754 USA * (maynard!campbell). You may freely copy, use, and distribute this software * subject to the following restrictions: * * 1) You may not charge money for it. * 2) You may not remove or alter this copyright notice. * 3) You may not claim you wrote it. * 4) If you make improvements (or other changes), you are requested * to send them to me, so there's a focal point for distributing * improved versions. * * John Chmielewski (tesla!jlc until 9/1/86, then rogue!jlc) assisted * by doing the System V port and adding some nice features. Thanks! */ /* * BSR X-10 "Powerhouse" Computer Interface Definitions */ /***********************************************************************/ /* You probably only need to hack this section to reconfigure for */ /* your system */ /***********************************************************************/ /* Some lints don't know about the void type */ #ifdef VOID #define void int #endif #define DEVNAME "/dev/x10" /* terminal line X10 box is connected to */ #define ROOTNAME "/dev/x10fs" /* name of root filesystem */ #ifndef XDIR #define XDIR "." /* directory containing X10 files */ #endif #define IDFILE "/id" /* description file for X10 modules */ #ifdef MINIEXCH /* if talking through a DEC Mini-Exchange */ #define MINIXPORT 3 /* port number X10 gizmo is plugged in to */ #endif #ifdef VENIX #define SMALLPAUSE -10 /* 1/6th of a second sleep(3) (VENIX only) */ #else #define SMALLPAUSE 1 #endif #define TIMEOUT 10 /* seconds to wait for data */ #define DTIMEOUT 15 /* timeout for dim and diagnostic commands */ /***********************************************************************/ /* End of configuration section */ /***********************************************************************/ #define SYNCN 16 /* number of FF chars to send before packet */ #define CHKSUM(buf) chksum(buf, sizeof(buf)) /* Event item as stored in event file */ struct evitem { unsigned e_num; unsigned char e_buf[8]; }; #define EVSIZE sizeof(struct evitem) #define EVENTS "events" /* event data keyword */ #define ETOTAL 128 /* total number of events */ #define ESIZE 8 /* size of event data field */ #define EVCMD 12 /* size of event command */ /* Data item as stored in data file */ struct ditem { unsigned d_num; unsigned char d_buf[2]; }; #define DISIZE 6 /* sizeof not used as it includes holes */ #define DATA "data" /* id data keyword */ #define DTOTAL 256 /* total number of id's */ #define DSIZE 2 /* size of id data field */ #define DICMD 6 /* size of data command */ /* description field structure */ #define DLENGTH 40 /* length of the description field */ struct id { char describe[DLENGTH]; }; /* Command codes */ #define SETHCODE 0 /* load house code */ #define DIRCMD 1 /* direct command */ #define SETCLK 2 /* set clock */ #define DATALOAD 3 /* timer/graphics data download */ #define GETINFO 4 /* get house code and clock */ #define GETEVENTS 5 /* get timer events */ #define GETDATA 6 /* get graphics data */ #define DIAGNOSE 7 /* run diagnostic */ #define XMTSYNC 16 /* transmitted sync length */ #define RCVSYNC 6 /* received sync length */ /* House code magic numbers */ #define HC_A 0x60 #define HC_B 0xE0 #define HC_C 0x20 #define HC_D 0xA0 #define HC_E 0x10 #define HC_F 0x90 #define HC_G 0x50 #define HC_H 0xD0 #define HC_I 0x70 #define HC_J 0xF0 #define HC_K 0x30 #define HC_L 0xB0 #define HC_M 0x00 #define HC_N 0x80 #define HC_O 0x40 #define HC_P 0xC0 struct hstruct { unsigned char h_code; char h_letter; }; struct nstruct { char *n_name; char n_code; }; /* Message definitions */ #define EM_2MANY "Too many command line arguments" #define EM_INVCN "Invalid command name" #define EM_WNA "Wrong number of arguments" #define EM_NMA "Need more command line arguments" #define EM_NOCMD "No command argument specified" /* External Variables */ extern char *E_2MANY, *E_INVCN, *E_WNA, *E_NMA, *E_NOCMD; SHAR_EOF fi exit 0 # End of shell archive -- Larry Campbell The Boston Software Works, Inc. ARPA: campbell%maynard.uucp@harvard.ARPA 120 Fulton Street, Boston MA 02109 UUCP: {alliant,wjh12}!maynard!campbell (617) 367-6846