(* Control of CM11A X-10 Activehome Interface *) (* Code copyright 2003 Ryan P. Wright (amxguy@ryanwright.com) *) (* VERSION 1.0 LAST MODIFIED: 2/3/2003 *) (* *) (* This code is free for personal (non-profit) use by individuals. *) (* *) (* Feel free to distribute to others. Please leave these comments *) (* intact if you distribute the code. (You're welcome to remove them *) (* for your own use) *) (* *) DEFINE_DEVICE RS232_2 = 2 (* cm11a activehome interface *) DEFINE_VARIABLE (* X-10 *) X10_BUFFER[255] X10_COMMAND[255] X10_XMIT_OBJECT[255] X10_XMIT_OBJECT_CKSUM[255] X10_XMIT_FUNCTION[255] X10_XMIT_FUNCTION_CKSUM[255] X10_RECV_CHECKSUM[255] X10_READY X10_LOSTREADYCOUNT X10_GET_CHECKSUM X10_CHECKSUM_RETRY X10_TEMP_HOUSE X10_TEMP_UNIT X10_TEMP_FUNC DEFINE_START (* Initialize serial ports *) SEND_COMMAND RS232_2,'SET BAUD 4800,N,8,1,232 ENABLE' (* 4800,8,N,1, RS-232 MODE, Enabled *) (* Initialize buffers *) CREATE_BUFFER RS232_2,X10_BUFFER (* X10 *) X10_READY = 1 X10_LOSTREADYCOUNT = 0 X10_GET_CHECKSUM = 0 X10_CHECKSUM_RETRY = 0 X10_TEMP_UNIT = 255 X10_TEMP_HOUSE = 255 X10_TEMP_FUNC = 255 DEFINE_PROGRAM (* In order to send X-10 commands, you'll need to drop the appropriate syntax into the array X10_COMMAND. Syntax is explained later. Below is an example of how to put incoming strings from a touch panel into X10_COMMAND: IF(LENGTH_STRING(THEATERTP_BUFFER)) { SELECT { ACTIVE(FIND_STRING(THEATERTP_BUFFER, 'X10:',1)): { X10_COMMAND = THEATERTP_BUFFER } } } (* select *) } (* if theatertp_buffer *) *) (**************************************************************************************) (* X-10 *) IF(LENGTH_STRING(X10_BUFFER)) { IF(X10_BUFFER = "$55") { (* interface ready *) X10_READY = 1 X10_LOSTREADYCOUNT = 0 } (* interface ready *) IF(X10_BUFFER = "$5A") { (* incoming x10 *) SEND_STRING RS232_2,"$C3" (* respond *) (* nothing is done with incoming x10 data *) (* if you wanted to do something with it, here would be the place *) } (* incoming x10 *) IF(X10_BUFFER = "$A5") { (* cm11 requesting init - clock set & housecode to monitor *) SEND_STRING RS232_2,"$9B,$00,$00,$00,$00,$00,$60" (* 00:00:00, 00/00/0000, House code A *) } (* cm11a requesting init *) IF (X10_GET_CHECKSUM = 1) { (* expecting checksum *) X10_RECV_CHECKSUM = X10_BUFFER } } (* if x10_buffer *) IF(LENGTH_STRING(X10_COMMAND)) { (* To send X-10 commands, use the following format: X10:HOUSE:UNIT:FUNCTION Example: X10:K:13:ON You may omit the unit number if you're only sending a function: Example: X10:K:BRI Valid housecodes are A-P. Valid devices are 1-16. Valid functions are: ON - Turn unit on OFF - Turn unit off DIM - Dim unit BRI - Brighten unit ALLUOFF - Turn all units off ALLLON - Turn all lights on ALLLOFF - Turn all lights off *) IF (X10_XMIT_OBJECT = "" AND X10_XMIT_FUNCTION = "") { (* only accept data if nothing waiting to xmit *) X10_READY = 1 X10_LOSTREADYCOUNT = 0 (* reset X10_READY - two way modules have problems sometimes *) SELECT { ACTIVE(FIND_STRING(X10_COMMAND, ':A:',4)): { X10_TEMP_HOUSE = 96 } ACTIVE(FIND_STRING(X10_COMMAND, ':B:',4)): { X10_TEMP_HOUSE = 224 } ACTIVE(FIND_STRING(X10_COMMAND, ':C:',4)): { X10_TEMP_HOUSE = 32 } ACTIVE(FIND_STRING(X10_COMMAND, ':D:',4)): { X10_TEMP_HOUSE = 160 } ACTIVE(FIND_STRING(X10_COMMAND, ':E:',4)): { X10_TEMP_HOUSE = 16 } ACTIVE(FIND_STRING(X10_COMMAND, ':F:',4)): { X10_TEMP_HOUSE = 144 } ACTIVE(FIND_STRING(X10_COMMAND, ':G:',4)): { X10_TEMP_HOUSE = 80 } ACTIVE(FIND_STRING(X10_COMMAND, ':H:',4)): { X10_TEMP_HOUSE = 208 } ACTIVE(FIND_STRING(X10_COMMAND, ':I:',4)): { X10_TEMP_HOUSE = 112 } ACTIVE(FIND_STRING(X10_COMMAND, ':J:',4)): { X10_TEMP_HOUSE = 240 } ACTIVE(FIND_STRING(X10_COMMAND, ':K:',4)): { X10_TEMP_HOUSE = 48 } ACTIVE(FIND_STRING(X10_COMMAND, ':L:',4)): { X10_TEMP_HOUSE = 176 } ACTIVE(FIND_STRING(X10_COMMAND, ':M:',4)): { X10_TEMP_HOUSE = 0 } ACTIVE(FIND_STRING(X10_COMMAND, ':N:',4)): { X10_TEMP_HOUSE = 128 } ACTIVE(FIND_STRING(X10_COMMAND, ':O:',4)): { X10_TEMP_HOUSE = 64 } ACTIVE(FIND_STRING(X10_COMMAND, ':P:',4)): { X10_TEMP_HOUSE = 192 } } SELECT { ACTIVE(FIND_STRING(X10_COMMAND, ':1:',6)): { X10_TEMP_UNIT = 6 } ACTIVE(FIND_STRING(X10_COMMAND, ':2:',6)): { X10_TEMP_UNIT = 14 } ACTIVE(FIND_STRING(X10_COMMAND, ':3:',6)): { X10_TEMP_UNIT = 2 } ACTIVE(FIND_STRING(X10_COMMAND, ':4:',6)): { X10_TEMP_UNIT = 10 } ACTIVE(FIND_STRING(X10_COMMAND, ':5:',6)): { X10_TEMP_UNIT = 1 } ACTIVE(FIND_STRING(X10_COMMAND, ':6:',6)): { X10_TEMP_UNIT = 9 } ACTIVE(FIND_STRING(X10_COMMAND, ':7:',6)): { X10_TEMP_UNIT = 5 } ACTIVE(FIND_STRING(X10_COMMAND, ':8:',6)): { X10_TEMP_UNIT = 13 } ACTIVE(FIND_STRING(X10_COMMAND, ':9:',6)): { X10_TEMP_UNIT = 7 } ACTIVE(FIND_STRING(X10_COMMAND, ':10:',6)): { X10_TEMP_UNIT = 15 } ACTIVE(FIND_STRING(X10_COMMAND, ':11:',6)): { X10_TEMP_UNIT = 3 } ACTIVE(FIND_STRING(X10_COMMAND, ':12:',6)): { X10_TEMP_UNIT = 11 } ACTIVE(FIND_STRING(X10_COMMAND, ':13:',6)): { X10_TEMP_UNIT = 0 } ACTIVE(FIND_STRING(X10_COMMAND, ':14:',6)): { X10_TEMP_UNIT = 8 } ACTIVE(FIND_STRING(X10_COMMAND, ':15:',6)): { X10_TEMP_UNIT = 4 } ACTIVE(FIND_STRING(X10_COMMAND, ':16:',6)): { X10_TEMP_UNIT = 12 } } SELECT { ACTIVE(FIND_STRING(X10_COMMAND, ':ALLUOFF',1)): { X10_TEMP_FUNC = 0 } ACTIVE(FIND_STRING(X10_COMMAND, ':ALLLON',1)): { X10_TEMP_FUNC = 1 } ACTIVE(FIND_STRING(X10_COMMAND, ':ON',1)): { X10_TEMP_FUNC = 2 } ACTIVE(FIND_STRING(X10_COMMAND, ':OFF',1)): { X10_TEMP_FUNC = 3 } ACTIVE(FIND_STRING(X10_COMMAND, ':DIM',1)): { X10_TEMP_FUNC = 4 } ACTIVE(FIND_STRING(X10_COMMAND, ':BRI',1)): { X10_TEMP_FUNC = 5 } ACTIVE(FIND_STRING(X10_COMMAND, ':ALLLOFF',1)): { X10_TEMP_FUNC = 6 } } IF(X10_TEMP_HOUSE <> 255 AND X10_TEMP_UNIT <> 255) { (* broadcasting unit *) X10_XMIT_OBJECT = "04,X10_TEMP_HOUSE+X10_TEMP_UNIT" X10_XMIT_OBJECT_CKSUM = "((04+(X10_TEMP_HOUSE+X10_TEMP_UNIT))&$FF)" } (* if broadcasting unit *) IF(X10_TEMP_HOUSE <> 255 AND X10_TEMP_FUNC <> 255) { (* broadcasting function *) X10_XMIT_FUNCTION = "06,X10_TEMP_HOUSE+X10_TEMP_FUNC" X10_XMIT_FUNCTION_CKSUM = "((06+(X10_TEMP_HOUSE+X10_TEMP_FUNC))&$FF)" } (* if broadcasting function *) } (* if nothing waiting to xmit *) X10_COMMAND = "" X10_TEMP_UNIT = 255 X10_TEMP_HOUSE = 255 X10_TEMP_FUNC = 255 } (* if X10_COMMAND *) IF(LENGTH_STRING(X10_XMIT_OBJECT) AND LENGTH_STRING(X10_XMIT_FUNCTION)) { (* xmit object *) IF(X10_GET_CHECKSUM = 0 AND X10_READY = 1) { (* send transmission *) SEND_STRING RS232_2,"X10_XMIT_OBJECT" X10_GET_CHECKSUM = 1 X10_READY = 0 } IF (X10_GET_CHECKSUM = 1 AND LENGTH_STRING(X10_RECV_CHECKSUM)) { (* got checksum *) IF (X10_RECV_CHECKSUM = X10_XMIT_OBJECT_CKSUM) { (* checksum OK *) SEND_STRING RS232_2,"$00" (* tell interface *) X10_GET_CHECKSUM = 0 X10_CHECKSUM_RETRY = 0 X10_RECV_CHECKSUM = "" X10_XMIT_OBJECT = "" X10_XMIT_OBJECT_CKSUM = "" } ELSE { (* checksum NOT OK *) SEND_STRING RS232_2,"X10_XMIT_OBJECT" (* resend transmission *) X10_CHECKSUM_RETRY = X10_CHECKSUM_RETRY + 1 } } (* if got checksum *) IF(X10_GET_CHECKSUM = 0 AND X10_READY = 0) { X10_LOSTREADYCOUNT = X10_LOSTREADYCOUNT + 1 } IF(X10_LOSTREADYCOUNT = 30) { X10_READY = 1 X10_LOSTREADYCOUNT = 0 } } (* if xmit object *) IF(X10_XMIT_OBJECT = "" AND LENGTH_STRING(X10_XMIT_FUNCTION)) { (* xmit function *) IF(X10_GET_CHECKSUM = 0 AND X10_READY = 1) { (* send transmission *) SEND_STRING RS232_2,"X10_XMIT_FUNCTION" X10_GET_CHECKSUM = 1 X10_READY = 0 } IF (X10_GET_CHECKSUM = 1 AND LENGTH_STRING(X10_RECV_CHECKSUM)) { (* got checksum *) IF (X10_RECV_CHECKSUM = X10_XMIT_FUNCTION_CKSUM) { (* checksum OK *) SEND_STRING RS232_2,"$00" (* tell interface *) X10_GET_CHECKSUM = 0 X10_CHECKSUM_RETRY = 0 X10_RECV_CHECKSUM = "" X10_XMIT_FUNCTION = "" X10_XMIT_FUNCTION_CKSUM = "" } ELSE { (* checksum NOT OK *) SEND_STRING RS232_2,"X10_XMIT_FUNCTION" (* resend transmission *) X10_CHECKSUM_RETRY = X10_CHECKSUM_RETRY + 1 } } (* if got checksum *) IF(X10_GET_CHECKSUM = 0 AND X10_READY = 0) { X10_LOSTREADYCOUNT = X10_LOSTREADYCOUNT + 1 } IF(X10_LOSTREADYCOUNT = 30) { X10_READY = 1 X10_LOSTREADYCOUNT = 0 } } (* if xmit function *) IF (X10_CHECKSUM_RETRY >= 3) { (* too many retries, kill remaining transmissions *) X10_XMIT_OBJECT = "" X10_XMIT_OBJECT_CKSUM = "" X10_XMIT_FUNCTION = "" X10_XMIT_FUNCTION_CKSUM = "" X10_GET_CHECKSUM = 0 X10_RECV_CHECKSUM = "" X10_CHECKSUM_RETRY = 0 X10_READY = 1 } (* if too many retries *) (* End X-10 ***************************************************************************) (**************************************************************************************) IF(LENGTH_STRING(X10_BUFFER)) { CLEAR_BUFFER X10_BUFFER } (* END PROGRAM *)