Home AMX User Forum AMXForums Archive Threads Tips and Tricks

Parsing IPod and Internet Radio Data

I have a Denon AVR-3312CI A/V receiver which is controlled by RS-232. The 3312CI has a RJ-45 connection to the Internet for Internet Radio and an USB connection for an iPod/iPhone. How can I display the Internet Radio data or the iPod metadata on a touch panel?

Thanks, Donald

Comments

  • viningvining Posts: 4,368
    You need to get the API for the AVR and look up the commands to control and query the device the the features you want.
  • dsmithdsmith Posts: 30
    I have the RS-232 document for the Denon and on page 25, it talks about the NSA and the NSE commands, where it refers you to page 46 & 47. I've tried to call Denon Integrator support line, but I have to be a A/V integrator with a passcode to get through.

    Thanks.
  • viningvining Posts: 4,368
    dsmith wrote: »
    I've tried to call Denon Integrator support line, but I have to be a A/V integrator with a passcode to get through.

    Thanks.

    What are you? Are you an AMX programmer trying to get additional features to work from an AMX or home grown and rolled module? If memory serves me the doc you specified should have all the commands needed but using them requires knowledge of AMX programming and access to the code including the Denon module code if you didn't roll it yourself.

    If you're not an AMX programmer you'll need to get one cuz is ain't plug and play and you can't just flip a switch to make it work. To add those features could take 20-40+ hours to do right depending on what you're starting with for a good programmer. It would take me 40-80+. :)
  • dsmithdsmith Posts: 30
    I have written in Axcess the program for my home theater then I wrote the same program from scratch in Netlinx. I have also been the the formal AMX programming 1 class. I just want to expand the capabilities of my home theater program. Funny thing, I've never used a module before.
  • viningvining Posts: 4,368
    So if you wrote the code currently being used to control the Denon AVR then it shouldn't be that difficult to add those features. Just requires time and patience. I doubt you'd gain anything talking with Denon's TS though, best bet would be to go through the api and play with the commands. When you're stuck or confused post your problem with a snippet of code. You could also ask forum members that may have already added these features to their own module for any tips or tricks that they've discovered.

    Any way the Denon api should give you specific commands needed to impliment those features and then give the possible replies that you'll need to parse and process.
  • dsmithdsmith Posts: 30
    More questions:

    In reading the forums. I came across this snipet of code:
    DEFINE_TYPE
    STRUCTURE stDEN_DNP720_STRUCTURE
    {
    WIDECHAR cDISP_DATA[135]
    }
    DEFINE_VARIABLE
    VOLATILE stDEN_DNP720_STRUCTURE stDISPLINE 
    VOLATILE stDEN_DNP720_STRUCTURE stDISPLINEARRAY [9]
    
    VOLATILE CHAR cDEN_DNP720_BUFFER [1500]
    VOLATILE CHAR cDEN_DNP720_DATA [135]
    VOLATILE WIDECHAR wcDEN_DNP720_DATA [135]
    VOLATILE INTEGER nLINE	=	0
    VOLATILE CHAR cTRASH	
    
    DEFINE_START
    INCLUDE 'UnicodeLib.axi'
    
    DEFINE_EVENT
    DATA_EVENT[dvDEN720]
    {
    STRING:
    	{
    	LOCAL_VAR CHAR cTPSTRING [500]
    	cDEN_DNP720_BUFFER = "cDEN_DNP720_BUFFER,DATA.TEXT"
    	wcDEN_DNP720_DATA = _wc(data.text)
    	WHILE (FIND_STRING(cDEN_DNP720_BUFFER,"$0D",1))
    		{
    		cDEN_DNP720_DATA = REMOVE_STRING (cDEN_DNP720_BUFFER,"$0D",1)
    		SELECT
    			{
    			ACTIVE (FIND_STRING(cDEN_DNP720_DATA,"'PWON'",1)):
    				{
    				nDEN_DNP720_POWER = conPWR_ON
    				}
    			ACTIVE (FIND_STRING(cDEN_DNP720_DATA,"'PWSTANDBY'",1)):
    				{
    				nDEN_DNP720_POWER = conPWR_OFF
    				}
    			ACTIVE (FIND_STRING(cDEN_DNP720_DATA,"'NSE'",1)):
    				{
    				REMOVE_STRING (cDEN_DNP720_DATA,"'NSE'",1)
    				nLINE = ATOI(LEFT_STRING(cDEN_DNP720_DATA,1))+1
    				cTRASH = GET_BUFFER_CHAR(cDEN_DNP720_DATA)
    				//cDEN_DNP720_DATA = LEFT_STRING (cDEN_DNP720_DATA,(FIND_STRING(cDEN_DNP720_DATA,"'_'",1)-1))
    				cTPSTRING = WC_TP_ENCODE(wcDEN_DNP720_DATA)
    				SEND_COMMAND dvTPKITSERVER,  "'^UNI-',ITOA(nLINE+210),',0,',cTPSTRING "
    

    If I modify the variables to suit my needs, this looks like it would work. My confusion is two fold: 1) how to display the text in Netlinx Studio for troubleshooting 2) how to display the text on the Modero.

    Thanks, dsmith
  • dsmithdsmith Posts: 30
    Any suggestions?

    Thanks, dsmith
  • I started doing AMX after the Axcess era, but i think (?) there is major changes since then.
    A new Programmer-1 training might be the way to go!

    Regarding your questions...

    Q1: Look at the "Debug" window in NS. You can track your variables "real time"
    Q2: Have a read through in the AMX PI under your Touchpanel model. Its all covered there
  • dsmithdsmith Posts: 30
    Parsing Test

    Does anyone have some parsing code that I use to test parsing or tell me why my code isn't working. I'm new to parsing and my end result is to parse Ipod and Internet Radio data from my Denon AV receiver and display it on my MVP-8400.

    My code:
    DEFINE_DEVICE
    
    RECEIVER = 6:1:0         (* DENON AVR-3312CI, RS232, 9600,N,8,1 *)
    MVP_8400 = 10001:1:0     (* AMX MVP-8400 TOUCH PANEL *)
    vdvTP = 33001:1:0        // VIRTUAL DEVICE FOR PANEL COMBINE
    vdvBUFFER = 35000:1:0      // VIRTUAL BUFFER FOR DENON RECIEVER
    
    DEFINE_VARIABLE
    
    
    VOLATILE CHAR DENON_BUFFER [1500]
    VOLATILE CHAR DENON_DATA [135]
    VOLATILE INTEGER nLINE	=	0
    VOLATILE CHAR cTRASH
    
    DEFINE_START
    
    SEND_COMMAND RECEIVER,'SET BAUD 9600,N,8,1 232 ENABLE'
    CREATE_BUFFER vdvBUFFER, DENON_BUFFER
    
    DEFINE_EVENT
    
    DATA_EVENT[RECEIVER]
    {
    ONLINE:
    	{
    	LOCAL_VAR CHAR cTPSTRING [500]
    	DENON_BUFFER = "DENON_BUFFER,DATA.TEXT"
    	DENON_DATA = (DATA.TEXT)
    	WHILE (FIND_STRING(DENON_BUFFER,"$0D",1))
    		{
    		DENON_DATA = REMOVE_STRING (DENON_BUFFER,"$0D",1)
    		SELECT
    			{
    			ACTIVE (FIND_STRING(DENON_DATA,"'NSE'",1)):
    				{
    				REMOVE_STRING (DENON_DATA,"'NSE'",1)
    				nLINE = ATOI(LEFT_STRING(DENON_DATA,1))+1
    				cTRASH = GET_BUFFER_CHAR(DENON_DATA)
    				SEND_COMMAND vdvTP,  "'^TXT-210,1,DENON_DATA'"
                                    }
                            }
    		}
    	}
    }	
    
    

    I've also reattached the Denon Protocol list. My code compiles with no errors but I can't see the iPod output in Netlinx. Thanks for the help.

    dsmith
  • Here is the full include, not just the snippet that you posted earlier.
  • dsmithdsmith Posts: 30
    PHSJason,

    My iPod connects directly to the Denon receiver via the Denon's USB or by using Airplay in the Denon, so I don't understand how the snippet of code can help, due to my not knowing how parsing works.

    dsmith
  • dsmith wrote: »
    PHSJason,

    My iPod connects directly to the Denon receiver via the Denon's USB or by using Airplay in the Denon, so I don't understand how the snippet of code can help, due to my not knowing how parsing works.

    dsmith

    I am going to have to apologize. I want to be helpful, but I am currently buried at work, and don't have the time in next few weeks to do more than what I have currently posted. I wish I could be of further help. Maybe after the holidays.
  • dsmithdsmith Posts: 30
    PHSJason wrote: »
    I am going to have to apologize. I want to be helpful, but I am currently buried at work, and don't have the time in next few weeks to do more than what I have currently posted. I wish I could be of further help. Maybe after the holidays.

    I completely understand. Please post what you can when you can.

    Happy Thankgiving to you.

    dsmith
  • viningvining Posts: 4,368
    The first thing that immediately comes to mind is your code in an ONLINE event handler trying to parse strings from the device.

    Next you then have DENON_DATA = (DATA.TEXT) which you don't want since your want to fill that from your buffer when you find $0D which you do later in your code.

    instead of being global, DENON_DATA should be a stack_var so in every pass of the while loop it starts fresh (empty). I changed that var's name so it doesn't get confused with your global var.

    I then made a few minor changes and added send_string 0's so you can see what's coming in, in diagnostics to assist in fine tuning your parsing techniques.

    Your send command to the TP was also messed up so that a look at how I did it.
    DEFINE_EVENT
    
    DATA_EVENT[RECEIVER]
         
         {
         STRING://ONLINE:
    	  {
    	  DENON_BUFFER = "DENON_BUFFER,DATA.TEXT"
    	  //DENON_DATA = (DATA.TEXT)
    	  WHILE (FIND_STRING(DENON_BUFFER,"$0D",1))
    	       {
    	       STACK_VAR CHAR cStrDATA[256]; 
    	       
    	       cStrDATA = REMOVE_STRING(DENON_BUFFER,"$0D",1);
    	       SET_LENGTH_STRING(cStrDATA,LENGTH_STRING(cStrDATA)-1);//get rid of $0D
    	       SELECT
    		    {
    		    ACTIVE(FIND_STRING(cStrDATA,"'NSE'",1)):
    			 {
    			 SEND_STRING 0,"'RX FROM DEVICE, WANTED-[ ',cStrDATA,' ] :DEBUG<',__LINE__,'>'";//THIS MAY BE TRUNCATED
    			 REMOVE_STRING(cStrDATA,"'NSE'",1)
    			 nLINE = ATOI(REMOVE_STRING(cStrDATA,"' '",1) +1);
    			 SEND_COMMAND vdvTP,"'^TXT-210,1,',cStrDATA";
    			 }
    		    ACTIVE(1):
    			 {
    			 SEND_STRING 0,"'RX FROM DEVICE, UNWANTED-[ ',cStrDATA,' ] :DEBUG<',__LINE__,'>'";//THIS MAY BE TRUNCATED
    			 }
    		    }
    	       }
    	  }
         }
    
  • dsmithdsmith Posts: 30
    vining wrote: »
    The first thing that immediately comes to mind is your code in an ONLINE event handler trying to parse strings from the device.

    Next you then have DENON_DATA = (DATA.TEXT) which you don't want since your want to fill that from your buffer when you find $0D which you do later in your code.

    instead of being global, DENON_DATA should be a stack_var so in every pass of the while loop it starts fresh (empty). I changed that var's name so it doesn't get confused with your global var.

    I then made a few minor changes and added send_string 0's so you can see what's coming in, in diagnostics to assist in fine tuning your parsing techniques.

    Your send command to the TP was also messed up so that a look at how I did it.
    DEFINE_EVENT
    
    DATA_EVENT[RECEIVER]
         
         {
         STRING://ONLINE:
    	  {
    	  DENON_BUFFER = "DENON_BUFFER,DATA.TEXT"
    	  //DENON_DATA = (DATA.TEXT)
    	  WHILE (FIND_STRING(DENON_BUFFER,"$0D",1))
    	       {
    	       STACK_VAR CHAR cStrDATA[256]; 
    	       
    	       cStrDATA = REMOVE_STRING(DENON_BUFFER,"$0D",1);
    	       SET_LENGTH_STRING(cStrDATA,LENGTH_STRING(cStrDATA)-1);//get rid of $0D
    	       SELECT
    		    {
    		    ACTIVE(FIND_STRING(cStrDATA,"'NSE'",1)):
    			 {
    			 SEND_STRING 0,"'RX FROM DEVICE, WANTED-[ ',cStrDATA,' ] :DEBUG<',__LINE__,'>'";//THIS MAY BE TRUNCATED
    			 REMOVE_STRING(cStrDATA,"'NSE'",1)
    			 nLINE = ATOI(REMOVE_STRING(cStrDATA,"' '",1) +1);
    			 SEND_COMMAND vdvTP,"'^TXT-210,1,',cStrDATA";
    			 }
    		    ACTIVE(1):
    			 {
    			 SEND_STRING 0,"'RX FROM DEVICE, UNWANTED-[ ',cStrDATA,' ] :DEBUG<',__LINE__,'>'";//THIS MAY BE TRUNCATED
    			 }
    		    }
    	       }
    	  }
         }
    

    Vining,

    First, thanks for the help.

    When the program is compiled, I get these errors:
    ---------- Starting NetLinx Compile - Version[2.5.2.20] [11-21-2012 00:22:26] ----------  
    C:\My AMX code\Home Theater Program.axs  
    WARNING: C:\My AMX code\Home Theater Program.axs(131): C10573: String used as a CHAR value in a math operation  
    ERROR: C:\My AMX code\Home Theater Program.axs(130): C10574: Zero length array bound for [A]  
    WARNING: C:\My AMX code\Home Theater Program.axs(131): C10573: String used as a CHAR value in a math operation  
    C:\My AMX code\Home Theater Program.axs - 1 error(s), 2 warning(s)  
    NetLinx Compile Complete [11-21-2012 00:22:28]  
    

    Line 130 in my code is this: nLINE = ATOI(REMOVE_STRING(cStrDATA,"' '",1) +1);

    If I comment it out with //, my program show no compiles errors.

    Also, I now can see the NSE information is the Netlinx Notification window but nothing in the button on the touch panel.

    My next questions would be 1) how to parse the data, so the album name, song, album art and elapsed time show on the touch panel?

    Thanks again, Vining and Happy Thanksgiving.

    dsmith
  • viningvining Posts: 4,368
    Try: nLINE = ( ATOI(REMOVE_STRING(cStrDATA,"' '",1) ) +1);

    This looks proper now although still untested or compiled. I'll give it a go when i get to a pc and verify.

    I'll try and look at your other questions then.
  • dsmithdsmith Posts: 30
    vining wrote: »
    Try: nLINE = ( ATOI(REMOVE_STRING(cStrDATA,"' '",1) ) +1);

    This looks proper now although still untested or compiled. I'll give it a go when i get to a pc and verify.

    I'll try and look at your other questions then.

    Vining,
    The added parenthesis' worked.

    dsmith
  • viningvining Posts: 4,368
    dsmith wrote: »
    Vining,
    The added parenthesis' worked.

    dsmith
    Yeah once you said it didn't compile it was easy to see the mistake. That's what happens when you rush through things with out proofing.

    dsmith wrote:
    Also, I now can see the NSE information is the Netlinx Notification window but nothing in the button on the touch panel.

    My next questions would be 1) how to parse the data, so the album name, song, album art and elapsed time show on the touch panel?
    In your code you're sending to a virtual so unless that virtual is combined (define_combine) with a real TP or your virtual has a command event to relay to a real TP it won't show. I personally don't used define_combine and I would just send it directly to the TP unless I'm passing this data out of a module back to the main code but then I would use send_string not send command. For now you should just send directly to the TP and leave the other crap until you got this crap figured out.

    To get the other info you'll need a seperate VT channel for each line you want to display and then parse based on the line numbers. The only real funky thing is with line 1-6 once you get rid of NSE and the line number you'll need to do bitwise comparisons on the first byte that remains and each bit in that byte will give the specific info that's spelled out in the protocol. Example bit 1 of that byte is whether or not that location is playable.

    PHSJason's code has this all done in the code he posted so you should use that as a reference and learning tool. If you have questions regarding his code just ask the forum and even though he's busy someone else will likely help if they have time. If you're trying to learn more so than trying to get a project completed in a hurry I would take snippets of his code and paste them into yours and play with it a little at a time to get an understanding of how this all works. When you get past one hurdle move on to the next. Got a question on why or how just ask.
  • dsmithdsmith Posts: 30
    More parsing questions

    I've decided to give up on the parsing Ipod & Internet Radio data for for now for something easier (I hope). I would like to parse the Denon's volume level to be displayed on the panel. So I've changed my code to look for the 'MV' parameter:
    DATA_EVENT[RECEIVER]
         
         {
         STRING://ONLINE:
    	  {
    	  DENON_BUFFER = "DENON_BUFFER,DATA.TEXT"
    	  //DENON_DATA = (DATA.TEXT)
    	  WHILE (FIND_STRING(DENON_BUFFER,"$0D",1))
    	       {
    	       STACK_VAR CHAR cStrDATA[256]; 
    	       
    	       cStrDATA = REMOVE_STRING(DENON_BUFFER,"$0D",1);
    	       SET_LENGTH_STRING(cStrDATA,LENGTH_STRING(cStrDATA)-1);//get rid of $0D
    	       SELECT
    		    {
    		    ACTIVE(FIND_STRING(cStrDATA,"'MV'",1)):
    			 {
    			 //SEND_STRING 0,"'RX FROM DEVICE, WANTED-[ ',cStrDATA,' ] :DEBUG<',__LINE__,'>'";//THIS MAY BE TRUNCATED
    			 REMOVE_STRING(cStrDATA,"'MV'",1)
    			 nLINE = (ATOI(REMOVE_STRING(cStrDATA,"' '",1)) +1);
    			 SEND_COMMAND vdvTP,"'^TXT-210,1&2,',cStrDATA"; // scrolls at the top fast
    			 }
    		    ACTIVE(1):
    			 {
    			 //SEND_STRING 0,"'RX FROM DEVICE, UNWANTED-[ ',cStrDATA,' ] :DEBUG<',__LINE__,'>'";//THIS MAY BE TRUNCATED
    			 }
    		    }
    	       }
    	  }
         }
    

    Going back to one of my older questions, how do I parse this data and display it on the touch panel?

    Thanks, dsmith
Sign In or Register to comment.