Home AMX User Forum NetLinx Studio

XAP 800 COMM and UI Module

A few months ago I asked for help parsing data from 2 XAP 800's and 1 XAP TH2. AMXJeff was kind enough to provide a Function he had written to parse the data. Using his Function as a model, I thought I would take a crack at making a UI and COMM module for those same XAP's for practice. Thought I would post what I had so far, for feedback. Everything compiles ok, but I have not tried any of it out yet. For all I know, the XAP's might burst into flames as soon as a load this. I am hoping for feedback as far as what I should change, what possibly won't work, if I'm am working in the right direction, etc. I still need to finish the TH2 portion. I am working that right now. Here's what I have so far. Any feedback would be much appreciated. Thanks.

First the delarations in the main program:
DEFINE_DEVICE

dvMaster	= 	0:1:0		//Master NetLinx

// Desk Touchpanel
dvTP1		=	10001:1:0
dvTP1_XAP	=	10001:2:0
// Rack Touchpanel
dvTP2		=	10002:1:0
dvTP2_XAP	=	10002:2:0
// Podium Touchpanel
dvTP3		=	10003:1:0
dvTP3_XAP	=	10003:2:0


DEFINE_START

// User Interface Modules
DEFINE_MODULE 'XAP_Functions_UI' XAP_UI_1(vdvXAP,dvTP1_XAP,ClearOne_XAP800_BUTTONS,ClearOne_XAPTH2_BUTTONS)
DEFINE_MODULE 'XAP_Functions_UI' XAP_UI_2(vdvXAP,dvTP2_XAP,ClearOne_XAP800_BUTTONS,ClearOne_XAPTH2_BUTTONS)
DEFINE_MODULE 'XAP_Functions_UI' XAP_UI_3(vdvXAP,dvTP3_XAP,ClearOne_XAP800_BUTTONS,ClearOne_XAPTH2_BUTTONS)

// COMM Modules
DEFINE_MODULE 'XAP_Functions_COMM' XAP_COMM(vdvXAP, dvXAP)


