Home AMX User Forum NetLinx Studio

I need to proccess a answer from device.

Hello, here I'm again making questions :$

The device sends for example:

ID01,F23,NB07□ID99,F14,NC06,ST01□□ID01,F02,ST00000010□ID02,F02,ST00110101□ etc etc

I need to divide this answer, like:

Device1 = ID01,F02,ST00000010
Device2 = ID02,F02,ST00110101
.
.
.
Device15=ID15,F02,ST01110101

Thanks!!

Comments

  • yuriyuri Posts: 861
    DEFINE_FUNCTION fnParseDevice(CHAR buffer[1024])
    {
        (* device name *)
        strDevice[i] = "REMOVE_STRING(buffer, "$7F", 1)"
        (* remove the appending $7F *)
        SET_LENGTH_STRING(strDevice[i], (LENGTH_STRING(strDevice[i]) - 1))
    
        (* check if we reached the end *)
        IF(i < nMaxDevices)
        {
    	i++
            (* do it again *)
    	fnParseSongs(buffer)
        }
    }
    

    something like that should work :)
  • jjamesjjames Posts: 2,908
    Yuri's way may work (I've never tested anything like that), but when parsing feedback, I prefer to keep it in the STRING section of the DEFINE_DATA for the device. So, I personally would do something like this, thus buffering while parsing as well. I don't have any code of mine to look at off the top of my head to give you a real example, but I use this structure of parsing with every device. You can change what it's looking for, so if your device ends with a line feed or a carriage return, just pop that in.

    Hope this helps!
    http://amx.com/techsupport/techNote.asp?id=616
  • 2Fast2Fast Posts: 90
    Thanks a lot!!!
  • DHawthorneDHawthorne Posts: 4,584
    jjames wrote: »
    Yuri's way may work (I've never tested anything like that), but when parsing feedback, I prefer to keep it in the STRING section of the DEFINE_DATA for the device. So, I personally would do something like this, thus buffering while parsing as well. I don't have any code of mine to look at off the top of my head to give you a real example, but I use this structure of parsing with every device. You can change what it's looking for, so if your device ends with a line feed or a carriage return, just pop that in.

    Hope this helps!
    http://amx.com/techsupport/techNote.asp?id=616

    The STRING section of a physical device is not very reliable. It's fine for inter-system communications, like between main code and modules, or virtuals, or master-to-master. However, a real device might pause a few milliseconds too much mid-string, and the STRING handler will see that as the entire string. If it doesn't pause enough between strings (and you can't set this interval), it may lump more than a full string together in one event. For those reasons, I prefer to use a buffer for real devices.
  • jjamesjjames Posts: 2,908
    Yes, but it's being buffered in the STRING section. I've never had a problem using this method. Looking at some of my OLD code that didn't use this method, I can recall having issues, but since I've used this - not once.
  • AMXJeffAMXJeff Posts: 450
    When parsing Buffers from IP or Serial devices, AMX recommends using Create_Buffer and parsing the data in the STRING section of the Data_Event, DATA.TEXT should not be used. When Parsing from Virtual with send_strings and send_commands, DATA.TEXT is guaranteed to have one message and the complete message.
  • viningvining Posts: 4,368
    I still handle inbound strings both ways but handling strings outside the Data_Event String handler as Dave mentioned is probably more reliable and does have added benefits.

    If you take the code out of the handler you can almost always remove a while statement since the code wil be evaluated on every pass to see if a certain condiiton is true. On the down side since it is not event driven it will be evaluated and evaluated and evaluated on every pass of the mainline.

    In the example below the code in the string handler needs a while loop to test for every possible complete parsable section of code otherwise you'll end up with un processed data and the data remaining in the buffer will get processed at a later time when the event is triggered again, second, minutes or days later. Not good! The code in the main program will check the buffer for a complete section on every pass. Now depending on how busy the system is the 2nd method will probably take longer to completely process.

    If you do process strings in the event handler and test for completeness before processing I don't think there should be a problem since in the event if a complete string isn't received if won't be processed and when the remainder of the string does arrive another event will be triggered and you'll test for completeness again.

    There appears to be pros & cons to either method and depending on where my head is at on any particular day I'll use one or the other.
    DATA_EVENT [dvXM]
         
         {
         ONLINE:
    	  {
    	  //online stuff
    	  }
         STRING:
    	  {
    	  STACK_VAR CHAR cTempSTR[255] ;
    	  
    	  if (nXM_DeBug)
    	       {
    	       SEND_STRING 0,"'cXM_Buff rcvd from device -> ',cXM_Buff,' <-Line-<',ITOA(__LINE__),'>',CRLF" ;
    	       }
    	  if (find_string(cXM_Buff,"CRLF",1))
    	       {
    	       while (find_string(cXM_Buff,"CRLF",1))
    		    {
    		    fnXM_ParseBuffer(remove_string(cXM_Buff,"CRLF",1)) ;
    		    }
    	       }
    	  }
         } 
    
    DEFINE_PROGRAM     
     
         {
         if (find_string(cXM_Buff,"CRLF",1))
    	  {
    	  if (nXM_DeBug)
    	       {
    	       SEND_STRING 0,"'cXM_Buff rcvd from device -> ',cXM_Buff,' <-Line-<',ITOA(__LINE__),'>',CRLF" ;
    	       }
    	  fnXM_ParseBuffer(remove_string(cXM_Buff,"CRLF",1)) ;
    	  }
         } 
    
  • yuriyuri Posts: 861
    jjames wrote: »
    Yuri's way may work (I've never tested anything like that), but when parsing feedback, I prefer to keep it in the STRING section of the DEFINE_DATA for the device. So, I personally would do something like this, thus buffering while parsing as well. I don't have any code of mine to look at off the top of my head to give you a real example, but I use this structure of parsing with every device. You can change what it's looking for, so if your device ends with a line feed or a carriage return, just pop that in.

    Hope this helps!
    http://amx.com/techsupport/techNote.asp?id=616

    this code works, i've tested it in the field.
    I use a buffer because the string that came from the device was way long, and was sent at short intervals. So i first populated the buffer with the exact string i wanted (header + data + checksum + footer) and then processed the buffer.
    When i didn't receive a correct string, i didn't do any buffer processing and just requested the data again. :)
  • AMXJeffAMXJeff Posts: 450
    vining wrote: »
    I still handle inbound strings both ways but handling strings outside the Data_Event String handler as Dave mentioned is probably more reliable and does have added benefits.

    Vining,

    I aggree either method is fine. Just so you know the "if" is redundant in your code, when using the while loop. The while loop acts like an if....
    	  if (find_string(cXM_Buff,"CRLF",1))
    	       {
    	       while (find_string(cXM_Buff,"CRLF",1))
    
  • viningvining Posts: 4,368
    AMXJeff wrote:
    Just so you know the "if" is redundant in your code, when using the while loop.

    Yep I knew that, I was hoping nobody noticed.
  • yuriyuri Posts: 861
    vining wrote: »
    AMXJeff wrote:


    Yep I knew that, I was hoping nobody noticed.

    <- laughed out loud :)
Sign In or Register to comment.