XAP 800 COMM and UI Module
staticattic
Posts: 200
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