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:
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:
And finally, the all important User Interface:
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 *)
(***********************************************************)
0
Comments
the protocol probably has a section that explains the minimum time that should be between commands. you should probably queue them