Home AMX User Forum NetLinx Studio

Be Gentle Please

This is the first bit of AMX code i have written and the fist bit of code of any type I have done in about 12 years. I would appreciate some tips or critique of what I'm doing here. It all seems to work as I expect but needs some polish. I considered including the .AXW file but that was 10 megs and I was unsure how the forum host would feel about that.

Thank you for any advice you may have.
Garret
PROGRAM_NAME='SHOWROOM_MAIN001'
(***********************************************************)
(***********************************************************)
(*  FILE_LAST_MODIFIED_ON: 04/05/2006  AT: 09:00:25        *)
(***********************************************************)
(* System Type : NetLinx                                   *)
(***********************************************************)
(* REV HISTORY:                                            *)
(***********************************************************)
(*
   $History: $
*)
(***********************************************************)
(*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_DEVICE

MASTER 						=	0:1:0			//HOUSE CONTROLLER, AMX NI-3100
dvARQ1 						=	0:2:0			//Set the IP Address or Baud settings in the ARQ Main v6_0_2 file!!
dvVANTAGE					=	0:3:0			//VANTAGE SYSTEM

//--DEVICE DEFFINISIONS
dvAVRECEIVER232			=	5001:1:0		//AV RECEIVER FOR FRONT ROOM SURROUND
dvAVSWITCH232				=	5001:2:0		//AV MATREX SWITCHER FOR SHOW ROOM
dvTVCONFRENCE232			=	5001:6:0		//CONFRENCE ROOM TV
dvTVFRONT232				=	5001:7:0		//FRONT ROOM TV
dvSATIR						=	5001:15:0	//STORE SAT DVR
dvBLUERAYIR					=	5001:16:0	//SHOWROOM BLUERAY
dvGAME						=	5001:14:0
dvRELAYS						=	5001:8:0		//RELAY SECTION OF CONTROLLER
dvIO							=	5001:17:0	//I/O SECTION OF CONTROLLER

//---TOUCH PANNEL DEFFINISIONS
dvTP_CONFRENCE_MAIN		=	10001:1:0
dvTP_CONFRENCE_SW			=	10001:2:0
dvTP_CONFRENCE_SAT		=	10001:11:0
dvTP_CONFRENCE_BLUERAY	=	10001:12:0
dvTP_CONFRENCE_GAME		=	10001:13:0
dvTP_CONFRENCE_REQUEST	=	10001:14:0
dvTP_CONFRENCE_RADIO		=	10001:15:0
dvTP_CONFRENCE_LIGHTS	=	10001:20:0
dvTP_CONFRENCE_LIGHTS_S	=	10001:21:0	//SLIDER FUNCTIONS FOR LIGHTS PAGE

dvTP_FRONT_MAIN			=	10002:1:0
dvTP_FRONT_SW				=	10002:2:0
dvTP_FRONT_SAT				=	10002:11:0
dvTP_FRONT_BLUERAY		=	10002:12:0
dvTP_FRONT_GAME			=	10002:13:0
dvTP_FRONT_REQUEST		=	10002:14:0
dvTP_FRONT_RADIO			=	10002:15:0
dvTP_FRONT_LIGHTS			=	10002:20:0
dvTP_FRONT_LIGHTS_S		=	10002:21:0

//VIRTUAL DEVICES
vdvARQ1_1					= 34000:1:0;	//Virtual device for ARQ 1, Zone 1
vdvARQ1_2					= 34001:1:0;	//Virtual device for ARQ 1, Zone 2
vdvARQ1_3					= 34002:1:0;	//Virtual device for ARQ 1, Zone 3
vdvARQ1_4					= 34003:1:0;	//Virtual device for ARQ 1, Zone 4

(***********************************************************)
(*               CONSTANT DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_CONSTANT

//VANTAGE CONTROLLER CONNECTION INFORMATION
CHAR sIPVANTAGE [] = '10.0.0.16'
svPORT = 3001
IP_TCP = 1
(*ADD ALL THE VIDs OF THE LOADS IN THE VANTAGE SYSTEM*)
NON_VOLATILE CHAR	cLOADVID[2000] = {'23 24 25 26 27 28 29 30 31 33 34 35 36 37 38 39'}
(*MAKE SURE THE STRING STARTS WITH A SPACE*)

SATPower_On    = 27
SATPower_Off   = 28
BRAYPower      = 9
//SYNC CONSTANTS
SYNC1				= 1
SYNC2				= 2
SYNC3				= 3
SYNC4				= 4
SYNC5				= 5
SYNC6				= 6
SYNCSAT			= 7
SYNCBLUERAY 	= 8

(***********************************************************)
(*              DATA TYPE DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_TYPE

(***********************************************************)
(*               VARIABLE DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_VARIABLE
//DEVICE ARRAYS
DEV arrTPMAIN[]		= {dvTP_CONFRENCE_MAIN,dvTP_FRONT_MAIN}
DEV arrTPSAT[] 		= {dvTP_CONFRENCE_SAT,dvTP_FRONT_SAT}
DEV arrTPBLUERAY[]	= {dvTP_CONFRENCE_BLUERAY,dvTP_FRONT_BLUERAY}
DEV arrTPREQUEST[]	= {dvTP_CONFRENCE_REQUEST,dvTP_FRONT_REQUEST}
DEV arrTPLIGHTS[]		= {dvTP_CONFRENCE_LIGHTS,dvTP_FRONT_LIGHTS}
DEV arrTPLIGHTS_S[]	= {dvTP_CONFRENCE_LIGHTS_S,dvTP_FRONT_LIGHTS_S}
DEV arrTPRADIO[]		= {dvTP_CONFRENCE_RADIO,dvTP_FRONT_RADIO}
DEV arrTV[]				= {dvTVCONFRENCE232,dvTVFRONT232}

//TP VARIABLES
//RECEIVER VARIABLES
VOLATILE CHAR 			cRECEIVERBUFF[100]				//SAVES THE RECEIVER FEEDBACK FOR TROUBLESHOOTING
NON_VOLATILE CHAR		cRECEIVERTUNER[50]			//FREQUENCY THE TUNER IS AT
NON_VOLATILE CHAR 	cRECEIVERINPUT[50]			//INPUT OF MAIN ZONE
NON_VOLATILE CHAR 	cRECEIVERINPUTZA[50]			//INPUT OF ZONE A
NON_VOLATILE CHAR 	cRECEIVERVOLUME[50]			//VOLUME OF MAIN ZONE
NON_VOLATILE CHAR 	cRECEIVERVOLUMEZA[50]		//VOLUME OF ZONE A
NON_VOLATILE INTEGER	nRECEIVERPOWERSTATUS			//POWER OF MAIN ZONE
NON_VOLATILE INTEGER	nRECEIVERPOWERSTATUSZA		//POWER OF ZONE A
NON_VOLATILE INTEGER	nRECEIVERMUTE					//MUTE STATUS OF MAIN ZONE
NON_VOLATILE INTEGER	nRECEIVERMUTEZA				//MUTE STATUS OF ZONE A
NON_VOLATILE DOUBLE	dRECEIVERVOLUME				//VOLUME OF MAIN ZONE
NON_VOLATILE DOUBLE	dRECEIVERVOLUMEZA				//VOLUME OF ZONE A
//SWITCHER VARIABLES
VOLATILE CHAR 			cSWBUFF[50]						//MATREX SWITCHER BUFFER
NON_VOLATILE INTEGER	iCRSWOI							//CONFRENCE ROOM SWITCHER OUTPUT
NON_VOLATILE INTEGER	iFRSWOI							//FRONT ROOM SWITCHER OUTPUT
//CONFRENCE TV VARIABLES
VOLATILE CHAR 			cCONFRENCETVBUFF[50]			//CONFRENCE TV FEEDBACK BUFFER
VOLATILE INTEGER 		nCTVPOWERONDEADTIME			//CONFRENCE TV HOLD FOR TV POWER ON
//IR VARIABLES
VOLATILE INTEGER 		nBICSAT							//SAT FEEDBACK VARIABLE
VOLATILE INTEGER 		nBICBLUERAY						//BLUERAY FEEDBACK VARIABLE
VOLATILE INTEGER 		nBICAVSWITCH					//COMPONET SWITCHER FEEDBACK VARIABLE
//FRONT TV VARIABLES
VOLATILE CHAR			cFRONTTVBUFF[50]				//FRONT TV FEEDBACK BUFFER
VOLATILE INTEGER		nFTVPOWERONDEADTIME			//FRONT TV HOLD FOR TV POWER ON
//VANTAGE VARIABLES
VOLATILE CHAR			cVANTAGEBUFF[1000]			//VANTAGE TROUBLESHOOTING VAREABLE
VOLATILE CHAR			cVANTAGEBUFFPART[100]
VOLATILE CHAR			cVANTAGELEVEL[50]				//USED FOR LEVEL VALUE DATA PARSEING
VOLATILE DOUBLE		iVANTAGELEVEL					//MATH OPPERATION TO PARSE DATA
NON_VOLATILE INTEGER	nLIGHTLEVELS[40][1]


VOLATILE CHAR			cTEMP[40]
VOLATILE INTEGER		iTEMP
VOLATILE CHAR			cTPBUFF[100]					//TP FEEDBACK
(***********************************************************)
(*               LATCHING DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_LATCHING
(***********************************************************)
(*       MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW           *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE
(***********************************************************)
(*        SUBROUTINE/FUNCTION DEFINITIONS GO BELOW         *)
(***********************************************************)
#include 'ARQ Defines v6_0_2.axi';
#include 'ARQ Main v6_0_2.axi';
#include 'ARQ TP Interface v6_0_2.axi';
#INCLUDE 'DEFINE_CALL.AXI'
(***********************************************************)
(*                STARTUP CODE GOES BELOW                  *)
(***********************************************************)
DEFINE_START	
IP_CLIENT_OPEN (dvVANTAGE.PORT,sIPVANTAGE,svPORT,IP_TCP)		//OPENS THE PORT TO ALLOW COMMUNICATION TO VANTAGE

CREATE_BUFFER dvAVRECEIVER232, cRECEIVERBUFF
CREATE_BUFFER dvTP_CONFRENCE_MAIN, cTPBUFF
CREATE_BUFFER dvVANTAGE, cVANTAGEBUFF

DEFINE_START																//THE SECOND PART OF DEFINE_START IS IGNORED WITHOUT THIS SECOND DEFINE
#INCLUDE 'ARQ INCLUDE.AXI';

(***********************************************************)
(*                THE EVENTS GO BELOW                      *)
(***********************************************************)
DEFINE_EVENT													//--------------------------MACRO AND SOURCE COMMANDS
BUTTON_EVENT [dvTP_FRONT_MAIN,0]							//MACRO AND VOLUME COMMANDS FOR FRONT ROOM
{
	PUSH: 
	{
		SWITCH (BUTTON.INPUT.CHANNEL)
		{
		CASE 11:		//DVR--------------------------------------------------------
			CALL'FRONT_TV_ON'
			CALL'FRONT_TV_INPUT1'
			CALL'FRNT_RECEIVER_DSS'
			CALL'FRNT_SW_01'
			IF (![dvIO,SYNCSAT])
				PULSE [dvSATIR,SATPower_On]
			
		CASE 12:		//DVD--------------------------------------------------------
			CALL'FRONT_TV_ON'
			CALL'FRONT_TV_INPUT2'
			CALL'FRNT_RECEIVER_DVD'
			CALL'FRNT_SW_02'
			IF (![dvIO,SYNCBLUERAY])
				PULSE [dvBLUERAYIR,BRAYPower]
				
		CASE 13:		//PS3--------------------------------------------------------
			CALL 'FRONT_TV_ON'
			
		CASE 14:		//REQUEST----------------------------------------------------
			CALL'FRNT_SW_04'
			CALL'FRONT_TV_OFF'
			
		CASE 15:		//RADIO------------------------------------------------------
			CALL'FRNT_RECEIVER_RADIO'
			
		CASE 24: 	//VOLUME UP--------------------------------------------------
			CALL 'FRNT_RECEIVER_VOLUME+'
		CASE 25:		//VOLUME DOWN------------------------------------------------
			CALL 'FRNT_RECEIVER_VOLUME-'
		CASE 26:		//MUTE-------------------------------------------------------
			CALL 'FRNT_RECEIVER_MUTE'
			
		CASE 28:		//OFF--------------------------------------------------------
			CALL'FRONT_TV_OFF'
			CALL'FRNT_RECEIVER_OFF'
			IF (nRECEIVERPOWERSTATUSZA=0)
			{
			CALL'SW_OFF'
			IF ([dvIO,SYNCSAT])
				PULSE [dvSATIR,SATPower_Off]
			IF ([dvIO,SYNCBLUERAY])
				PULSE [dvBLUERAYIR,BRAYPower]
			}
		}
	}
	HOLD[4,REPEAT]:
	{
		SWITCH (BUTTON.INPUT.CHANNEL)
		{
		CASE 24:
			CALL 'FRNT_RECEIVER_VOLUME+'
		CASE 25:
			CALL 'FRNT_RECEIVER_VOLUME-'
		}
	}
}
BUTTON_EVENT [dvTP_CONFRENCE_MAIN,0]					//MACRO AND VOLUME COMMANDS FOR CONFRENCE ROOM
{
	PUSH: 
	{
		SWITCH (BUTTON.INPUT.CHANNEL)
		{
		CASE 11:		//DVR--------------------------------------------------------
			CALL'CONFRENCE_TV_ON'
			CALL'CONFRENCE_TV_INPUT1'
			CALL'CR_RECEIVER_VCR'
			CALL'CR_SW_01'
			IF (![dvIO,SYNCSAT])
				PULSE [dvSATIR,SATPower_On]
			
		CASE 12:		//DVD--------------------------------------------------------
			CALL'CONFRENCE_TV_ON'
			CALL'CONFRENCE_TV_INPUT2'
			CALL'CR_RECEIVER_VCR'
			CALL'CR_SW_02'
			IF (![dvIO,SYNCBLUERAY])
				PULSE [dvBLUERAYIR,BRAYPower]
		CASE 13:		//PS3--------------------------------------------------------
			CALL'CONFRENCE_TV_ON'
			CALL'CONFRENCE_TV_INPUT7'
			CALL'CR_RECEIVER_VCR'
			CALL'CR_SW_03'
			CALL 'CONFRENCE_TV_ON'
			
		CASE 14:		//REQUEST----------------------------------------------------
			CALL'CR_RECEIVER_VCR'
			CALL'CR_SW_04'
			CALL'CONFRENCE_TV_OFF'
			
		CASE 15:		//RADIO------------------------------------------------------
			CALL'CR_RECEIVER_RADIO'
			
		CASE 24: 	//VOLUME UP--------------------------------------------------
			CALL 'CR_RECEIVER_VOLUME+'
		CASE 25:		//VOLUME DOWN------------------------------------------------
			CALL 'CR_RECEIVER_VOLUME-'
		CASE 26:		//MUTE-------------------------------------------------------
			CALL 'CR_RECEIVER_MUTE'
			
		CASE 28:		//OFF--------------------------------------------------------
			CALL'CONFRENCE_TV_OFF'
			CALL'CR_RECEIVER_OFF'
			IF (nRECEIVERPOWERSTATUS=0)
			{
			CALL 'SW_OFF'
			IF ([dvIO,SYNCSAT])
				PULSE [dvSATIR,SATPower_Off]
			IF ([dvIO,SYNCBLUERAY])
				PULSE [dvBLUERAYIR,BRAYPower]
			}
		}
	}
	HOLD[1,REPEAT]:
	{
		SWITCH (BUTTON.INPUT.CHANNEL)
		{
		CASE 24:
			CALL 'CR_RECEIVER_VOLUME+'
		CASE 25:
			CALL 'CR_RECEIVER_VOLUME-'
		}
	}
}

DEFINE_EVENT													//--------------------------DATA EVENTS ONLINE AND STRING STUFF AND SUCH
DATA_EVENT [0:dvVANTAGE.PORT:0]							//VANTAGE IP FUNCTIONS
{
	ONLINE:
	{
		SEND_STRING dvVANTAGE, "'ADDSTATUS ',cLOADVID,$0D,$0A"		//ADDS ALL THE LOADS WHOS STATUS ARE TO BE MONITORED
		SEND_STRING dvVANTAGE, "'LISTSTATUS',$0D,$0A"
		WAIT 10 
		{
			SEND_STRING dvVANTAGE, "'TASK 919 RELEASE',$0D,$0A"		//RUNS A TASK THAT UPDATES ALL THE LIGHT LEVELS
			SEND_STRING dvVANTAGE, "'TASK 919 RELEASE',$0D,$0A"		//TURNS THAT TASK OFF IDEALY THIS HAPPENS SO QUICKLY NO ONE SEES
		}
	}
}

DATA_EVENT [dvAVRECEIVER232]								//RS232 FUNCTIONS FOR THE RECEIVER
{
   ONLINE:                                                                                                                                                                //WHEN THE DEVISE COMES ONLINE
   {
   SEND_COMMAND dvAVRECEIVER232,"'SET BAUD 9600,N,8,1 485 DISABLE'"
	WAIT 10
	SEND_STRING dvAVRECEIVER232, "'@AST:1',$0D"		//SETS THE FEEDBACK VOLUME FROM THE RECEIVER TO MOST PERTANANT COMMANDS
	WAIT 10
	SEND_STRING dvAVRECEIVER232, "'@MSP:?',$0D"		//CHECK IF ZA IS ON IT DOSENT HAPPEN AUTOMATICLY
	WAIT 10
		{
		IF (nRECEIVERPOWERSTATUS=1)								//CHECKS THE TUNER STATUS IF THE RECEIVER IS ON DURING A REBOOT
			{
			CALL 'FRNT_RECEIVER_FREQ?'								//CHECK WHAT FREQUENCY THE TUNER IS 
			}
		ELSE IF (nRECEIVERPOWERSTATUS=0 AND nRECEIVERPOWERSTATUSZA=1)
			{
			CALL 'CR_RECEIVER_FREQ?'								//IF ONLY ZONE A IS ON CHECK USING THIS METHOD
			}
		}
	}
   STRING:
   {
//   cRECEIVERBUFF = DATA.TEXT												//THROWS THE RETURN STRINGS INTO VARIABLE TO KEEP A DEBUG EYE ON IT
		{
			IF (FIND_STRING (DATA.TEXT,"'@PWR:1'",1))					//POWER OFF RETURN STRING MAIN
				nRECEIVERPOWERSTATUS=0
			ELSE IF (FIND_STRING (DATA.TEXT,"'@PWR:2'",1))			//POWER ON RETURN STRING MAIN
				nRECEIVERPOWERSTATUS=1
			ELSE IF (FIND_STRING (DATA.TEXT,"'@MSP:1'",1))			//POWER OFF RETURN STRING ZA
				nRECEIVERPOWERSTATUSZA=0
			ELSE IF (FIND_STRING (DATA.TEXT,"'@MSP:2'",1))			//POWER ON RETURN STRING ZA
				nRECEIVERPOWERSTATUSZA=1
			ELSE IF (FIND_STRING (DATA.TEXT,"'@AMT:1'",1))			//MUTE OFF RETURN STRING MAIN
				nRECEIVERMUTE=0
			ELSE IF (FIND_STRING (DATA.TEXT,"'@AMT:2'",1))			//MUTE ON RETURN STRING MAIN
				nRECEIVERMUTE=1
			ELSE IF (FIND_STRING	(DATA.TEXT,"'@MSM:1'",1))			//MUTE OFF RETURN STRING ZA
				nRECEIVERMUTEZA=0
			ELSE IF (FIND_STRING	(DATA.TEXT,"'@MSM:2'",1))			//MUTE ON RETURN STRING ZA
				nRECEIVERMUTEZA=1
			ELSE IF (FIND_STRING (DATA.TEXT,"'VOL'",1))				//VOLUME RETURN STRINGS DATA HANDLING MAIN
			{
				cRECEIVERVOLUME=DATA.TEXT									//VOLUME DATA PARSING
				IF (FIND_STRING (cRECEIVERVOLUME,"'ZZ'",1))			//IF THE VOLUME IS ALL THE WAY DOWN THE RECEIVER RETURNS ZZ INSTEAD OF A NUMBER
				{
					dRECEIVERVOLUME=0
				}
				ELSE
				{
					(*SETS THE VOLUME FEEDBACK TO A VALUE OF 0 TO 255*)
					dRECEIVERVOLUME= ((ATOI(cRECEIVERVOLUME)+71)*255/89)
				}
				SEND_COMMAND dvTP_FRONT_MAIN, "'^TXT-52,1&2,','VOLUME',MID_STRING(cRECEIVERVOLUME,6,4)"			//VOLUME FEEDBACK MAIN
				SEND_LEVEL dvTP_FRONT_MAIN,52,dRECEIVERVOLUME																	//SENDS THE LEVEL INFO TO BUTTON 52 OF MAPPED TP
			}
			ELSE IF (FIND_STRING	(DATA.TEXT,"'MSV'",1))				//VOLUME RETURN STRINGS DATA HANDLING ZA
			{
				cRECEIVERVOLUMEZA=DATA.TEXT								//VOLUME DATA PARSING ZA
				(***SETS THE VOLUME FEEDBACK TO A VALUE OF 0 TO 255***)
				dRECEIVERVOLUMEZA= ((ATOI(cRECEIVERVOLUMEZA)+90)*255/90)
				SEND_COMMAND dvTP_CONFRENCE_MAIN, "'^TXT-52,1&2,','VOLUME',MID_STRING(cRECEIVERVOLUMEZA,6,4)"	//VOLUME FEEDBACK ZA
				SEND_LEVEL dvTP_CONFRENCE_MAIN,52,dRECEIVERVOLUMEZA															//SENDS THE LEVEL INFO TO BUTTON 52 OF MAPPED TP
			}
			ELSE IF (FIND_STRING(DATA.TEXT,"'@SRC:'",1))				//INPUT FUNCTIONS
			{
				IF (FIND_STRING (DATA.TEXT,"'@SRC:11'",1))			
					cRECEIVERINPUT='TV'
				ELSE IF (FIND_STRING (DATA.TEXT,"'@SRC:22'",1))
					cRECEIVERINPUT='DVD'
				ELSE IF (FIND_STRING (DATA.TEXT,"'@SRC:33'",1))
					cRECEIVERINPUT='VCR1'
				ELSE IF (FIND_STRING (DATA.TEXT,"'@SRC:55'",1))
					cRECEIVERINPUT='DSS'
				ELSE IF (FIND_STRING (DATA.TEXT,"'@SRC:99'",1))
					cRECEIVERINPUT='AUX1'
				ELSE IF (FIND_STRING (DATA.TEXT,"'@SRC:AA'",1))
					cRECEIVERINPUT='AUX2'
				ELSE IF (FIND_STRING (DATA.TEXT,"'@SRC:CC'",1))
					cRECEIVERINPUT='CD'
				ELSE IF (FIND_STRING (DATA.TEXT,"'@SRC:EE'",1))
					cRECEIVERINPUT='TAPE'
				ELSE IF (FIND_STRING (DATA.TEXT,"'F'",7))
					cRECEIVERINPUT='TUNER'
				ELSE IF (FIND_STRING (DATA.TEXT,"'G'",7))
					cRECEIVERINPUT='FM'
				ELSE IF (FIND_STRING (DATA.TEXT,"'H'",7))
					cRECEIVERINPUT='AM'
				ELSE IF (FIND_STRING (DATA.TEXT,"'J'",7))
					cRECEIVERINPUT='XM'
			}
			ELSE IF (FIND_STRING(DATA.TEXT,"'@MSC:'",1))				//INPUT FUNCTIONS ZA
			{
				IF (FIND_STRING (DATA.TEXT,"'11'",1))			
					cRECEIVERINPUTZA='TV'
				ELSE IF (FIND_STRING (DATA.TEXT,"'22'",1))
					cRECEIVERINPUTZA='DVD'
				ELSE IF (FIND_STRING (DATA.TEXT,"'33'",1))
					cRECEIVERINPUTZA='VCR1'
				ELSE IF (FIND_STRING (DATA.TEXT,"'55'",1))
					cRECEIVERINPUTZA='DSS'
				ELSE IF (FIND_STRING (DATA.TEXT,"'@99'",1))
					cRECEIVERINPUTZA='AUX1'
				ELSE IF (FIND_STRING (DATA.TEXT,"'AA'",1))
					cRECEIVERINPUTZA='AUX2'
				ELSE IF (FIND_STRING (DATA.TEXT,"'CC'",1))
					cRECEIVERINPUTZA='CD'
				ELSE IF (FIND_STRING (DATA.TEXT,"'EE'",1))
					cRECEIVERINPUTZA='TAPE'
				ELSE IF (FIND_STRING (DATA.TEXT,"'F'",7))
					cRECEIVERINPUTZA='TUNER'
				ELSE IF (FIND_STRING (DATA.TEXT,"'G'",7))
					cRECEIVERINPUTZA='FM'
				ELSE IF (FIND_STRING (DATA.TEXT,"'H'",7))
					cRECEIVERINPUTZA='AM'
				ELSE IF (FIND_STRING (DATA.TEXT,"'J'",7))
					cRECEIVERINPUTZA='XM'
			}
			(*  TUNER FUNCTIONS GO BELOW  *)
			ELSE IF (FIND_STRING(DATA.TEXT,"'@MTF:'",1) OR FIND_STRING(DATA.TEXT,"'@TFQ:'",1))
			{
				cRECEIVERTUNER=(RIGHT_STRING (DATA.TEXT,6))
				(*TUNER PARSED DISPLAY COMMANDS BELOW*)
				IF (ATOI(cRECEIVERTUNER)< 2000)
				{
					IF (ATOI(cRECEIVERTUNER)< 512)
						SEND_COMMAND arrTPRADIO, "'^TXT-50,1&2,','XM',$20,RIGHT_STRING (cRECEIVERTUNER,4),'CH'"
					ELSE
					{
						IF (LEFT_STRING(cRECEIVERTUNER,1)='0')
							SEND_COMMAND arrTPRADIO, "'^TXT-50,1&2,','AM',$20,RIGHT_STRING (cRECEIVERTUNER,4),'kHz'"
						ELSE
							SEND_COMMAND arrTPRADIO, "'^TXT-50,1&2,','AM',$20,RIGHT_STRING (cRECEIVERTUNER,5),'kHz'"
					}
				}
				ELSE
				{
					IF (LEFT_STRING(cRECEIVERTUNER,1)='0')
						SEND_COMMAND arrTPRADIO, "'^TXT-50,1&2,','FM',$20,MID_STRING (cRECEIVERTUNER,2,2),'.',RIGHT_STRING (cRECEIVERTUNER,3),'MHz'"
					ELSE
						SEND_COMMAND arrTPRADIO, "'^TXT-50,1&2,','FM',$20,MID_STRING (cRECEIVERTUNER,1,3),'.',RIGHT_STRING (cRECEIVERTUNER,3),'MHz'"
				}
			}
		}
   }
}
DATA_EVENT [dvAVSWITCH232]									//RS232 FUNCTIONS FOR THE SWITCHER
{
   ONLINE:                                                                                                                                                                //WHEN THE DEVISE COMES ONLINE
   {
   SEND_COMMAND dvAVSWITCH232,"'SET BAUD 19200,N,8,1 485 DISABLE'"
	SEND_STRING dvAVSWITCH232, "'p1',$0D"
	WAIT 10
	SEND_STRING dvAVSWITCH232, "'e1',$0D"
	}
	STRING:
	{
	cSWBUFF=DATA.TEXT
	}
}
DATA_EVENT [dvTVFRONT232]									//RS232 FUNCTIONS FOR THE FRONT TV
{
   ONLINE:                                                                                                                                                                //WHEN THE DEVISE COMES ONLINE
   {
   SEND_COMMAND dvTVFRONT232,"'SET BAUD 9600,N,8,1 485 DISABLE'"
	SEND_STRING dvTVFRONT232, "'RSPW1',$20,$20,$20,$0D"
	}
	STRING:
	{
	cFRONTTVBUFF=DATA.TEXT
	}
}
DATA_EVENT [dvTVCONFRENCE232]								//RS232 FUNCTIONS FOR THE CONFRINCE TV
{
   ONLINE:                                                                                                                                                                //WHEN THE DEVISE COMES ONLINE
   {
   SEND_COMMAND dvTVCONFRENCE232,"'SET BAUD 9600,N,8,1 485 DISABLE'"
	SEND_STRING dvTVCONFRENCE232, "'RSPW1',$20,$20,$20,$0D"
	}
	STRING:
	{
	cCONFRENCETVBUFF=DATA.TEXT
	}
}
DATA_EVENT [dvSATIR]											//IR FUNCTIONS FOR THE SAT RECEIVER
{
  ONLINE:														//WHEN THE IR PORT COMES ONLINE
  {
    SEND_COMMAND dvSATIR,"'SET IO LINK 1'"			//LINKS THE IR DEVICE TO A I/O CHANNEL
    SEND_COMMAND dvSATIR,"'SET MODE IR'"				//SET IT TO IR
    SEND_COMMAND dvSATIR,"'CARON'"						//TURNS THE CARRIOR ON FOR EMMITOR USE
    SEND_COMMAND dvSATIR,"'XCHM-2'"						//SETS XCHM MODE TO 0
  }
}
DATA_EVENT [dvBLUERAYIR]									//IR FUNCTIONS FOR THE BLUERAY
{
  ONLINE:														//WHEN THE IR PORT COMES ONLINE
  {
    SEND_COMMAND dvBLUERAYIR,"'SET IO LINK 1'"		//LINKS THE IR DEVICE TO A I/O CHANNEL
    SEND_COMMAND dvBLUERAYIR,"'SET MODE IR'"			//SET IT TO IR
    SEND_COMMAND dvBLUERAYIR,"'CARON'"					//TURNS THE CARRIOR ON FOR EMMITOR USE
    SEND_COMMAND dvBLUERAYIR,"'XCHM-2'"				//SETS XCHM MODE TO 0
  }
}
DATA_EVENT [dvTP_CONFRENCE_MAIN]							//TP ONLINE SEND PAGE FEEDBACK TO CONTROLLER
{
	ONLINE:
	{
		SEND_COMMAND dvTP_CONFRENCE_MAIN, "'TPAGEON'"
	}
	STRING:
	{
		IF (FIND_STRING (cTPBUFF,'PPF-LIGHTS',1))
		{
		CLEAR_BUFFER cTPBUFF
		}	
	}
}

DEFINE_EVENT													//--------------------------DEVICE SPECIFIC COMMANDS CHANNEL UP AND SUCH
LEVEL_EVENT  [arrTPLIGHTS_S,0]							//VANTAGE SYSTEM LEVEL EVENTS REMEMBER THE DOUBLE SLIDERS TO PREVENT INFINATE LOOPS
{
	STACK_VAR FLOAT LIGHTTEMP
	LIGHTTEMP = (LEVEL.VALUE/2.55)
	SEND_STRING dvVANTAGE, "'LOAD ',ITOA(LEVEL.INPUT.LEVEL),' ',ITOA(LIGHTTEMP),$0D,$0A"
}

BUTTON_EVENT [arrTPSAT,0]									//IR BUTTON EVENTS FOR THE SAT RECEIVER
{
	PUSH:
	{
		STACK_VAR INTEGER BIC
		BIC = BUTTON.INPUT.CHANNEL
		nBICSAT = BIC
		SET_PULSE_TIME (2)
		PULSE[dvSATIR,BIC]
	}
	HOLD[3,REPEAT]:
	{
		STACK_VAR INTEGER BIC
		BIC = BUTTON.INPUT.CHANNEL
		nBICSAT = BIC
		SET_PULSE_TIME (1)
		PULSE[dvSATIR,BIC]
	}
}
BUTTON_EVENT [arrTPBLUERAY,0]								//IR BUTTON EVENTS FOR THE BLUERAY
{
	PUSH:
	{
		STACK_VAR INTEGER BIC
		BIC = BUTTON.INPUT.CHANNEL
		nBICBLUERAY = BIC
		SET_PULSE_TIME (2)
		PULSE[dvBLUERAYIR,BIC]
	}
	HOLD[3,REPEAT]:
	{
		STACK_VAR INTEGER BIC
		BIC = BUTTON.INPUT.CHANNEL
		nBICBLUERAY = BIC
		SET_PULSE_TIME (1)
		PULSE[dvBLUERAYIR,BIC]
	}
}
BUTTON_EVENT [arrTPRADIO,0]								//RS232 FUNCTIONS FOR THE RADIO
{
	PUSH:
	{
		SWITCH (BUTTON.INPUT.CHANNEL)
		{
		CASE 164:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_FREQ+'
			ELSE
				CALL 'CR_RECEIVER_FREQ+'
		CASE 165:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_FREQ-'
			ELSE
				CALL 'CR_RECEIVER_FREQ-'
		CASE 168:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_PRESET+'
			ELSE
				CALL 'CR_RECEIVER_PRESET+'
		CASE 169:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_PRESET-'
			ELSE
				CALL 'CR_RECEIVER_PRESET-'
		CASE 171:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_FM'
			ELSE
				CALL 'CR_RECEIVER_FM'
		CASE 172:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_AM'
			ELSE
				CALL 'CR_RECEIVER_AM'
		CASE 173:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_XM'
			ELSE
				CALL 'CR_RECEIVER_XM'
		}
	}
	HOLD[3,REPEAT]:
	{
		SWITCH (BUTTON.INPUT.CHANNEL)
		{
		CASE 164:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_FREQ+'
			ELSE
				CALL 'CR_RECEIVER_FREQ+'
		CASE 165:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_FREQ-'
			ELSE
				CALL 'CR_RECEIVER_FREQ-'
		CASE 168:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_PRESET+'
			ELSE
				CALL 'CR_RECEIVER_PRESET+'
		CASE 169:
			IF (nRECEIVERPOWERSTATUS=1)
				CALL 'FRNT_RECEIVER_PRESET-'
			ELSE
				CALL 'CR_RECEIVER_PRESET-'
		}
	}
}
(***********************************************************)
(*            THE ACTUAL PROGRAM GOES BELOW                *)
(***********************************************************)
DEFINE_PROGRAM

[dvTP_CONFRENCE_MAIN,11]	= (nRECEIVERPOWERSTATUSZA=1 AND cRECEIVERINPUTZA = 'VCR1' AND iCRSWOI=1 AND [dvIO,SYNCSAT])
[dvTP_CONFRENCE_MAIN,12]	= (nRECEIVERPOWERSTATUSZA=1 AND cRECEIVERINPUTZA = 'VCR1' AND iCRSWOI=2)
[dvTP_CONFRENCE_MAIN,14]	= (nRECEIVERPOWERSTATUSZA=1 AND cRECEIVERINPUTZA = 'VCR1' AND iCRSWOI=4)
[dvTP_CONFRENCE_MAIN,28]	= (nRECEIVERPOWERSTATUSZA=0)
[dvTP_CONFRENCE_MAIN,20]	= (FIND_STRING (cTPBUFF,'PPN-LIGHTS',1))

//IR PULSE STATUS WHILE IR IS PULSEING THE STATUS IS ON
[arrTPBLUERAY,nBICBLUERAY]	=	[dvBLUERAYIR,nBICBLUERAY]
[arrTPSAT,nBICSAT]			=	[dvSATIR,nBICSAT]

WHILE (FIND_STRING(cVANTAGEBUFF,"$0D,$0A",1))								//WHILE THERE IS A CR AND LF IN THE BUFFER
{
	cVANTAGEBUFFPART = REMOVE_STRING (cVANTAGEBUFF,"$0D,$0A",1)			//PULL THE STRING PRECEDEING A CR AND LF OUT OF BUFFER
	
	IF (FIND_STRING(cVANTAGEBUFFPART,"'S:STATUS'",1))						//IF STATUS IS IN THE STRING RUN THE FOLLOWING
	{
		STACK_VAR INTEGER iVID														//CREATE VARIABLE
		iVID = ATOI (LEFT_STRING (cVANTAGEBUFFPART,14))						//WICH VID CHANGES STATE?
		cVANTAGELEVEL = RIGHT_STRING (cVANTAGEBUFFPART,8)					//PULLSE THE LEVEL OUT OF THE STRING
		nLIGHTLEVELS[iVID][1] = ATOI (LEFT_STRING (cVANTAGELEVEL,3))	//SAVE LEVELS TO A VID NUMBERED ROW OF THE nLIGHTLEVELS VARIABLE
		SEND_LEVEL arrTPLIGHTS,iVID,(nLIGHTLEVELS[iVID][1]*2.55)			//SENDS THE LEVEL SAVED TO THE TP ARRAY
	}
}

(***********************************************************)
(*                     END OF PROGRAM                      *)
(*        DO NOT PUT ANY CODE BELOW THIS COMMENT           *)
(***********************************************************)


Comments

  • Pretty nice looking code for a first time in 12-years shot!

    I pretty much stopped when you said "it's working" :)

    Just a quick thing, in the data event for the av receiver you've got several wait 10 commands in there. Those don't stack the way you have them written so you run the risk of flooding the device. Also, if you can implement a send queue, that's a good function to have in your library. There are several posts on command queue's.

    Again, congratulations on the "it's working" part.

    --John
  • ericmedleyericmedley Posts: 4,177
    ditto on congrats.

    I might add that although not necessary, those stacked waits might be a good place to try creating a timeline. If nothing else it'll give you an easy example of how to do it.

    My threshold of pain on using timelines is fairly low. I'll stack waits a lot sooner than make a timeline myself. But I use timelines all the time for lots of things even though there can be a lot of mental overhead with them because they offer a lot of on-the-fly flexibility.

    Another thing might be to go ahead and get rid of the button_event[dvtp,0] idea and go with a button array instead. The only reason is the button_event ... ,0] is going to fire on every button event even and the switch/case is going to run every time even though it's going to fire only every so often. No sense cpu-tick-wise to process stuff if you don't need to.

    and example of one of your events might be
    define_variable
    
    volatile integer n_my_buttons[]=
    {
    11, //dvr
    12, // dvd
    13, // ps3
    14, // request
    15, // radio
    24, // etc...
    25,
    26,
    28
    }
    
    define_event
    
    button_event[dvTP,n_my_buttons]
    {
    push:
      {
      local_var integer nbutton_index
      nbutton_index=(get_last(n_my_buttons)) // this will give you the index of the button pushed.
      // for example if they hit button 12 (dvd) nbutton_index will be 2 since it's the 2nd item in the    list.  so...
      switch(nbutton_index)
        {
        case 2: dvd
          {
          // do stuff for the dvd
         }
        }
      }
    }
    

    the nice thing about doing it this way is that it allows you to change the button numbers later if you want to without having to dig through a lot of code. You just change it above in the variable declaration and it all still works below.

    But, there's nothing wrong with your method either.
  • GarretGarret Posts: 27
    Thank you so very much! I will look into all your suggestions. The send que sounds like a wonderful tool and the different way of laying out button inputs sound great. Anything to make changes to a system later easier I'm interested in. Nothing wrecks my day faster then a "how the crap did I make this work?" moment.

    Again thank you for taking the time to help.
  • DHawthorneDHawthorne Posts: 4,584
    Garret wrote: »
    Nothing wrecks my day faster then a "how the crap did I make this work?" moment.

    I have to agree with that. Closely followed by, "but it worked when I tested it ...".
  • kbeattyAMXkbeattyAMX Posts: 358
    Great Job

    With all of the advances in 12 year, I'm amazed at how well you grasp the NetLinx Programming.

    One comment: Parsing from data.text in a string event can be problematic. The device you're controlling can possibly send 2 or more responses before parsing data.text. I would buffer it and parse the buffer while it has length or the end delimiter of the string coming from the device. In this way you won't miss any feedback from the device.
  • GarretGarret Posts: 27
    kbeattyAMX wrote: »
    Parsing from data.text in a string event can be problematic.

    I didn't know how to setup a buffer until i got to the vantage system which sent back commands too fast, forcing me to find a better way. Do you recommend always using a buffer instead of data.text for feedback parsing? I can see how in larger programs the processor could be dealing with many more IRQ's causing data.text to be lost frequently. Being prepared for those situations even if its not necessary at the moment is probably wise. Alright I have convinced myself. That leads to the next question do you typically handle the parsing of that buffer in mainline similar to what I did?

    Thank you for your knowledge,

    I'm always impressed by the forums here. This forum is a large amount of the reason I know anything about AMX, I would also like to thank not just the responders to my post but the responders to every post.
  • kbeattyAMXkbeattyAMX Posts: 358
    A buffer for me is a generic term. char variable[500] can be a buffer especially when you do variable = "variable,data.text". Then parse for the end delimiter until variable is empty. If variable has length or an end delimiter, parse it. You can use the CREATE_BUFFER command but I haven't used it in years.
  • Garret wrote: »
    I didn't know how to setup a buffer until i got to the vantage system which sent back commands too fast, forcing me to find a better way. Do you recommend always using a buffer instead of data.text for feedback parsing? I can see how in larger programs the processor could be dealing with many more IRQ's causing data.text to be lost frequently. Being prepared for those situations even if its not necessary at the moment is probably wise. Alright I have convinced myself. That leads to the next question do you typically handle the parsing of that buffer in mainline similar to what I did?

    Thank you for your knowledge,

    I'm always impressed by the forums here. This forum is a large amount of the reason I know anything about AMX, I would also like to thank not just the responders to my post but the responders to every post.

    I highly recommend you use a buffer. The data.text only shows you the data that causes that event. Sometimes a serial command can end up split across multiple data events. To correctly parse command, you have to look at the data from multiple separate events combined into a single buffer. So, you can create a buffer to hold the data from multiple events, or let create_buffer do this for you.
  • DHawthorneDHawthorne Posts: 4,584
    Garret wrote: »
    I didn't know how to setup a buffer until i got to the vantage system which sent back commands too fast, forcing me to find a better way. Do you recommend always using a buffer instead of data.text for feedback parsing?

    When dealing with an independent device, yes. You can never be sure how it may be talking to your system, and whether the master will properly interprets pauses (or lack thereof) as a distinct break in the comms, triggering the STRING event. For virtual device communications, a buffer is not necessary, since that is all internal to the master itself.
  • GarretGarret Posts: 27
    I'm hooked on the buffers, and using them for all my incoming strings now. How are people handling the feedback parsing? I'm using a lot of if and else if strings to sort the data out and saving my findings to variables. Power, input, volume, variables and such. Is this similar to what most people do or are there some more preferred methods that I'm unaware of?

    Thank you,
  • DHawthorneDHawthorne Posts: 4,584
    Garret wrote: »
    I'm hooked on the buffers, and using them for all my incoming strings now. How are people handling the feedback parsing? I'm using a lot of if and else if strings to sort the data out and saving my findings to variables. Power, input, volume, variables and such. Is this similar to what most people do or are there some more preferred methods that I'm unaware of?

    Thank you,

    Saving to variable, yes ... if's, not so much. For parsing, I'm partial to SELECT...ACTIVE or SWITCH...CASE, as appropriate. They are far more scalable, and result in something much easier to follow than 10 levels of nested if's.
  • kbeattyAMXkbeattyAMX Posts: 358
    Sometimes I take results from parsing and place them right into a Level or Channel so if the code is used in a module the results would be accessible globally. Example if you are looking for the status of a mute, I might do this:
    if (find_string(incomingResult,'MUTE 1',1))
    {
    [dvVortex,1] = find_string(incomingResult,'MUTE 1 1',1)
    }

    Now dvVortex has a status for the mute that can be seen to the local program and any master connect to this master. This is also great for using with RMS.
Sign In or Register to comment.