The COMM Module. If I am correct, SEND_STRING's come from the COMM and SEND_COMMAND's come from the UI. I also have a FOR loop in here that I am not 100% sure about:
MODULE_NAME='XAP_Functions_COMM'(DEV vdvXAP, DEV dvXAP)
(***********************************************************)
(*  FILE CREATED ON: 01/06/2009  AT: 11:12:18              *)
(***********************************************************)
(***********************************************************)
(***********************************************************)
(*  FILE_LAST_MODIFIED_ON: 01/07/2009  AT: 10:17:16        *)
(***********************************************************)
(* System Type : NetLinx                                   *)
(***********************************************************)
(* REV HISTORY:                                            *)
(***********************************************************)
(*
    $History: $
*)
(***********************************************************)
(*	NOTES:                                             *)
(*  1. 	2 XAP 800's and 1 XAP TH2			   *)
(*  2. 	13 Mics total. Mics 1 - 10 are the floor mics.     *)
(*     	11 - 13 are the ceiling mics.                      *)
(*  3. 	The Touchpanel DOES NOT provide any funtionality   *)
(*     	for the XAP's other than Master volume controls	   *)
(*	and mics on or off.				   *)
(*  4.	Only 2 mic mute buttons. 1 for all floor mics and  *)
(*	and 1 for all ceiling mics. No level controls.     *)
(*	Mics are either on or off.			   *)
(*	                                                   *)
(*	                                                   *)
(*	                                                   *)
(*	                                                   *)
(*	                                                   *)
(*	                                                   *)
(***********************************************************)    
(***********************************************************)
(*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_DEVICE

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

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

STRUCTURE _XAP800		// Both XAPs		
{	
    CHAR 	bMUTE_M[8];
    CHAR 	bMUTE_P[8];
    FLOAT 	fGAIN_P[8];
}
(***********************************************************)
(*               VARIABLE DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_VARIABLE

VOLATILE FLOAT 		flGain
VOLATILE CHAR 		cXAP_BUFF[100]		//Use this buffer for all XAP comms
VOLATILE INTEGER 	nHook			//1 = On Hook, 0 =Off Hook
VOLATILE CHAR 		XAP800_1_ADDRESS[] 	=	'#50';
VOLATILE CHAR 		XAP800_2_ADDRESS[]	=	'#51';
VOLATILE CHAR 		XAP800_3_ADDRESS[]	=	'#60';
VOLATILE INTEGER	nFloor_Mic_Status

// XAPs
VOLATILE _XAP800 	uXAP800_1;
VOLATILE _XAP800 	uXAP800_2;
PERSISTENT FLOAT 	flLevel_Bargraph

// Telco
VOLATILE INTEGER	nTelcoButtons
VOLATILE INTEGER 	nCOUNTER
VOLATILE INTEGER 	ClearOne_XAP800_BUTTONS_INDEX
VOLATILE CHAR 		cPHONE_NUMBER[40] 	// STORES THE PHONE NUMBER TO BE DIALED (CHAR FROM 0..9, #, *)
VOLATILE CHAR 		cLAST_NUMBER[40] 	// STORES THE LAST NUMBER DIALED
VOLATILE INTEGER 	nSPEED_DIAL 		// STORES THE SPEED DIAL SLOT ENTERED BY USER
PERSISTENT CHAR 	cNUMBER_FOR_REDIAL[40]	// STORES THE LAST NUMBER DIALED
PERSISTENT CHAR 	cSPEED_DIAL_1[40]
PERSISTENT CHAR 	cSPEED_DIAL_2[40]
PERSISTENT CHAR 	cSPEED_DIAL_3[40]
(***********************************************************)
(*               LATCHING DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_LATCHING

(***********************************************************)
(*       MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW           *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE

(***********************************************************)
(*        SUBROUTINE/FUNCTION DEFINITIONS GO BELOW         *)
(***********************************************************)
(* EXAMPLE: DEFINE_FUNCTION <RETURN_TYPE> <NAME> (<PARAMETERS>) *)
(* EXAMPLE: DEFINE_CALL '<NAME>' (<PARAMETERS>) *)
DEFINE_FUNCTION XAPs_ParseResponse()
{
    LOCAL_VAR CHAR cMSG[50], cGroup[1], cTempChannel[2], cChannel
    LOCAL_VAR INTEGER nTELE_RINGING
    cMSG = REMOVE_STRING(cXAP_BUFF, "13,10",1)
    IF (LENGTH_STRING(cMSG) != 0)			//If anything is in string cMSG
    {
	SET_LENGTH_STRING(cMSG,LENGTH_STRING(cMSG) - 2)	//removes the CR and LF
	SELECT
	{
	    ACTIVE(FIND_STRING(cMSG, "XAP800_1_ADDRESS,' MUTE '",1)):		
	    {
		REMOVE_STRING (cMSG,"XAP800_1_ADDRESS,' MUTE '",1)		
		cTempChannel = REMOVE_STRING(cMSG,' ',1)		
		cChannel = ATOI(cTempChannel)		
		cGroup = GET_BUFFER_STRING(cMSG,2)
		SWITCH (cGroup)
		{
		    CASE 'M':	// Floor mics 1 - 8 are on this XAP. 
		    {
			uXAP800_1.bMUTE_M[cChannel] = cMsg = '1';
			IF (FIND_STRING(uXAP800_1.bMUTE_M,'0',1))
			{
			    
			}
			ELSE
			{
			    
			}
		    }
		    CASE 'P':
		    {
			cChannel = cTempChannel[1] - 'A' + 1;
			uXAP800_1.bMUTE_P[cChannel] = cMsg = '1';
		    }
		}
	    }
	    ACTIVE (FIND_STRING(cMsg, "XAP800_1_ADDRESS,' GAIN '",1)): 	//#50 GAIN A P xx A 
	    {
		REMOVE_STRING(cMsg,"XAP800_1_ADDRESS,' GAIN '",1);    	// cMSG = A P xx A
		IF (FIND_STRING(cMsg,'A',1))				// I don't care about Processor B. Processor B will always match A
		{
		    cTempChannel = REMOVE_STRING(cMsg,' ',1);		// cTempChannel = A
		    cChannel = ATOI(cTempChannel);			// cChannel = A
		    cGroup = GET_BUFFER_STRING(cMsg,2);			// cMSG = xx A cGroup = P
		    flGain = ATOF(cMsg);				// xx (any non-numeric characters are ignored)
		    SWITCH (cGroup)
		    {
			CASE 'P':
			{
			    cChannel = cTempChannel[1] - 'A' + 1;
			    uXAP800_1.fGAIN_P[cChannel] = flGain;
			    flLevel_Bargraph = ((100*(flGain + 65)) / 85)
			    SEND_STRING vdvXAP, "'VOLUME=',flLevel_Bargraph"
			}
		    }
		}
	    }
	    ACTIVE(FIND_STRING(cMSG, "XAP800_2_ADDRESS,' MUTE '",1)):
	    {
		REMOVE_STRING (cMSG,"XAP800_2_ADDRESS,' MUTE '",1)
		cTempChannel = REMOVE_STRING(cMSG,' ',1)
		cChannel = ATOI(cTempChannel)
		cGroup = GET_BUFFER_STRING(cMSG,2)
		SWITCH (cGroup)
		{
		    CASE 'M':	// Floor Mics 9 and 10 and Ceiling Mics 1 - 3 are on this XAP. 	
		    {
			uXAP800_2.bMUTE_M[cChannel + 8] = cMsg = '1';
			IF (FIND_STRING(uXAP800_2.bMUTE_M,'0',1))
			{
			    
			}
			ELSE
			{
			    
			}
		    }
		    CASE 'P':
		    {
			cChannel = cTempChannel[1] - 'A' + 1;
			uXAP800_1.bMUTE_P[cChannel] = cMsg = '1';
		    }
		}
	    }
	    ACTIVE (FIND_STRING(cMsg, "XAP800_2_ADDRESS,' GAIN '",1)):	// Currently no Gain controls for this XAP. 
	    {
		REMOVE_STRING(cMsg,"XAP800_2_ADDRESS,' GAIN '",1); 
		cTempChannel = REMOVE_STRING(cMsg,' ',1);
		cChannel = ATOI(cTempChannel);
		cGroup = GET_BUFFER_STRING(cMsg,2);
		flGain = ATOF(cMsg);
		SWITCH (cGroup)
		{
		    CASE 'P':
		    {
			cChannel = cTempChannel[1] - 'A' + 1;
			uXAP800_2.fGAIN_P[cChannel] = flGain;
		    }
		}
	    }
	    ACTIVE(FIND_STRING(cMSG, "XAP800_3_ADDRESS,' TE '",1)):
	    {
		REMOVE_STRING (cMSG,"XAP800_3_ADDRESS,' TE 1 '",1)
		nHook = ATOI(RIGHT_STRING(cMSG,1))
	    }		    
	    ACTIVE(FIND_STRING(cMSG, "XAP800_3_ADDRESS,' RING 1'",1)):
	    {
		REMOVE_STRING (cMSG,"XAP800_3_ADDRESS,' RING 1'",1)
		nTELE_RINGING = ATOI(RIGHT_STRING(cMSG,1))
		SEND_STRING vdvXAP,"'RINGING=',nTELE_RINGING"
		//IF (nTELE_RINGING = 1)
//		{
//		    //SEND_COMMAND TOUCHPANEL,"'^BMF-8,0,%CF 00'"
//		    //SEND_COMMAND TOUCHPANEL,"'^BMF-8,0,%J 5,%Tincoming call...'"
//		}
//		IF (nTELE_RINGING = 0)
//		{
//		    //SEND_COMMAND TOUCHPANEL,"'^BMF-8,0,%CF 53'"
//		    //SEND_COMMAND TOUCHPANEL,"'^BMF-8,0,%J 5,%T'"
//		}
	    }
	    //ACTIVE(FIND_STRING(cMSG, "XAP800_3_ADDRESS,' STOREDIAL '",1)): // Verify actual feedback from the XAP before making this section.
//	    {
//		REMOVE_STRING (cMSG,"XAP800_3_ADDRESS,' RING 1'",1)
//		nTELE_RINGING = ATOI(RIGHT_STRING(cMSG,1))
//		SEND_COMMAND TOUCHPANEL,"'@PPN-IP Phone Controls'"
//		IF (nTELE_RINGING = 1)
//		{
//		    SEND_COMMAND TOUCHPANEL,"'^BMF-8,0,%CF 00'"
//		    SEND_COMMAND TOUCHPANEL,"'^BMF-8,0,%J 5,%Tincoming call...'"
//		}
//		IF (nTELE_RINGING = 0)
//		{
//		    SEND_COMMAND TOUCHPANEL,"'^BMF-8,0,%CF 53'"
//		    SEND_COMMAND TOUCHPANEL,"'^BMF-8,0,%J 5,%T'"
//		}
//	    }
	}
    }
}
(***********************************************************)
(*                STARTUP CODE GOES BELOW                  *)
(***********************************************************)
DEFINE_START

CREATE_BUFFER dvXAP, cXAP_BUFF
(***********************************************************)
(*                THE EVENTS GO BELOW                      *)
(***********************************************************)
DEFINE_EVENT

DATA_EVENT[dvXAP]
{
    ONLINE:
    {
	SEND_COMMAND dvXAP,"'TSET BAUD 9600,N,8,1 485 DISABLE'"
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 1 M 1',13"	// #50 1 - 8 and #51 1 - 2 are the floor mics
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 2 M 1',13"
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 3 M 1',13"
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 3 M 1',13"
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 4 M 1',13"
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 5 M 1',13"
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 6 M 1',13"
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 7 M 1',13"
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE 8 M 1',13"
	SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 1 M 1',13"
	SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 2 M 1',13"
	SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 3 M 1',13"	// #51 3 - 5 are the ceiling mics
	SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 4 M 1',13"
	SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 5 M 1',13"
	SEND_STRING dvXAP,"XAP800_3_ADDRESS,' HOOKD 1 500',13"	// Sets the Hook Flash duration to 500ms
	SEND_STRING dvXAP,"XAP800_3_ADDRESS,' TE 1 0',13"	// Places the phone on Hook
	SEND_STRING dvXAP,"XAP800_1_ADDRESS,' GAIN A P',13"	// Queries the current volume 
    }
    STRING:
    {
	WHILE (FIND_STRING(cXAP_BUFF,"13,10",1))
	{
	    XAPs_ParseResponse()
	}
    }
}
DATA_EVENT[vdvXAP]
{
    COMMAND:
    {
	LOCAL_VAR CHAR cCommand[30]
	cCommand = REMOVE_STRING(DATA.TEXT, '=',1)
	SWITCH(cCommand)
	{
	    CASE 'Floor_Mics=':		// Toggle
	    {
		LOCAL_VAR INTEGER nXAP_1_Count
		FOR(nXAP_1_Count = 1; nXAP_1_Count<=8; nXAP_1_Count++)
		{
		    SEND_STRING dvXAP,"XAP800_1_ADDRESS,' MUTE ',ITOA(nXAP_1_Count),'1 M 2',13"	// #50 1 - 8 and #51 1 - 2 are the floor mics
		}
		SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 1 M 2',13"
		SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 2 M 2',13"
	    }
	    CASE 'Ceiling_Mics=':	// Toggle
	    {
		SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 3 M 2',13"	// #51 3 - 5 are the ceiling mics
		SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 4 M 2',13"
		SEND_STRING dvXAP,"XAP800_2_ADDRESS,' MUTE 5 M 2',13"
	    }
	    CASE 'Gain=':
	    {
		IF (FIND_STRING(DATA.TEXT,'UP',1))
		{
		    flGain=flGain + 1
		    IF(flGain<=20)
		    {
			SEND_STRING dvXAP,"'#50 GAIN A P ',FTOA(flGain),'A',13"
			SEND_STRING dvXAP,"'#50 GAIN B P ',FTOA(flGain),'A',13"
		    }
		    ELSE
		    {
			SEND_STRING dvXAP,"'#50 GAIN A P 20 A',13"
			SEND_STRING dvXAP,"'#50 GAIN B P 20 A',13"
		    }
		}
		IF (FIND_STRING(DATA.TEXT,'DOWN',1))
		{
		    flGain=flGain - 1
		    IF(flGain>=-65)
		    {
			SEND_STRING dvXAP,"'#50 GAIN A P ',FTOA(flGain),'A',13"
			SEND_STRING dvXAP,"'#50 GAIN B P ',FTOA(flGain),'A',13"
		    }
		    ELSE
		    {
			SEND_STRING dvXAP,"'#50 GAIN A P -65 A',13"
			SEND_STRING dvXAP,"'#50 GAIN B P -65 A',13"
		    }
		}
		IF (FIND_STRING(DATA.TEXT,'MUTE',1))
		{
		    SEND_STRING dvXAP,"'#50 MUTE A P 2',13"
		    SEND_STRING dvXAP,"'#50 MUTE B P 2',13"
		}
	    }
	}
    }
}
(***********************************************************)
(*            THE ACTUAL PROGRAM GOES BELOW                *)
(***********************************************************)
DEFINE_PROGRAM

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


And finally, the all important User Interface:
MODULE_NAME='XAP_Functions_UI'(DEV vdvXAP, DEV dvTP, INTEGER ClearOne_XAP800_BUTTONS[], INTEGER ClearOne_XAPTH2_BUTTONS[])
(***********************************************************)
(*  FILE CREATED ON: 12/12/2008  AT: 09:45:13              *) 
(***********************************************************)
(***********************************************************)
(***********************************************************)
(*  FILE_LAST_MODIFIED_ON: 01/07/2009  AT: 10:29:10        *)
(***********************************************************)
(* System Type : NetLinx                                   *)
(***********************************************************)
(* REV HISTORY:                                            *)
(***********************************************************)
(*
    $History: $
*)    
(***********************************************************)
(*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_DEVICE

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

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


(***********************************************************)
(*               VARIABLE DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_VARIABLE

VOLATILE INTEGER nXAP_Level 
VOLATILE INTEGER nPanelOffline = false 

(***********************************************************)
(*               LATCHING DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_LATCHING

(***********************************************************)
(*       MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW           *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE

(***********************************************************)
(*        SUBROUTINE/FUNCTION DEFINITIONS GO BELOW         *)
(***********************************************************)
(* EXAMPLE: DEFINE_FUNCTION <RETURN_TYPE> <NAME> (<PARAMETERS>) *)
(* EXAMPLE: DEFINE_CALL '<NAME>' (<PARAMETERS>) *)


(***********************************************************)
(*                STARTUP CODE GOES BELOW                  *)
(***********************************************************)
DEFINE_START

(***********************************************************)
(*                THE EVENTS GO BELOW                      *)
(***********************************************************)
DEFINE_EVENT

DATA_EVENT[dvTP]
{
    OFFLINE:  nPanelOffline = true
    ONLINE:
    {
	SEND_LEVEL dvTP, 1, nXAP_Level
    }
}
DATA_EVENT[vdvXAP]
{
    STRING:
    {
	SEND_STRING 0,"'UI rcvd from COMM:',DATA.TEXT"
	SWITCH(REMOVE_STRING(DATA.TEXT,'=',1))
	{
	    CASE 'VOLUME=':
	    {
		nXAP_Level = ATOI(DATA.TEXT)
		SEND_LEVEL dvTP, 1, nXAP_Level
	    }
	    CASE 'RINGING=':
	    {
		
	    }
	    CASE 'MIC_STATUS=':
	    {
		
	    }
	    CASE 'HOOK=':
	    {
		
	    }
	    CASE 'DIAL=':
	    {
		
	    }
	    CASE 'REDIAL=':
	    {
		
	    }
	}
    }
}
BUTTON_EVENT[dvTP,ClearOne_XAP800_BUTTONS]
{
    PUSH:
    {
	SWITCH (GET_LAST(ClearOne_XAP800_BUTTONS))
	{
	    CASE 1:			// Toggle Floor Mics On / Off 
	    {
		SEND_COMMAND vdvXAP, 'Floor_Mics=TOGGLE'
	    }
	    CASE 2:			// Toggle Ceiling Mics On / Off 
	    {
		SEND_COMMAND vdvXAP, 'Ceiling_Mics=TOGGLE'
	    }
	    CASE 3:			// Gain Up
	    {
		SEND_COMMAND vdvXAP, 'Gain=UP'
	    }
	    CASE 4:			// Gain Down
	    {
		SEND_COMMAND vdvXAP, 'Gain=DOWN'
		
	    }
	    CASE 5:			// Toggle Audio Mute
	    {
		SEND_COMMAND vdvXAP, 'Gain=MUTE'
	    }
	}
    }
    HOLD[3,REPEAT]:
    {
	SWITCH (GET_LAST(ClearOne_XAP800_BUTTONS))
	{
	    CASE 3:			// Gain Up
	    {
		SEND_COMMAND vdvXAP, 'Gain=UP'
	    }
	    CASE 4:			// Gain Down
	    {
		SEND_COMMAND vdvXAP, 'Gain=DOWN'
	    }
	}
    }
}
(***********************************************************)
(*            THE ACTUAL PROGRAM GOES BELOW                *)
(***********************************************************)
DEFINE_PROGRAM

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

Comments

  • One thing I have already noticed, rather than 3 UI's for the XAP TP's, should I combine them? How would that work if one TP was controlling the volume while at the same time, another TP was muting the mics? Would the two have to fight for control? Should I create a command buffer that will rack and stack the incoming commands and release them one at a time?
  • yuriyuri Posts: 861
    One thing I have already noticed, rather than 3 UI's for the XAP TP's, should I combine them? How would that work if one TP was controlling the volume while at the same time, another TP was muting the mics? Would the two have to fight for control? Should I create a command buffer that will rack and stack the incoming commands and release them one at a time?

    the protocol probably has a section that explains the minimum time that should be between commands. you should probably queue them :)
Sign In or Register to comment.