Home AMX User Forum NetLinx Studio
Options

STACK_VAR vs LOCAL_VAR

Still trying to wrap my head around the difference. Could someone explain in further detail than what's listed in the help, when one would be preferred over the other?

Comments

  • Options
    ericmedleyericmedley Posts: 4,177
    Here's the basic concept.

    A Stack and Local variable is a variable name that only applies within the brackets they exist. the nice thing about them is they can be resued all over the place since you can think of them as being Function_X:myStackVar and FunctionY:MyStackVar. you can have multiple instances of MyStackVar all over your code but they stay descrete to each set of braces they live.

    So, if you have something like this:
    define_device
    TP1=10091:01:0
    TP2=10092:01:0
    TP3=10003:01:0
    
    define_variable
    volatile dev MyTPs[]={
    TP1
    ,TP2
    ,TP3
      }
    
    define_event
    
    button_event[MyTPs,1]{  // double beep my panel
      push:{
        stack_var integer tp_id;
        tp_id=get_last(MyTPs);
        send_Command MyTPs[tp_id],'adbeep'
        }// push
      }//button_evenet
    
    button_event[MyTPs,2]{  // single beep my panel
      push:{
        stack_var integer tp_id;
        tp_id=get_last(MyTPs);
        send_Command MyTPs[tp_id],'abeep'
        }// push
      }//button_evenet
    

    In this example I've used the variable name tp_id twice. but they will never stomp on each other since they only exist within the braces of the push event. If I hit TP id 1's button 1 and TP_ID2's button 2 - the stack vars tp_id will be differnt in the two different button events.

    The reason this is handy is it allows me to do quick copy/pastes (whicd I did in this example to get my second button event) without haveing to change a bunch of code.

    Now - having set this table - here's the differnec between a Stack Variable and a Local Variable.

    a stack_var resets to zero every time you leave the set of braces they live in. A local_var retains its value throughout runtime. So, if you find yourself needing to hang on to the value of the variable for later use, then you use a local_var. If you don't care if it goes away and don't need it again until the next time you hit the braces, then use a stack_var.

    And examle of this is if you put a wait in the button_event that requires the value you grabbed.

    example
    button_event[MyTPs,1]{  // double beep my panel
      push:{
        stack_var integer tp_id;
        tp_id=get_last(MyTPs);
        send_Command MyTPs[tp_id],'adbeep'
        wait 50{
           send_Command MyTPs[tp_id],'adbeep' // send another double-beep after 5 seconds
          }
        }// push
      }//button_evenet
    
    ^^ This won't work because the value of tp_id goes back to zero by the time the 5 seconds pases. so you'd basicall be saying "Send a double-beep command to the zero-th TP" doesn't work.
    button_event[MyTPs,1]{  // double beep my panel
      push:{
        local_var integer tp_id;
        tp_id=get_last(MyTPs);
        send_Command MyTPs[tp_id],'adbeep'
        wait 50{
           send_Command MyTPs[tp_id],'adbeep' // send another double-beep after 5 seconds
          }
        }// push
      }//button_evenet
    
    ^^ This WILL work since the local_var will have the value still after 5 seconds. local_vars hng on to their values after you leave the braces.

    Make sense?
    e
  • Options
    You can debug a Local in studio, but not a Stack. However, to Eric's point, it if is a Local that you use all over, it is virtually impossible to know which one you are watching. It may suggest you give it a unique name for testing.
  • Options
    a_riot42a_riot42 Posts: 1,624
    ericmedley wrote: »
    button_event[MyTPs,1]{  // double beep my panel
      push:{
        stack_var integer tp_id;
        tp_id=get_last(MyTPs);
        send_Command MyTPs[tp_id],'adbeep'
        wait 50{
           send_Command MyTPs[tp_id],'adbeep' // send another double-beep after 5 seconds
          }
        }// push
      }//button_evenet
    
    ^^ This won't work because the value of tp_id goes back to zero by the time the 5 seconds pases. so you'd basicall be saying "Send a double-beep command to the zero-th TP" doesn't work.
    button_event[MyTPs,1]{  // double beep my panel
      push:{
        local_var integer tp_id;
        tp_id=get_last(MyTPs);
        send_Command MyTPs[tp_id],'adbeep'
        wait 50{
           send_Command MyTPs[tp_id],'adbeep' // send another double-beep after 5 seconds
          }
        }// push
      }//button_evenet
    

    So if two different touch panels hit button 1 within five seconds, which touch panel will get the second beep, the first or the second?
    Paul
  • Options
    ericmedleyericmedley Posts: 4,177
    Chris,
    Isn't it th case that you CAN see a stack_var value if you put a stop/breakpoint there and pause runtime in debug?
  • Options
    Hi Guys,

    To make it easy for our guys to program, I tell them that
    stack_var are variables that get created and destroyed upon event starting and finishing.
    local_var are variables that get created upon event starting and are retained for that event in the future.

    In general I don't use local_vars much at all.

    Regards
    Craig
  • Options
    ericmedleyericmedley Posts: 4,177
    a_riot42 wrote: »
    So if two different touch panels hit button 1 within five seconds, which touch panel will get the second beep, the first or the second?
    Paul

    Paul,
    In the case you describe it will equal the s cond hit. In that regard this is not a good example. The example is sufficient to explain the way it works I thimk. But not a very good use in practice.
  • Options
    ericmedleyericmedley Posts: 4,177
    cmatkin wrote: »
    Hi Guys,

    To make it easy for our guys to program, I tell them that
    stack_var are variables that get created and destroyed upon event starting and finishing.
    local_var are variables that get created upon event starting and are retained for that event in the future.

    In general I don't use local_vars much at all.

    Regards
    Craig


    Agreed,
    I rarely use local_var. and stack_vars are always "throw away" stuff.
  • Options
    a_riot42a_riot42 Posts: 1,624
    ericmedley wrote: »
    Paul,
    In the case you describe it will equal the s cond hit. In that regard this is not a good example. The example is sufficient to explain the way it works I thimk. But not a very good use in practice.

    Yes that was I thought. Doing feedback to panels using waits is tricky because a stack_var only exists for a short period of time, and a local_var's value can change before the wait occurs giving erroneous behavior.
    Paul
  • Options
    ericmedleyericmedley Posts: 4,177
    a_riot42 wrote: »
    Yes that was I thought. Doing feedback to panels using waits is tricky because a stack_var only exists for a short period of time, and a local_var's value can change before the wait occurs giving erroneous behavior.
    Paul

    Yep, like I said, on many levels it's not a good example of a real-world use. Just a silly one to try and help illustrate how it works.
  • Options
    travistravis Posts: 180
    put a local var in a function for a global but not really global variable

    define_function integer fnGfjadj(INTEGER _ddd) {
    local_var integer notGlobal

    notGlobal = notGlobal + _ddd

    return notGlobal
    }


    x = fnGfjadj(1)



    why? i don't know
  • Options
    truetrue Posts: 307
    STACK_VAR is on the stack. This variable is dynamically allocated at runtime.
    LOCAL_VAR is in the data segment. This variable is statically allocated once at compile time.

    For most architectures, using a variable on the stack can be faster than using one in the data segment, making STACK_VAR faster. NetLinx isn't an interrupt-based system and I'm not sure how it handles optimization and variable stores/loads, but some informal tests validate this claim. Not like it matters, most of my systems have ~5% cpu usage, but "efficiency" was muttered around here for a while. :)

    The type of variable will also matter if you are writing recursive functions.
  • Options
    true wrote: »
    STACK_VAR is on the stack. This variable is dynamically allocated at runtime.
    LOCAL_VAR is in the data segment. This variable is statically allocated once at compile time.

    For most architectures, using a variable on the stack can be faster than using one in the data segment, making STACK_VAR faster. NetLinx isn't an interrupt-based system and I'm not sure how it handles optimization and variable stores/loads, but some informal tests validate this claim. Not like it matters, most of my systems have ~5% cpu usage, but "efficiency" was muttered around here for a while. :)

    The type of variable will also matter if you are writing recursive functions.

    Interesting perspective. I had a better understanding of usage for Stack/Local from the replies above, but I am wondering if this may be causing performance issues on my NI-700. I am using a TON of loops and functions for certain button presses and my processor isn't working correctly.

    For example, I have one button that looks like this:
    BUTTON_EVENT[dvTP_Mtg, 5] //Reserve Quick Meeting
    {
        PUSH:
        {
    	STACK_VAR CHAR CURRENT_DATE[10]
    	STACK_VAR CHAR cSTART_TIME[12]
    	STACK_VAR CHAR cEND_TIME[12]
    	STACK_VAR CHAR TITLE[20]
    	STACK_VAR INTEGER nNUM_MTGS
    	STACK_VAR INTEGER nINDEX 
    	STACK_VAR INTEGER nINDEX_2 
    	STACK_VAR INTEGER ACCESS
    
    	CURRENT_DATE = DATE
    	TITLE = "'Quick Meeting'"
    	nINDEX = fnPROCESS_TIME(nCURRENT_HOUR, nCURRENT_MIN)
    	nNUM_MTGS = (nQUICK_DUR/15)
    	nINDEX_2 = (nINDEX + nNUM_MTGS)
    	
    	cSTART_TIME = fnPROCESS_INDEX(nINDEX)
    	cEND_TIME = fnPROCESS_INDEX(nINDEX_2)
    	
    	ACCESS = fnPROCESS_REQUEST(nINDEX, nNUM_MTGS)
    	
    	IF(ACCESS == 1)
    	{
    	    IF(nINDEX_2 <= 40)
    	    {
    		fnADD_QUERY(sREAD_MTG_LB, CURRENT_DATE, cSTART_TIME, cEND_TIME, TITLE, cHOST_NAME)
    	    }
    	    ELSE IF(nINDEX_2 > 40)
    	    {
    		cEND_TIME = "'5:00 PM'"
    		fnADD_QUERY(sREAD_MTG_LB, CURRENT_DATE, cSTART_TIME, cEND_TIME, TITLE, cHOST_NAME)
    	    }
    	    
    	    SEND_COMMAND dvTP, "'@PPN-Server_Comm'"
    	    TIMELINE_CREATE(TL_FEEDBACK4,nTIMER4,1,TIMELINE_ABSOLUTE,TIMELINE_REPEAT) //Start Countdown 5 sec
    	    WAIT 50
    	    {
    		TIMELINE_KILL(TL_FEEDBACK4)
    		SEND_LEVEL dvTP, 3, 0
    		SEND_COMMAND dvTP, "'@PPX-Quick Meeting'"
    	    }
    	}
    	ELSE IF (ACCESS == 0)
    	{
    	    SEND_COMMAND dvTP, "'@PPN-Error'"
    	}
        }
    }
    

    The variables do not get initiated on the first button press. If I press it two more times, it then initiates the variables.
  • Options
    viningvining Posts: 4,368
    Put in some send_string 0's with vars in your string in various point of this button push so you can see what's going on. Your push event should be running on every button push unless the channel isn't releasing so possibly your function calls in this push aren't working until sever pushes. It's hard to say since we can't see those functions.

    Also when using functions, if they have waits in them and you pass in a stack var it won't work and you won't get a compiler error like you do trying to use a stack inside a wait when you do that inside the braces where the stack in defined.
  • Options
    JasonSJasonS Posts: 229
    vining wrote: »
    Also when using functions, if they have waits in them and you pass in a stack var it won't work and you won't get a compiler error like you do trying to use a stack inside a wait when you do that inside the braces where the stack in defined.

    You can define a LOCAL_VAR inside the function and copy the value of the parameter to get around this. However, subsequent calls to the function before the wait expires will overwrite the value. And if you don't name the wait, cancel it, and restart it, the "SEND_STRING 0" will execute once with the latest value at the wait time from the first call.

    To me this is a good reason to use a timeline instead, if you can overlook the fact that timelines are finicky with variables for the timeline ID.
    DEFINE FUNCTION Do_Something_Later(INTEGER var)
    {
        LOCAL_VAR INTEGER var2
    
        var 2 = var
        wait 10
        {
            SEND_STRING 0, "'var2 = ', ITOA(var2)"
        }
    }
    
    DEFINE_EVENT
    
        BUTTON_EVENT [10001:1:0, 0]
        {
            PUSH:
            {
                 Do_Something_Later(Button.Input.Channel)
            }
        }
    
    
  • Options
    JasonSJasonS Posts: 229
    true wrote: »
    The type of variable will also matter if you are writing recursive functions.

    I have found recursion to be somewhat problematic with NetLinx. Nobody in Tech support could give me a definitive answer on how to figure out the depth limitation. Some said it was a fixed number that they didn't know, others said it was based on memory. An alphabetical Bubble sort on 400 items would reach the limit, pre sorting by first letter then bubble sorting each letter group usually worked.

    But back to STACK_VARs...

    I use STACK_VARs as much as possible. 99.9% of the time all my function variables STACK_VARs (every so often you need a LOCAL_VAR). I have seen way to much NetLinx code with tons of global variables that cause very weird interactions that are hard to track down.
  • Options
    ericmedleyericmedley Posts: 4,177
    I'm not going to be hypocritical and say I've never done the quickie wait - but it really is a good idea to avoid using waits in functiins even with local_vars (or globals for that matter) as Netlinx is still essentially a single threaded runtime. There is no way to guaranty that the variable won't get changed if the function or routine gets called again within the time of the wait. I have been burned by this with a person who just seemed to be able to do double-taps due to fingernails or dry skin or whatever.

    Building a queue to handle waits can be a bit tiresome but if you've done it once, the work is over and you can ensure you don't stomp on yourself.
  • Options
    DHawthorneDHawthorne Posts: 4,584
    My rule-of-thumb is to use STACK_VAR as the default, and only use a local when I need it. When using a LOCAL_VAR, as it's been mentioned, you have to be careful, so I only put them in functions or subroutines that I know exactly when that routine is going to be called and under what conditions, so I know for sure it has the value I expect it to. I may, for troubleshooting purpose, convert a STACK to LOCAL just so I can watch it, but always put it back when done. Putting a LOCAL_VAR in a WAIT is asking for trouble ... not that I haven't done it from time to time, but only with very short waits, and again, when I know exactly what else has access to the WAIT that might change it.
  • Options
    viningvining Posts: 4,368
    DHawthorne wrote: »
    I may, for troubleshooting purpose, convert a STACK to LOCAL just so I can watch it, but always put it back when done.
    I often do that too but I wonder how many never got changed back to a stack? Also when doing this I usually initialize it to zero right after it's defined so it acts just like a stack but doesn't go poof after the closing brace so I can watch in debug.

    You can watch stack vars in debug too if you put in break points and step through your code but I haven't done that in years, it's too flaky, instead I tend to use more send_string 0's than one would think necessary and then as I start to debug my code I usually add more because I didn't have enough or have them in the right places.
  • Options
    JasonSJasonS Posts: 229
    I use "send_String 0" for my debugging. I find it easier to figure out what is going on with a record of the values I am interested in over time. When I am done debugging I just comment those lines out incase I need to use them later. I much prefer a Telnet client to NetLinx Studio notifications.
  • Options
    I created a TDebug_MsgTypeXXX "Class", that I can turn ON & OFF certain DEBUG_MSG_TYPE_XXX Channels via a virtual Device in "Control a Device"; which in turn set PERSISTENT Char Vars, in an array, ON & OFF - so I do not have to keep turning them off when I am debugging a system each time I recompile.
    I also added the ability to turn all Debug Channels off via one Channel. With this I can control any Type of Debug Info I need without recompiling. With all of the systems I have done I have not noticed any hit on functionality or speed. If the Debug Channel is ON the messages are sent via "Send_String 0", if it is OFF the function just returns to the calling function...
  • Options
    viningvining Posts: 4,368
    I just use a debug function in each module and put the function call everywhere in my code during the development. I pass an integer to the function for a verbose level so I can control how much I see in diagnostics. I'll put the rx buffer strings at level 5 and then decrease the level at the various stages through out the code.

    Each function call also passes the line in the code where it exists so it easy to find that section. Since some debug strings exceed the length available in a send_string 0 my function also breaks the string it gets passed into multiple lines if necessary and my send_string 0 indicates the line number so again it's easy to tell the lines in diag that are part of the same debug string. When I have my debug calls in switch cases or select active I usually use the default or active(1) if they have no other purpose to print out values that I didn't create a case or active handler for so as I debug I'll find things the device sends that I did plan on and then add them in even if action is required or desired.

    Beginning of function so I can check values coming in:
    DEFINE_FUNCTION fnJSON_Process_FB(_FB iFB)
    
         {
         STACK_VAR _FB sMyFB;
         STACK_VAR INTEGER i;
         STACK_VAR INTEGER nLVL;
         STACK_VAR INTEGER nFBS;
         STACK_VAR INTEGER nIndx;
         STACK_VAR INTEGER nPlugin;
         STACK_VAR INTEGER nRecognized;
         STACK_VAR INTEGER nSearchPerformed;
         
         sMyFB = iFB;
         
         nLVL = sSBS.sBrowseState.nLevel;
         fnJSON_DeBug("'Process_FB, **, START-->'",1);
         fnJSON_DeBug("'Process_FB, **, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], TAGCNT-[',itoa(sMyFB.nTagCnt),'], ORIGINDX-[',itoa(sMyFB.nOrigIndx),'], LVL-[',itoa(nLVL),'] :DEBUG<',ITOA(__LINE__),'>'",1);
    
    Through out the function at vatious stages:
    	 SWITCH(sMyFB.cFB_Tag[i])
    			      {
    			      CASE 'album'		:{sLevelList[nLVL].cAlbum[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'artist'		:{sLevelList[nLVL].cArtist[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'cmd'		:{sLevelList[nLVL].cListCmd[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'command'		:{}//pandora button command arrays
    			      CASE 'genre'		:{sLevelList[nLVL].cGenre[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'playlist'		:{sLevelList[nLVL].cPlaylist[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'title'		:{sLevelList[nLVL].cTitle[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'id'			:
    				   {//spotify has spaces with %20 for some id's, these are needed in string sent back but the DecodeURL func removes them so we add an escape %--
    				    //and modified the DecodeURL func to recognize it
    				   sLevelList[nLVL].cItem_ID[sMyFB.nFB_Indx[i]] = fnStrReplace(sMyFB.cFB_VAL[i],'%20','%--%20');
    				   }//sLevelList[nLVL].nHasItems[sMyFB.nFB_Indx[i]] = 1;
    			      CASE 'icon'		:{sLevelList[nLVL].cIconURL[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'name'		:{sLevelList[nLVL].cName[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'type'		:{sLevelList[nLVL].cType[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'weight'		:{sLevelList[nLVL].cWeight[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'url'		:{sLevelList[nLVL].cURL[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'isaudio'		:{sLevelList[nLVL].nIsAudio[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'hasitems'		:{sLevelList[nLVL].nHasItems[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'duration'		:{sLevelList[nLVL].nDuration[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'tracknum'		:{sLevelList[nLVL].nTrackNum[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'remote'		:{sLevelList[nLVL].nRemote[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'image'		:{sLevelList[nLVL].cImageURL[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}//found in radios, pandora
    			      CASE 'playlist index' 	:{sLevelList[nLVL].nIndxNum[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}//playlist tracks zap song
    			      DEFAULT:
    				   {
    				   nRecognized = 0;
    				   fnJSON_DeBug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX-[',itoa(sMyFB.nFB_Indx[i]),'] :DEBUG<',ITOA(__LINE__),'>'",1);
    				   }
    			      }
    			 if(nRecognized)
    			      {
    			      fnJSON_DeBug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX-[',itoa(sMyFB.nFB_Indx[i]),'] :DEBUG<',ITOA(__LINE__),'>'",1);
    			      nRecognized = 0;
    			      }
    			 }
    ........
    
    The print oun in diagnostics.
    Line      4 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], TX to JSON.....,PARAM_STR-[ ["00:04:20:23:a7:6d",["status",0,8,"tags:aBdgKlNotuxyY"]] ] :DEBUG<3368>
    Line      5 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], ParseBody, Result, VAL-[ {"player_name":"VAV Green","player_connected":1,"player_ip":"127.0.0.1:41658","power":1,"signalstrength":0,"mode":"stop","mixer volu
    Line      6 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-2], me":100,"playlist repeat":0,"playlist shuffle":0,"playlist mode":"off","seq_no":0,"playlist_cur_index":0,"playlist_timestamp":1425729297.63372,"playlist_trac
    Line      7 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-3], ks":1,"remoteMeta":{"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_url":"imageproxy/spotify:image:462342903cda2a
    Line      8 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-4], 69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"spotify:track:5eWgDlp3k6Tb5RD8690s6I","remote"
    Line      9 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-5], :1,"year":"0"},"playlist_loop":[{"playlist index":0,"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_url":"imagepr
    Line     10 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-6], oxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"spotify:track:
    Line     11 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-7], 5eWgDlp3k6Tb5RD8690s6I","remote":1,"year":"0"}]} ] :DEBUG<932>
    Line     12 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], ParseBody, Param, TAG-[ params ], VAL-[ ["00:04:20:23:a7:6d",["status","0",8,"tags:aBdgKlNotuxyY"]] ] :DEBUG<950>
    Line     13 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Param, TAG-[ params ], VAL[ ["00:04:20:23:a7:6d",["status","0",8,"tags:aBdgKlNotuxyY"]] ] :DEBUG<1379>
    Line     14 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Param, $$, TAG-[ params ], VAL1-[ status ], VAL2-[ 0 ], VAL3-[ 8 ], CNT-[4] :DEBUG<1579>
    Line     15 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, Parent-[ status ], VAL-[ {"player_name":"VAV Green","player_connected":1,"player_ip":"127.0.0.1:41658","power":1,"signalstrength":0,"mode":"stop",
    Line     16 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-2], "mixer volume":100,"playlist repeat":0,"playlist shuffle":0,"playlist mode":"off","seq_no":0,"playlist_cur_index":0,"playlist_timestamp":1425729297.63372,"pl
    Line     17 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-3], aylist_tracks":1,"remoteMeta":{"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_url":"imageproxy/spotify:image:462
    Line     18 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-4], 342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"spotify:track:5eWgDlp3k6Tb5RD8690s6
    Line     19 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-5], I","remote":1,"year":"0"},"playlist_loop":[{"playlist index":0,"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_ur
    Line     20 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-6], l":"imageproxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"spo
    Line     21 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-7], tify:track:5eWgDlp3k6Tb5RD8690s6I","remote":1,"year":"0"}]} ], INDX-[1], OBJ CNT-[1], ORIG INDX-[1] :DEBUG<1243>
    Line     22 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ player_name:VAV Green ] ] :DEBUG<1356>
    Line     23 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ player_connected:1 ] ] :DEBUG<1356>
    Line     24 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ player_ip:127.0.0.1:41658 ] ] :DEBUG<1356>
    Line     25 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ power:1 ] ] :DEBUG<1356>
    Line     26 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ signalstrength:0 ] ] :DEBUG<1356>
    Line     27 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ mode:stop ] ] :DEBUG<1356>
    Line     28 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ mixer volume:100 ] ] :DEBUG<1356>
    Line     29 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist repeat:0 ] ] :DEBUG<1356>
    Line     30 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist shuffle:0 ] ] :DEBUG<1356>
    Line     31 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist mode:off ] ] :DEBUG<1356>
    Line     32 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ seq_no:0 ] ] :DEBUG<1356>
    Line     33 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist_cur_index:0 ] ] :DEBUG<1356>
    Line     34 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist_timestamp:1425729297.63372 ] ] :DEBUG<1356>
    Line     35 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist_tracks:1 ] ] :DEBUG<1356>
    Line     36 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, Object, TOPTAG-[ status ], TAG-[ remoteMeta ], VAL-[ {"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_
    Line     37 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-2], url":"imageproxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"s
    Line     38 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-3], potify:track:5eWgDlp3k6Tb5RD8690s6I","remote":1,"year":"0"} ], SUBS-[0 ] :DEBUG<1309>
    Line     39 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, Array, TOPTAG-[ status ], TAG-[ playlist_loop ], VAL-[ [{"playlist index":0,"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","dur
    Line     40 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-2], ation":"235","artwork_url":"imageproxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","
    Line     41 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-3], tracknum":"5","url":"spotify:track:5eWgDlp3k6Tb5RD8690s6I","remote":1,"year":"0"}] ], SUBS-[0 ] :DEBUG<1281>
    Line     42 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, ParseObj, Send to Post Parse Processing, INDX-[4] :DEBUG<1000>
    Line     43 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TOPTAG-[ status ], TAG-[ status ], OBJ CNT-[3] :DEBUG<2887>
    Line     44 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[1], TAG-[ player_name ], VAL-[ VAV Green ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     45 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[2], TAG-[ player_connected ], VAL-[ 1 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     46 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[3], TAG-[ player_ip ], VAL-[ 127.0.0.1:41658 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     47 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[4], TAG-[ power ], VAL-[ 1 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     48 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[5], TAG-[ signalstrength ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     49 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[6], TAG-[ mode ], VAL-[ stop ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     50 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[7], TAG-[ mixer volume ], VAL-[ 100 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     51 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[8], TAG-[ playlist repeat ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     52 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[9], TAG-[ playlist shuffle ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     53 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[10], TAG-[ playlist mode ], VAL-[ off ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     54 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[11], TAG-[ seq_no ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     55 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[12], TAG-[ playlist_cur_index ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     56 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[13], TAG-[ playlist_timestamp ], VAL-[ 1425729297.63372 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     57 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[14], TAG-[ playlist_tracks ], VAL-[ 1 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     58 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, **, START-->
    Line     59 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, **, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], TAGCNT-[14], ORIGINDX-[1], LVL-[5] :DEBUG<1604>
    Line     60 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ player_name ], VAL-[ VAV Green ], FBINDX-[0] :DEBUG<2214>
    Line     61 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ player_connected ], VAL-[ 1 ], FBINDX-[0] :DEBUG<2214>
    Line     62 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ player_ip ], VAL-[ 127.0.0.1:41658 ], FBINDX-[0] :DEBUG<2214>
    Line     63 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ power ], VAL-[ 1 ], FBINDX-[0] :DEBUG<2214>
    Line     64 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ signalstrength ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     65 (09:56:05)::  SBS__MOD-[1] DEBUG:[L-1], Get_SongTime(), Source either radio & ran once, UI-inactive, -[ time ? ], not added to Q :DEBUG<4652
    Line     66 (09:56:05)::  SBS__MOD-[1] DEBUG:[L-2], >
    Line     67 (09:56:05)::  SBS__MOD-[1] DEBUG:[L-1], Set_Song_TL: Pausing Song TL :DEBUG<9620>
    Line     68 (09:56:05)::  SBS__MOD-[1] DEBUG:[L-1], Set_Song_TL: TL_STATE-[3] :DEBUG<9687>
    Line     69 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ mode ], VAL-[ stop ], FBINDX-[0] :DEBUG<2164>
    Line     70 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ mixer volume ], VAL-[ 100 ], FBINDX-[0] :DEBUG<2214>
    Line     71 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist repeat ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     72 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist shuffle ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     73 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist mode ], VAL-[ off ], FBINDX-[0] :DEBUG<2214>
    Line     74 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ seq_no ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     75 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist_cur_index ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     76 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist_timestamp ], VAL-[ 1425729297.63372 ], FBINDX-[0] :DEBUG<2214>
    Line     77 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist_tracks ], VAL-[ 1 ], FBINDX-[0] :DEBUG<2214>
    Line     78 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[1], TAG-[ playlist index ], VAL-[ 0 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     79 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[2], TAG-[ id ], VAL-[ -225345080 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     80 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[3], TAG-[ title ], VAL-[ Sugar by Maroon 5 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     81 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[4], TAG-[ artist ], VAL-[ Maroon 5 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     82 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[5], TAG-[ duration ], VAL-[ 235 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     83 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[6], TAG-[ artwork_url ], VAL-[ imageproxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg ], OBJINDX-[3], ORIG IN
    Line     84 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-2], DX-[1], FBINDX-[1] :DEBUG<3017>
    Line     85 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[7], TAG-[ album ], VAL-[ V (Deluxe) ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     86 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[8], TAG-[ type ], VAL-[ Ogg Vorbis (Spotify) ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     87 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[9], TAG-[ tracknum ], VAL-[ 5 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     88 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[10], TAG-[ url ], VAL-[ spotify:track:5eWgDlp3k6Tb5RD8690s6I ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     89 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[11], TAG-[ remote ], VAL-[ 1 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     90 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[12], TAG-[ year ], VAL-[ 0 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     91 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, **, START-->
    Line     92 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, **, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], TAGCNT-[12], ORIGINDX-[1], LVL-[5] :DEBUG<1604>
    Line     93 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ playlist index ], VAL-[ 0 ], FBINDX-[1] :DEBUG<2349>
    Line     94 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ id ], VAL-[ -225345080 ], FBINDX-[1] :DEBUG<2349>
    Line     95 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ title ], VAL-[ Sugar by Maroon 5 ], FBINDX-[1] :DEBUG<2349>
    Line     96 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ artist ], VAL-[ Maroon 5 ], FBINDX-[1] :DEBUG<2349>
    Line     97 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ duration ], VAL-[ 235 ], FBINDX-[1] :DEBUG<2349>
    Line     98 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ artwork_url ], VAL-[ imageproxy/spotify:image:462342903cda2a69377d73f1c8
    Line     99 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-2], 37a9ffa73de031/image.jpg ], FBINDX-[1] :DEBUG<2349>
    Line    100 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ album ], VAL-[ V (Deluxe) ], FBINDX-[1] :DEBUG<2349>
    Line    101 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, !!, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ type ], VAL-[ Ogg Vorbis (Spotify) ], FBINDX-[1] :DEBUG<2344>
    Line    102 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, !!, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ tracknum ], VAL-[ 5 ], FBINDX-[1] :DEBUG<2344>
    Line    103 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ url ], VAL-[ spotify:track:5eWgDlp3k6Tb5RD8690s6I ], FBINDX-[1] :DEBUG<2
    Line    104 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-2], 349>
    Line    105 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ remote ], VAL-[ 1 ], FBINDX-[1] :DEBUG<2349>
    Line    106 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ year ], VAL-[ 0 ], FBINDX-[1] :DEBUG<2349>
    

    My debug function:
    This ins't typical since I made this one to maximize the length of the printed string, normally 1/2 this stuff isn't in my function and I just sent the line length to 100 but with this server I get some long strings so I want as much on one print out line as possible.
    DEFINE_FUNCTION fnJSON_DeBug(CHAR iStr[],INTEGER iLVL)
    
         {
         if(nJSON_DeBug[1] > DEBUG_AXI_ONLY && iLVL <= nJSON_DeBug[2])
    	  {
    	  STACK_VAR CHAR cCopyStr[MAX_RESP_LEN];
    	  STACK_VAR INTEGER nLineCount;
    	  LOCAL_VAR INTEGER nLenStr;
    	  
    	  if(!nLenStr)
    	       {//CHAR JSON_MAX_DEBUG_STR = 187; //213 is max, 187 is max we can use. 213 - 26 chars used by AMX (26 + 187 =213) 
    	       cCopyStr = 'JSON_MOD-[xxx] DEBUG:[L-xxx], ';//max it can realistically ever be
    	       nLenStr = (JSON_MAX_DEBUG_STR - LENGTH_STRING(cCopyStr));
    	       SEND_STRING 0,"'JSON_MOD-[',itoa(sJSON.sPlayer.nDev_Instance),']:DEBUG:[L-',itoa(nLineCount),'], set debug str length-[',itoa(nLenStr),' ] :DEBUG<',ITOA(__LINE__),'>'";
    	       cCopyStr = '';
    	       }
    	       
    	  cCopyStr = iStr;//preserve original
    	  WHILE(length_string(cCopyStr) > nLenStr)
    	       {
    	       STACK_VAR CHAR cStrTmp[MAX_256];
    	       STACK_VAR INTEGER nCnt;
    	       STACK_VAR INTEGER i;
    	       
    	       cStrTmp = get_buffer_string(cCopyStr,nLenStr);
    	       //nCnt = fnJSON_FindCharOccurrences("$0d,$0a",cStrTmp);
    	       nCnt = fnJSON_CountNonPrintChars(cStrTmp);
    	      
    	       nLineCount++;
    	       SEND_STRING 0,"'JSON_MOD-[',itoa(sJSON.sPlayer.nDev_Instance),']:DEBUG:[L-',itoa(nLineCount),'], ',get_buffer_string(cStrTmp,nLenStr - (nCnt*2))";
    	       cCopyStr = "cStrTmp,cCopyStr";
    	       }
    	  if(length_string(cCopyStr))
    	       {
    	       STACK_VAR INTEGER nCnt;
    	       
    	       //nCnt = fnJSON_FindCharOccurrences("$0d,$0a",cCopyStr);
    	       nCnt = fnJSON_CountNonPrintChars(cCopyStr);
    	       
    	       nLineCount++;
    	       if((LENGTH_STRING(cCopyStr) + (nCnt*2)) > nLenStr)
    		    {
    		    SEND_STRING 0,"'JSON_MOD-[',itoa(sJSON.sPlayer.nDev_Instance),']:DEBUG:[L-',itoa(nLineCount),'], ',get_buffer_string(cCopyStr,nLenStr - (nCnt*2))";
    		    nLineCount++;
    		    }
    	       SEND_STRING 0,"'JSON_MOD-[',itoa(sJSON.sPlayer.nDev_Instance),']:DEBUG:[L-',itoa(nLineCount),'], ',cCopyStr";
    	       }
    	  }
         
         RETURN;
         } 
    
  • Options
    truetrue Posts: 307
    JasonS wrote: »
    I have found recursion to be somewhat problematic with NetLinx. Nobody in Tech support could give me a definitive answer on how to figure out the depth limitation. Some said it was a fixed number that they didn't know, others said it was based on memory. An alphabetical Bubble sort on 400 items would reach the limit, pre sorting by first letter then bubble sorting each letter group usually worked.

    Agreed. I wrote that just for completeness but I tend to avoid recursion on NetLinx. I've never seen anyone else use it in wild NetLinx code but that's probably the nicest thing I can say about wild NetLinx code...
  • Options
    ericmedleyericmedley Posts: 4,177
    vining wrote: »
    I just use a debug function in each module and put the function call everywhere in my code during the development. I pass an integer to the function for a verbose level so I can control how much I see in diagnostics. I'll put the rx buffer strings at level 5 and then decrease the level at the various stages through out the code.

    Each function call also passes the line in the code where it exists so it easy to find that section. Since some debug strings exceed the length available in a send_string 0 my function also breaks the string it gets passed into multiple lines if necessary and my send_string 0 indicates the line number so again it's easy to tell the lines in diag that are part of the same debug string. When I have my debug calls in switch cases or select active I usually use the default or active(1) if they have no other purpose to print out values that I didn't create a case or active handler for so as I debug I'll find things the device sends that I did plan on and then add them in even if action is required or desired.

    Beginning of function so I can check values coming in:
    DEFINE_FUNCTION fnJSON_Process_FB(_FB iFB)
    
         {
         STACK_VAR _FB sMyFB;
         STACK_VAR INTEGER i;
         STACK_VAR INTEGER nLVL;
         STACK_VAR INTEGER nFBS;
         STACK_VAR INTEGER nIndx;
         STACK_VAR INTEGER nPlugin;
         STACK_VAR INTEGER nRecognized;
         STACK_VAR INTEGER nSearchPerformed;
         
         sMyFB = iFB;
         
         nLVL = sSBS.sBrowseState.nLevel;
         fnJSON_DeBug("'Process_FB, **, START-->'",1);
         fnJSON_DeBug("'Process_FB, **, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], TAGCNT-[',itoa(sMyFB.nTagCnt),'], ORIGINDX-[',itoa(sMyFB.nOrigIndx),'], LVL-[',itoa(nLVL),'] :DEBUG<',ITOA(__LINE__),'>'",1);
    
    Through out the function at vatious stages:
    	 SWITCH(sMyFB.cFB_Tag[i])
    			      {
    			      CASE 'album'		:{sLevelList[nLVL].cAlbum[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'artist'		:{sLevelList[nLVL].cArtist[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'cmd'		:{sLevelList[nLVL].cListCmd[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'command'		:{}//pandora button command arrays
    			      CASE 'genre'		:{sLevelList[nLVL].cGenre[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'playlist'		:{sLevelList[nLVL].cPlaylist[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'title'		:{sLevelList[nLVL].cTitle[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'id'			:
    				   {//spotify has spaces with %20 for some id's, these are needed in string sent back but the DecodeURL func removes them so we add an escape %--
    				    //and modified the DecodeURL func to recognize it
    				   sLevelList[nLVL].cItem_ID[sMyFB.nFB_Indx[i]] = fnStrReplace(sMyFB.cFB_VAL[i],'%20','%--%20');
    				   }//sLevelList[nLVL].nHasItems[sMyFB.nFB_Indx[i]] = 1;
    			      CASE 'icon'		:{sLevelList[nLVL].cIconURL[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'name'		:{sLevelList[nLVL].cName[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'type'		:{sLevelList[nLVL].cType[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'weight'		:{sLevelList[nLVL].cWeight[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'url'		:{sLevelList[nLVL].cURL[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}
    			      CASE 'isaudio'		:{sLevelList[nLVL].nIsAudio[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'hasitems'		:{sLevelList[nLVL].nHasItems[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'duration'		:{sLevelList[nLVL].nDuration[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'tracknum'		:{sLevelList[nLVL].nTrackNum[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'remote'		:{sLevelList[nLVL].nRemote[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}
    			      CASE 'image'		:{sLevelList[nLVL].cImageURL[sMyFB.nFB_Indx[i]] = sMyFB.cFB_VAL[i];}//found in radios, pandora
    			      CASE 'playlist index' 	:{sLevelList[nLVL].nIndxNum[sMyFB.nFB_Indx[i]] = atoi(sMyFB.cFB_VAL[i]);}//playlist tracks zap song
    			      DEFAULT:
    				   {
    				   nRecognized = 0;
    				   fnJSON_DeBug("'Process_FB, !!, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX-[',itoa(sMyFB.nFB_Indx[i]),'] :DEBUG<',ITOA(__LINE__),'>'",1);
    				   }
    			      }
    			 if(nRecognized)
    			      {
    			      fnJSON_DeBug("'Process_FB, $$, TOPTAG-[ ',sMyFB.cTopTag,' ], TAG-[ ',sMyFB.cTag,' ], OBJTAG-[ ',sMyFB.cObjTag,' ], FBTAG-[ ',sMyFB.cFB_Tag[i],' ], VAL-[ ',sMyFB.cFB_Val[i],' ], FBINDX-[',itoa(sMyFB.nFB_Indx[i]),'] :DEBUG<',ITOA(__LINE__),'>'",1);
    			      nRecognized = 0;
    			      }
    			 }
    ........
    
    The print oun in diagnostics.
    Line      4 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], TX to JSON.....,PARAM_STR-[ ["00:04:20:23:a7:6d",["status",0,8,"tags:aBdgKlNotuxyY"]] ] :DEBUG<3368>
    Line      5 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], ParseBody, Result, VAL-[ {"player_name":"VAV Green","player_connected":1,"player_ip":"127.0.0.1:41658","power":1,"signalstrength":0,"mode":"stop","mixer volu
    Line      6 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-2], me":100,"playlist repeat":0,"playlist shuffle":0,"playlist mode":"off","seq_no":0,"playlist_cur_index":0,"playlist_timestamp":1425729297.63372,"playlist_trac
    Line      7 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-3], ks":1,"remoteMeta":{"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_url":"imageproxy/spotify:image:462342903cda2a
    Line      8 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-4], 69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"spotify:track:5eWgDlp3k6Tb5RD8690s6I","remote"
    Line      9 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-5], :1,"year":"0"},"playlist_loop":[{"playlist index":0,"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_url":"imagepr
    Line     10 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-6], oxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"spotify:track:
    Line     11 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-7], 5eWgDlp3k6Tb5RD8690s6I","remote":1,"year":"0"}]} ] :DEBUG<932>
    Line     12 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], ParseBody, Param, TAG-[ params ], VAL-[ ["00:04:20:23:a7:6d",["status","0",8,"tags:aBdgKlNotuxyY"]] ] :DEBUG<950>
    Line     13 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Param, TAG-[ params ], VAL[ ["00:04:20:23:a7:6d",["status","0",8,"tags:aBdgKlNotuxyY"]] ] :DEBUG<1379>
    Line     14 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Param, $$, TAG-[ params ], VAL1-[ status ], VAL2-[ 0 ], VAL3-[ 8 ], CNT-[4] :DEBUG<1579>
    Line     15 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, Parent-[ status ], VAL-[ {"player_name":"VAV Green","player_connected":1,"player_ip":"127.0.0.1:41658","power":1,"signalstrength":0,"mode":"stop",
    Line     16 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-2], "mixer volume":100,"playlist repeat":0,"playlist shuffle":0,"playlist mode":"off","seq_no":0,"playlist_cur_index":0,"playlist_timestamp":1425729297.63372,"pl
    Line     17 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-3], aylist_tracks":1,"remoteMeta":{"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_url":"imageproxy/spotify:image:462
    Line     18 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-4], 342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"spotify:track:5eWgDlp3k6Tb5RD8690s6
    Line     19 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-5], I","remote":1,"year":"0"},"playlist_loop":[{"playlist index":0,"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_ur
    Line     20 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-6], l":"imageproxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"spo
    Line     21 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-7], tify:track:5eWgDlp3k6Tb5RD8690s6I","remote":1,"year":"0"}]} ], INDX-[1], OBJ CNT-[1], ORIG INDX-[1] :DEBUG<1243>
    Line     22 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ player_name:VAV Green ] ] :DEBUG<1356>
    Line     23 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ player_connected:1 ] ] :DEBUG<1356>
    Line     24 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ player_ip:127.0.0.1:41658 ] ] :DEBUG<1356>
    Line     25 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ power:1 ] ] :DEBUG<1356>
    Line     26 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ signalstrength:0 ] ] :DEBUG<1356>
    Line     27 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ mode:stop ] ] :DEBUG<1356>
    Line     28 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ mixer volume:100 ] ] :DEBUG<1356>
    Line     29 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist repeat:0 ] ] :DEBUG<1356>
    Line     30 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist shuffle:0 ] ] :DEBUG<1356>
    Line     31 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist mode:off ] ] :DEBUG<1356>
    Line     32 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ seq_no:0 ] ] :DEBUG<1356>
    Line     33 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist_cur_index:0 ] ] :DEBUG<1356>
    Line     34 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist_timestamp:1425729297.63372 ] ] :DEBUG<1356>
    Line     35 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, TAG:VAL-[ playlist_tracks:1 ] ] :DEBUG<1356>
    Line     36 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, Object, TOPTAG-[ status ], TAG-[ remoteMeta ], VAL-[ {"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","duration":"235","artwork_
    Line     37 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-2], url":"imageproxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","tracknum":"5","url":"s
    Line     38 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-3], potify:track:5eWgDlp3k6Tb5RD8690s6I","remote":1,"year":"0"} ], SUBS-[0 ] :DEBUG<1309>
    Line     39 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, Array, TOPTAG-[ status ], TAG-[ playlist_loop ], VAL-[ [{"playlist index":0,"id":"-225345080","title":"Sugar by Maroon 5","artist":"Maroon 5","dur
    Line     40 (09:56:04)::  JSON_MOD-[1]:DEBUG:[L-2], ation":"235","artwork_url":"imageproxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg","album":"V (Deluxe)","type":"Ogg Vorbis (Spotify)","
    Line     41 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-3], tracknum":"5","url":"spotify:track:5eWgDlp3k6Tb5RD8690s6I","remote":1,"year":"0"}] ], SUBS-[0 ] :DEBUG<1281>
    Line     42 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Parse_Obj, ParseObj, Send to Post Parse Processing, INDX-[4] :DEBUG<1000>
    Line     43 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TOPTAG-[ status ], TAG-[ status ], OBJ CNT-[3] :DEBUG<2887>
    Line     44 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[1], TAG-[ player_name ], VAL-[ VAV Green ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     45 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[2], TAG-[ player_connected ], VAL-[ 1 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     46 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[3], TAG-[ player_ip ], VAL-[ 127.0.0.1:41658 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     47 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[4], TAG-[ power ], VAL-[ 1 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     48 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[5], TAG-[ signalstrength ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     49 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[6], TAG-[ mode ], VAL-[ stop ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     50 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[7], TAG-[ mixer volume ], VAL-[ 100 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     51 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[8], TAG-[ playlist repeat ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     52 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[9], TAG-[ playlist shuffle ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     53 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[10], TAG-[ playlist mode ], VAL-[ off ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     54 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[11], TAG-[ seq_no ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     55 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[12], TAG-[ playlist_cur_index ], VAL-[ 0 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     56 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[13], TAG-[ playlist_timestamp ], VAL-[ 1425729297.63372 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     57 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, TAG/VAL, CNT-[14], TAG-[ playlist_tracks ], VAL-[ 1 ], OBJINDX-[1], ORIG INDX-[1] :DEBUG<2928>
    Line     58 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, **, START-->
    Line     59 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, **, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], TAGCNT-[14], ORIGINDX-[1], LVL-[5] :DEBUG<1604>
    Line     60 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ player_name ], VAL-[ VAV Green ], FBINDX-[0] :DEBUG<2214>
    Line     61 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ player_connected ], VAL-[ 1 ], FBINDX-[0] :DEBUG<2214>
    Line     62 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ player_ip ], VAL-[ 127.0.0.1:41658 ], FBINDX-[0] :DEBUG<2214>
    Line     63 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ power ], VAL-[ 1 ], FBINDX-[0] :DEBUG<2214>
    Line     64 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ signalstrength ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     65 (09:56:05)::  SBS__MOD-[1] DEBUG:[L-1], Get_SongTime(), Source either radio & ran once, UI-inactive, -[ time ? ], not added to Q :DEBUG<4652
    Line     66 (09:56:05)::  SBS__MOD-[1] DEBUG:[L-2], >
    Line     67 (09:56:05)::  SBS__MOD-[1] DEBUG:[L-1], Set_Song_TL: Pausing Song TL :DEBUG<9620>
    Line     68 (09:56:05)::  SBS__MOD-[1] DEBUG:[L-1], Set_Song_TL: TL_STATE-[3] :DEBUG<9687>
    Line     69 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ mode ], VAL-[ stop ], FBINDX-[0] :DEBUG<2164>
    Line     70 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ mixer volume ], VAL-[ 100 ], FBINDX-[0] :DEBUG<2214>
    Line     71 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist repeat ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     72 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist shuffle ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     73 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist mode ], VAL-[ off ], FBINDX-[0] :DEBUG<2214>
    Line     74 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ seq_no ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     75 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist_cur_index ], VAL-[ 0 ], FBINDX-[0] :DEBUG<2214>
    Line     76 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist_timestamp ], VAL-[ 1425729297.63372 ], FBINDX-[0] :DEBUG<2214>
    Line     77 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ status ], FBTAG-[ playlist_tracks ], VAL-[ 1 ], FBINDX-[0] :DEBUG<2214>
    Line     78 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[1], TAG-[ playlist index ], VAL-[ 0 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     79 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[2], TAG-[ id ], VAL-[ -225345080 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     80 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[3], TAG-[ title ], VAL-[ Sugar by Maroon 5 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     81 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[4], TAG-[ artist ], VAL-[ Maroon 5 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     82 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[5], TAG-[ duration ], VAL-[ 235 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     83 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[6], TAG-[ artwork_url ], VAL-[ imageproxy/spotify:image:462342903cda2a69377d73f1c837a9ffa73de031/image.jpg ], OBJINDX-[3], ORIG IN
    Line     84 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-2], DX-[1], FBINDX-[1] :DEBUG<3017>
    Line     85 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[7], TAG-[ album ], VAL-[ V (Deluxe) ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     86 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[8], TAG-[ type ], VAL-[ Ogg Vorbis (Spotify) ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     87 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[9], TAG-[ tracknum ], VAL-[ 5 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     88 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[10], TAG-[ url ], VAL-[ spotify:track:5eWgDlp3k6Tb5RD8690s6I ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     89 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[11], TAG-[ remote ], VAL-[ 1 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     90 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_Obj, ParseOB, CNT-[12], TAG-[ year ], VAL-[ 0 ], OBJINDX-[3], ORIG INDX-[1], FBINDX-[1] :DEBUG<3017>
    Line     91 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, **, START-->
    Line     92 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, **, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], TAGCNT-[12], ORIGINDX-[1], LVL-[5] :DEBUG<1604>
    Line     93 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ playlist index ], VAL-[ 0 ], FBINDX-[1] :DEBUG<2349>
    Line     94 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ id ], VAL-[ -225345080 ], FBINDX-[1] :DEBUG<2349>
    Line     95 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ title ], VAL-[ Sugar by Maroon 5 ], FBINDX-[1] :DEBUG<2349>
    Line     96 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ artist ], VAL-[ Maroon 5 ], FBINDX-[1] :DEBUG<2349>
    Line     97 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ duration ], VAL-[ 235 ], FBINDX-[1] :DEBUG<2349>
    Line     98 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ artwork_url ], VAL-[ imageproxy/spotify:image:462342903cda2a69377d73f1c8
    Line     99 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-2], 37a9ffa73de031/image.jpg ], FBINDX-[1] :DEBUG<2349>
    Line    100 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ album ], VAL-[ V (Deluxe) ], FBINDX-[1] :DEBUG<2349>
    Line    101 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, !!, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ type ], VAL-[ Ogg Vorbis (Spotify) ], FBINDX-[1] :DEBUG<2344>
    Line    102 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, !!, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ tracknum ], VAL-[ 5 ], FBINDX-[1] :DEBUG<2344>
    Line    103 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ url ], VAL-[ spotify:track:5eWgDlp3k6Tb5RD8690s6I ], FBINDX-[1] :DEBUG<2
    Line    104 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-2], 349>
    Line    105 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ remote ], VAL-[ 1 ], FBINDX-[1] :DEBUG<2349>
    Line    106 (09:56:05)::  JSON_MOD-[1]:DEBUG:[L-1], Process_FB, $$, TOPTAG-[ status ], TAG-[ status ], OBJTAG-[ playlist_loop ], FBTAG-[ year ], VAL-[ 0 ], FBINDX-[1] :DEBUG<2349>
    

    My debug function:
    This ins't typical since I made this one to maximize the length of the printed string, normally 1/2 this stuff isn't in my function and I just sent the line length to 100 but with this server I get some long strings so I want as much on one print out line as possible.
    DEFINE_FUNCTION fnJSON_DeBug(CHAR iStr[],INTEGER iLVL)
    
         {
         if(nJSON_DeBug[1] > DEBUG_AXI_ONLY && iLVL <= nJSON_DeBug[2])
    	  {
    	  STACK_VAR CHAR cCopyStr[MAX_RESP_LEN];
    	  STACK_VAR INTEGER nLineCount;
    	  LOCAL_VAR INTEGER nLenStr;
    	  
    	  if(!nLenStr)
    	       {//CHAR JSON_MAX_DEBUG_STR = 187; //213 is max, 187 is max we can use. 213 - 26 chars used by AMX (26 + 187 =213) 
    	       cCopyStr = 'JSON_MOD-[xxx] DEBUG:[L-xxx], ';//max it can realistically ever be
    	       nLenStr = (JSON_MAX_DEBUG_STR - LENGTH_STRING(cCopyStr));
    	       SEND_STRING 0,"'JSON_MOD-[',itoa(sJSON.sPlayer.nDev_Instance),']:DEBUG:[L-',itoa(nLineCount),'], set debug str length-[',itoa(nLenStr),' ] :DEBUG<',ITOA(__LINE__),'>'";
    	       cCopyStr = '';
    	       }
    	       
    	  cCopyStr = iStr;//preserve original
    	  WHILE(length_string(cCopyStr) > nLenStr)
    	       {
    	       STACK_VAR CHAR cStrTmp[MAX_256];
    	       STACK_VAR INTEGER nCnt;
    	       STACK_VAR INTEGER i;
    	       
    	       cStrTmp = get_buffer_string(cCopyStr,nLenStr);
    	       //nCnt = fnJSON_FindCharOccurrences("$0d,$0a",cStrTmp);
    	       nCnt = fnJSON_CountNonPrintChars(cStrTmp);
    	      
    	       nLineCount++;
    	       SEND_STRING 0,"'JSON_MOD-[',itoa(sJSON.sPlayer.nDev_Instance),']:DEBUG:[L-',itoa(nLineCount),'], ',get_buffer_string(cStrTmp,nLenStr - (nCnt*2))";
    	       cCopyStr = "cStrTmp,cCopyStr";
    	       }
    	  if(length_string(cCopyStr))
    	       {
    	       STACK_VAR INTEGER nCnt;
    	       
    	       //nCnt = fnJSON_FindCharOccurrences("$0d,$0a",cCopyStr);
    	       nCnt = fnJSON_CountNonPrintChars(cCopyStr);
    	       
    	       nLineCount++;
    	       if((LENGTH_STRING(cCopyStr) + (nCnt*2)) > nLenStr)
    		    {
    		    SEND_STRING 0,"'JSON_MOD-[',itoa(sJSON.sPlayer.nDev_Instance),']:DEBUG:[L-',itoa(nLineCount),'], ',get_buffer_string(cCopyStr,nLenStr - (nCnt*2))";
    		    nLineCount++;
    		    }
    	       SEND_STRING 0,"'JSON_MOD-[',itoa(sJSON.sPlayer.nDev_Instance),']:DEBUG:[L-',itoa(nLineCount),'], ',cCopyStr";
    	       }
    	  }
         
         RETURN;
         } 
    


    Now THIS is the good ole AMX Forum that I know and love!
Sign In or Register to comment.