Home AMX User Forum AMX Technical Discussion

RUSSOUND SMS3 Protocol Help

I ahve to code one of these soon - the russound Media Server...I dont understand what to do with this protocol as it appears to be XML based.

Help Please...maybe some sample strings....thanks guys

Below Are linx to protocol

Thanx

Rolo



http://www.harmonysoundandvision.com/Russound%20SMS3%20RS-232%20Commands.htm

http://www.harmonysoundandvision.com/Russound%20SMS3%20RS-232%20Protocol.htm

http://www.harmonysoundandvision.com/Russound%20SMS3%20RS-232%20Queries.htm

Comments

  • For their queries, you're probably going to want to sit down with one of these and watch how data comes back based on certain commands, since those documents aren't terribly specific.

    But otherwise, the syntax for what you're sending isn't difficult - don't be intimidated by the label of "XML"...

    Each example they show in the protocol can simply be sent with SEND_STRING commands in sequence, so their "stream 1, nextsong" would look like this:
    SEND_STRING Russ,"'<?xml version="1.0"?>',$0D,$0A"
    SEND_STRING Russ,"'<Event>',$0D,$0A"
    SEND_STRING Russ,"'<Command>NextSong</Command>',$0D,$0A"
    SEND_STRING Russ,"'<Stream>1</Stream>',$0D,$0A"
    SEND_STRING Russ,"'</Event>',$0D,$0A"
    SEND_STRING Russ,"'@',$0D,$0A"
    
    Technically, if they're processing your XML-formatted commands properly, you don't need to put a $0D,$0A at the end of each line, but their comments on the end of message character seems to indicate that you should use them.

    Parsing responses doesn't initially appear too difficult, as you're getting something like this in your buffer:
    <Info>
    <Stream>1</Stream>
    <State>Playing</State>
    <Title>Heart And Soul</Title>
    <Artist>Huey Lewis And The News</Artist>
    <Album>Sports</Album>
    <Genre>Unknown</Genre>
    <Theme>All Songs</Theme>
    <IDTheme>2</IDTheme>
    </Info>
    

    I >assume< each line in a response will have a carriage return, linefeed, or both at the end, although there's no guarantee. You'll either have to try it for yourself, or ask Russound T.S. If each line has a delimiter, you can pretty easily take an instance of:
    <Title>Heart And Soul</Title>
    
    and pretty easilly determine that that should go into a variable called (something along the lines of) "Title". If there's no delimiter, then you need to write some code that uses a lot of FIND_STRINGS for the tags and the "<" and ">" characters to pick stuff apart. Time consuming to write, but really not >that< scary.

    It looks like each <info> block starts with the stream number, so if you're dealing with the possibility of 2 or 3 streams, your parsing code can easilly keep track of which stream data is currently coming in by setting a flag any time it sees the <stream>x</stream> tags. I believe you can safely assume that any data that comes in is associated with the most recently reported stream.

    Kinda looks like fun to work with - wish I had one!

    - Chip
  • ipssheldonipssheldon Posts: 106
    Russound SMS-3

    Rolo,

    Did you get this working? I've got to develop a module for one of these as well. Curious to learn how well the controls worked out for you.

    TIA.

    Sheldon Samuels
    IPS Resources LLC
  • jjamesjjames Posts: 2,908
    To add a bit on the parsing of incoming XML data, I started to write an XML module based on what I have below. I started to work on the SMS3 for someone, though he never let me know if it worked or not. This was several months ago and as we well know, programming skills can change in a quick matter of time. (Which I feel mine has improved some in a few months)

    So here's some old code that if I had to do it again, I'd probably rewrite. Since I'll probably never use the SMS3 - someone do let me know if this works (even partially.)

    Snippet of attached code:
    // FIND STATE OF STREAM
    cSTATE[nCOUNTER] = REMOVE_STRING
    (	
    	cSMS3_BUFFER,	// REMOVE STRING FROM THIS VARIABLE
    	'</State>',		// REMOVE UP TO AND INCLUDING THIS STRING
    	FIND_STRING(cSMS3_BUFFER,'<State>',nSTREAM_POINTER)	// STARTING FROM HERE
    )
    REMOVE_STRING(cSTATE[nCOUNTER],'<State>',FIND_STRING(cSTATE[nCOUNTER],'<State>',1))
    REMOVE_STRING(cSTATE[nCOUNTER],'</State>',FIND_STRING(cSTATE[nCOUNTER],'</State>',1))
    

    Variables are explained in code.
  • viningvining Posts: 4,368
    The first thing that comes to mind would be in the string event to wait until you get the closing tag before calling in the parsing function (call).
    DATA_EVENT[dvSMS3]	// EVENTS FOR SMS3
         {
         STRING:		// EVENT TO PARSE STRINGS FROM SMS3
              {
              if (find_string(cSMS3_BUFFER,'</xml>',1))// what ever the closing tag is!
                   {     
    	       CALL 'PARSE SMS3'()
                   }
               }
         }
    

    Then once you have a complete file commence parsing. If the xml file is real long then I would probably pick at it by looking for individual tags like </Theme>, </Genre>, etc using a select active or switch case to list all possibities. But if your picking it a part I would remove and pass just that part of the received buffer string that's is prior to and including the find_string 'string' to the parsing function.

    The main thing is starting with complete file or portion of file then it's just parsing for what you want.
  • jjamesjjames Posts: 2,908
    I agree. I have no excuses for the poor code - I just agree. :D
  • DHawthorneDHawthorne Posts: 4,584
    For parsing XML, you can just use the ">" character for your delimiter, and break it into chunks with REMOVE_STING. If there is no "/" character present, it's a tag opening, if there is, it's a closing tag. If you have determined it's a closing tag, you can then break off everything after any "<" you find, and what's left will be your data.

    CHAR sBuffer[1024]
    CHAR sChunk[1024]
    CHAR sData[1024]

    sChunk = REMOVE_STRING(sBuffer, "'>'",1)

    So lets say you get a string like this:

    sChunk = <Title>Heart And Soul</Title>

    Your first REMOVE_STRING with "'>'" as an argument is going to give you "<Title>." There is no /, so you can store <Title> as your current tag type. The next REMOVE_STRING will net "Heart And Soul</Title>." Since you can find a / in there, you know the tag was closed, so you can do a subsequent:

    sData = REMOVE_STRING(sChunk, "'<'", 1) and sData will be "Heart And Soul<". Drop the < off the end, and store it; you've processed that tag.

    I've found in many cases, it's easier to just throw away the opening tag. When you detect a closing tag and break away the data, what's left will identify the type of tag it was, and you don't have to fuss over where the tag was - unless, of course, your XML format duplicates certain types of data tag names and you need a context from an enclosing tag. Much depends on the format of the XML.
  • jjamesjjames Posts: 2,908
    DHawthorne wrote:
    For parsing XML, you can just use the ">" character for your delimiter, and break it into chunks with REMOVE_STING . . . . .
    CHAR sBuffer[1024]
    CHAR sChunk[1024]
    CHAR sData[1024]

    sChunk = REMOVE_STRING(sBuffer, "'>'",1)

    So lets say you get a string like this:

    sChunk = <Title>Heart And Soul</Title>
    Question - how would you get <Title>Heart and Soul</Title> if you're looking for ">" from the beginning? You would get "<Title>" as sChunk . . . right?

    You need to know what you're parsing - as in which element you want. You just can't parse blindly and say an end delimeter is ">" because that could be either the closing sign for the opening element tag, or the closing of the closing element tag.

    Is there a faster way to parse an element with three REMOVE_STRING commands?
Sign In or Register to comment.