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?
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.
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
0
[Deleted User]Harman Integrated Technologies Group (ITG)Posts: 0
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.
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
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.
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.
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.
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
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.
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.
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:
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.
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.
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.
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.
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.
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.
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.
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...
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:
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.
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...
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:
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.
Comments
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:
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
^^ 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.
^^ 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
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
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?
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
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.
Agreed,
I rarely use local_var. and stack_vars are always "throw away" stuff.
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.
define_function integer fnGfjadj(INTEGER _ddd) {
local_var integer notGlobal
notGlobal = notGlobal + _ddd
return notGlobal
}
x = fnGfjadj(1)
why? i don't know
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:
The variables do not get initiated on the first button press. If I press it two more times, it then initiates the variables.
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.
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.
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.
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.
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...
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: Through out the function at vatious stages: The print oun in diagnostics.
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.
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...
Now THIS is the good ole AMX Forum that I know and love!