PROGRAM_NAME='WITCC V2' (*****************************************************************) (*****************************************************************) (* FILE_LAST_MODIFIED_ON: 05/15/2007 AT: 14:35:30 *) (* Control of CM11A X-10 Activehome Interface *) (* Code copyright 2003 Ryan P. Wright (amxguy@ryanwright.com) *) (* Modified for use with NetLinx by Dave McDonald (davewmc@ncn.net *) (* VERSION 1.0 LAST MODIFIED: 5/15/2007 *) (* *) (* 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) *) (* *) (*****************************************************************) (* System Type : NetLinx *) (**********************************************************) (* REV HISTORY: *) (**********************************************************) (* $History: $ *) (**********************************************************) (* DEVICE NUMBER DEFINITIONS GO BELOW *) (**********************************************************) DEFINE_DEVICE Processor = 05001:1:0 TP = 128:1:0 (* Touch Panel *) RS232_2 = 05001:2:0 (* RS-232 Serial Port *) (***********************************************************) (* CONSTANT DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_CONSTANT (***********************************************************) (* DATA TYPE DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_TYPE (***********************************************************) (* VARIABLE DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_VARIABLE (* X-10 *) CHAR X10_BUFFER[255] CHAR X10_COMMAND[255] CHAR X10_XMIT_OBJECT[255] CHAR X10_XMIT_OBJECT_CKSUM[255] CHAR X10_XMIT_FUNCTION[255] CHAR X10_XMIT_FUNCTION_CKSUM[255] CHAR X10_RECV_CHECKSUM[255] CHAR TP_BUFFER[255] INTEGER X10_READY INTEGER X10_LOSTREADYCOUNT INTEGER X10_GET_CHECKSUM INTEGER X10_CHECKSUM_RETRY INTEGER X10_TEMP_HOUSE INTEGER X10_TEMP_UNIT INTEGER X10_TEMP_FUNC (***********************************************************) (* LATCHING DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_LATCHING (***********************************************************) (* MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_MUTUALLY_EXCLUSIVE (***********************************************************) (* SUBROUTINE/FUNCTION DEFINITIONS GO BELOW *) (***********************************************************) (* EXAMPLE: DEFINE_FUNCTION () *) (* EXAMPLE: DEFINE_CALL '' () *) (***********************************************************) (* STARTUP CODE GOES BELOW *) (***********************************************************) DEFINE_START (* Initialize serial ports *) SEND_COMMAND RS232_2,'SET BAUD 4800,N,8,1' (* Set port 2=4800,N,8,1 *) (* Initialize buffers *) CREATE_BUFFER RS232_2,X10_BUFFER CREATE_BUFFER TP,TP_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 X10_RECV_CHECKSUM = "" (***********************************************************) (* THE EVENTS GO BELOW *) (***********************************************************) DEFINE_EVENT (***********************************************************) (* THE ACTUAL PROGRAM GOES BELOW *) (***********************************************************) 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(TP_BUFFER)) { SELECT { ACTIVE(FIND_STRING(TP_BUFFER, 'X10:',1)): { X10_COMMAND = TP_BUFFER } } } (* select *) (* if TP_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,$20" (* 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, ':01:',6)): { X10_TEMP_UNIT = 6 } ACTIVE(FIND_STRING(X10_COMMAND, ':02:',6)): { X10_TEMP_UNIT = 14 } ACTIVE(FIND_STRING(X10_COMMAND, ':03:',6)): { X10_TEMP_UNIT = 2 } ACTIVE(FIND_STRING(X10_COMMAND, ':04:',6)): { X10_TEMP_UNIT = 10 } ACTIVE(FIND_STRING(X10_COMMAND, ':05:',6)): { X10_TEMP_UNIT = 1 } ACTIVE(FIND_STRING(X10_COMMAND, ':06:',6)): { X10_TEMP_UNIT = 9 } ACTIVE(FIND_STRING(X10_COMMAND, ':07:',6)): { X10_TEMP_UNIT = 5 } ACTIVE(FIND_STRING(X10_COMMAND, ':08:',6)): { X10_TEMP_UNIT = 13 } ACTIVE(FIND_STRING(X10_COMMAND, ':09:',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) { (* Get Function checksum *) X10_RECV_CHECKSUM = X10_BUFFER } 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(TP_BUFFER)) {CLEAR_BUFFER TP_BUFFER} (* CLEAR THE TP_BUFFER *) IF(LENGTH_STRING(X10_BUFFER)) { CLEAR_BUFFER X10_BUFFER } (***********************************************************) (* END OF PROGRAM *) (* DO NOT PUT ANY CODE BELOW THIS COMMENT *) (***********************************************************)