Primary interface messages

Hello,

I would like to read messages from Primary Interface but the only things, that I seem to get are 1 Version message in the beginning and then only Robot State packages. There is occasional package of type 5, which is undocumented in the Client Interface excel file. Looks like it has something to do with Modbus, because it contains Modbus variable name and IP.
There are no other kind of messages. Am I doing something wrong here? I used code snippet posted by @ajp

#Establish connection to controller
HOST = '127.0.0.1'
PORT = 30001

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((HOST, PORT))

while 1:
    data = s.recv(4096)
    #initialise i to keep track of position in packet
    i = 0
    if data:
        #extract packet length, timestamp and packet type from start of packet and print to screen
        (packlen, packtype) =  struct.unpack(packageHeaderFmt, data[0:5])
        
        print datetime.datetime.now().time(), 'Package type/length: ' + str(packtype) + '/' + str(packlen)

My output when program is running is:

08:51:23.507757 Package type/length: 20/55
08:51:23.566580 Package type/length: 16/1350
08:51:23.666343 Package type/length: 16/680
08:51:23.769182 Package type/length: 16/680
08:51:23.871268 Package type/length: 16/680
08:51:23.973110 Package type/length: 16/680
08:51:24.074660 Package type/length: 16/680
08:51:24.175271 Package type/length: 16/680
08:51:24.276287 Package type/length: 16/680
08:51:24.296636 Package type/length: 5/58
08:51:24.383859 Package type/length: 16/680
08:51:24.482564 Package type/length: 16/680
08:51:24.584622 Package type/length: 16/680
08:51:24.685020 Package type/length: 16/680
08:51:24.782761 Package type/length: 16/680
08:51:24.886360 Package type/length: 16/680
08:51:24.984001 Package type/length: 16/680
08:51:25.087597 Package type/length: 16/680
08:51:25.186707 Package type/length: 16/680
08:51:25.290717 Package type/length: 16/680
08:51:25.391275 Package type/length: 16/680
08:51:25.489538 Package type/length: 16/680
08:51:25.591094 Package type/length: 16/680
08:51:25.691669 Package type/length: 16/680
08:51:25.795735 Package type/length: 16/680
08:51:25.896116 Package type/length: 16/680
08:51:25.997656 Package type/length: 16/680
08:51:26.098551 Package type/length: 16/680
08:51:26.201491 Package type/length: 16/680
08:51:26.220641 Package type/length: 5/58
08:51:26.303984 Package type/length: 16/680
08:51:26.404312 Package type/length: 16/680
08:51:26.506644 Package type/length: 16/680
08:51:26.605390 Package type/length: 16/680
08:51:26.705845 Package type/length: 16/680
08:51:26.807356 Package type/length: 16/680
08:51:26.910007 Package type/length: 16/680
08:51:27.010727 Package type/length: 16/680
08:51:27.111086 Package type/length: 16/680
08:51:27.210027 Package type/length: 16/680
08:51:27.313414 Package type/length: 16/680
08:51:27.413586 Package type/length: 16/680
08:51:27.520255 Package type/length: 16/680
08:51:27.546977 Package type/length: 5/58
08:51:27.621895 Package type/length: 16/680
08:51:27.722238 Package type/length: 16/680
08:51:27.822685 Package type/length: 16/680
08:51:27.923039 Package type/length: 16/680
08:51:28.025699 Package type/length: 16/680
08:51:28.127525 Package type/length: 16/680
08:51:28.226291 Package type/length: 16/680
08:51:28.329319 Package type/length: 16/680
08:51:28.426827 Package type/length: 16/680
08:51:28.527061 Package type/length: 16/680
08:51:28.627124 Package type/length: 16/680
08:51:28.727265 Package type/length: 16/680
08:51:28.827363 Package type/length: 16/680
08:51:28.927527 Package type/length: 16/680
08:51:29.027665 Package type/length: 16/680
08:51:29.127957 Package type/length: 16/680
08:51:29.227936 Package type/length: 16/680
08:51:29.328154 Package type/length: 16/680
08:51:29.428375 Package type/length: 16/680
08:51:29.528602 Package type/length: 16/680
08:51:29.628699 Package type/length: 16/680

I connected to real robot and looks like I get more messages.
Occasionally I get Label Message and Global Variables Update Message, but not as often as I should.

Hi @dozminkowski,

Apologies for the delayed response, have been on leave recently. What i see here is pretty much what I would expect from the primary interface, the additional primary messages (besides the standard ROBOT_STATE message that you get on the secondary) are only sent when something needs to be updated in Polyscope such as a variable value, or a label message showing the currently executing line of a program.

The MessageSources sheet in the Client Interface excel sheet shows that message type 5 is a MODBUS_INFO_MESSAGE (it’s fairly well hidden at the bottom).

What data are you looking to extract from this interface? Knowing that perhaps I can provide further pointers.

1 Like

Hello,

I hope you had nice holiday.

To be honest, I started my program this morning to check the output again and now it seems to receive many more messages. :thinking:
It doesn’t send every label message, but now it is consistent with behavior of Polyscope.
Last week I could tell, that I see much more happening in Polyscope, then what I was receiving in my script.

I am exploring the network interfaces to see what we can do with them. For example if we can react to events such as emergency stop, input activation, maybe robot being in certain zones. I know, that there are companies, that do it already, so I suppose it is feasible.

Could you elaborate on the contents of Modbus message?

Also GlobalVariablesUpdateMessage says “for each variable: (terminated with the \n character)”. So it looks like this:
char dataType | data | '\n' character | char dataType | data | '\n' character'. Can I do data.split('\n') on it and then inspect the contents? What if one of variables had something inside that looks like end of line character? That will ruin everything.
The only way to process it would be to read first char and then read the specific amount of data for that value type + 1 char for end of line. Is that right?

What is the purpose of unsigned short startIndex?

I know, that is a lot of questions, so thank you for your patience. :slight_smile:

Hi @dozminkowski,

I don’t have the specs for the Modbus message, but it will contain essentially contain all of the data that you see in Polyscope relating to Modbus signals, so variable value, response time etc.

So your GlobalVariablesSetupMessage will contain the names of all of the variables, and you then need to match them up with their values from the GlobalVariablesUpdateMessage. The startIndex value is usually 0 and I am fairly certain this will only be used when you have a very large number of variables in your program and so they can’t all be sent in one message, so allows you to again match them with the correct names.

I agree the best approach is the one you mention, checking the variable type and then incrementing the appropriate number of bytes to get to the next variable type. You’ll have to check the length of the variable also if it’s a string or list. I’ve tested it out with the integer values and it works nicely.

1 Like

Hello,

so I experimented a little with messages. My conclusions are, that these messages are not dependable. Label messages will come only if line of code takes a considerable amount of time. Otherwise they are skipped. I can not get GlobalVariableSetupMessage at the beginning of the program. All these Program state type: 1 is GlobalVariableUpdate which comes also when program is paused (??). Could variables be changing when program is paused? Notice also, that I delay creation of global program variables. I expect to see GlobalVariableSetup, but it does not come at all. I should see it more than once.

I do all this in simulator. Does it make a difference, if I start it on the robot?

Output of my program

Robot message type: 3 URControl 3.5.0.0 Build Date 14-11-2017, 18:47:56
Robot message type: 12 20 / 24 : RobotMessageHeader(timestamp=18446744073709551615L, source=-2, robotMessageType=12)
Robot message type: 7 Key code, arg, title, message 0 0 PROGRAM_XXX_STARTED blah
Robot message type: 1 Label 4 Wait: 3.0
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 0 / None
Type/Value: 0 / None
Type/Value: 0 / None
Robot message type: 1 Label 14 Waypoint_2
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / pongpong
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / True
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / pongpong
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / True
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / pongpong
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / True
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / pongpong
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / True
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / True
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / True
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / True
Robot message type: 1 Label 14 Waypoint_2
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False
Robot message type: 7 Key code, arg, title, message 0 0 PROGRAM_XXX_STOPPED blah
Program state type: 1
Type/Value: 14 / 333
Type/Value: 3 / z
Type/Value: 3 / ping
Type/Value: 5 / [(14, 10), (14, 20)]
Type/Value: 5 / [(14, 30), (14, 40)]
Type/Value: 12 / False

Program script
def blah():
  set_standard_analog_input_domain(0, 1)
  set_standard_analog_input_domain(1, 1)
  set_tool_analog_input_domain(0, 1)
  set_tool_analog_input_domain(1, 1)
  set_analog_outputdomain(0, 0)
  set_analog_outputdomain(1, 0)
  set_tool_voltage(0)
  set_input_actions_to_default()
  set_tcp(p[0.0,0.0,0.0,0.0,0.0,0.0])
  set_payload(0.0)
  set_gravity([0.0, 0.0, 9.82])
  global i_var_1=333
  global i_var_2="z"
  $ 2 "BeforeStart"
  $ 3 "sync()"
  sync()
  $ 4 "Wait: 3.0"
  sleep(3.0)
  while (True):
    $ 5 "Robot Program"
    $ 6 "MoveJ"
    $ 7 "Waypoint_1"
    movej([-1.6007002035724085, -1.7271001974688929, -2.2029998938189905, -0.8079999128924769, 1.5951000452041626, -0.03099996248354131], a=1.3962634015954636, v=1.0471975511965976)
    $ 8 "var_4≔'ping'"
    global var_4="ping"
    $ 9 "Wait: 1.0"
    sleep(1.0)
    $ 10 "var_1≔[10, 20]"
    global var_1=[10, 20]
    $ 11 "var_2≔[30, 40]"
    global var_2=[30, 40]
    $ 12 "var_3≔False"
    global var_3=False
    $ 13 "MoveJ"
    $ 14 "Waypoint_2"
    movej([-1.0911002035724078, -1.7271001974688929, -2.2029998938189905, -0.8079999128924769, 1.5951000452041626, -0.03099996248354131], a=1.3962634015954636, v=1.0471975511965976)
    $ 15 "var_1≔var_2"
    global var_1=var_2
    $ 16 "var_3≔True"
    global var_3=True
    $ 17 "var_4≔'pongpong'"
    global var_4="pongpong"
  end
end

Hi @dozminkowski,

I suppose that makes sense if you think about the original purpose of the label messages - if the line executes in a matter of milliseconds there’s not much point in sending a message to display it to the user.

I did have a python sample working in the simulator receiving variable setup names and update values… but it doesn’t seem to work now. Let me take a look at it when I get a chance and see if I can give you some useful info on that part.

1 Like

@ajp

Sure thing. Normally, we don’t need to see every label, but why are VariablesSetup dropped? VariablesUpdate on the other hand seems to be broadcasting like crazy. Not just after assignment to a variable, but every 1/10 of a second.

1 Like

Ok, so here is what I found.
Setup does not come whenever a new global variable is created.
It comes once, when I start a program. It knows not only about “official” variables created with assignment node, but also about those created in script node e.g. global a = 1. I also tried to hide it inside an if, but looks like Polyscope scans the whole code beforehand for global keyword.

Variable update, on the other hand, spams messages 10 times per second, regardless if they were changed.

Thank you @ajp for your assistance. :slight_smile:

Hello,

Thank you for your code. I am trying to understand your code. The packageHeaderFmt i am trying to debug. Can you please help me out with this
Thank you in advance

Hi dozminkowski,
I do not understand how to read the GlobalVariablesSetupMessage:

int messageSize
unsigned char messageType = MESSAGE_TYPE_PROGRAM_STATE_MESSAGE = 25
uint64_t timestamp
char robotMessageType = PROGRAM_STATE_MESSAGE_TYPE_GLOBAL_VARIABLES_SETUP = 0
uint16_t startIndex
charArray variableNames|List of names separated by new line character (’\n’ character). Example: var_1\nvar_2\n

It seems that I am not receiving the MESSAGE_TYPE_PROGRAM_STATE_MESSAGE = 25 and PROGRAM_STATE_MESSAGE_TYPE_GLOBAL_VARIABLES_SETUP = 0,
but only MESSAGE_TYPE_PROGRAM_STATE_MESSAGE = 25 and PROGRAM_STATE_MESSAGE_TYPE_GLOBAL_VARIABLES_SETUP = 1

Have you solved this issue?
Thank you in advance,
Edoardo

Hi,

unfortunately I haven’t done anything with UR for over 2 years. I remember I got it working, so it can be done.
Variables setup message was a list of names of variables. It was sent only when the robot program was started. When the program is running, you get only Variable update.

Update message contained pairs of <type, value> (I think). Based on the type you knew how many more bytes you need to read in and then convert them to said type. Rinse and repeat until the message is consumed whole.
Robot always sent you the whole list of values, even if they didn’t change. There were no names in UPDATE. You had to remember variable names from the SETUP message and match those two lists together (names and values).

I still come back here for nostalgia of memories how fun it was to explore robot interfaces. I hope you will have fun with them too. :wink:

Note that the current documentation sheets are not updated to the latest versions of robot/URSim software (3.14 for CB and 5.9 for e-Series).

With those versions they introduced the matrix variable type and so the ValueTypes sheet shows wrong numeric values for type byte. According to my experiments I found these number-type correspondence:

  • 3: string
  • 12: pose
  • 15: int
  • 16: float
  • 18: matrix

Try to experiment yourself to confirm these or to find out the others, until UR updates the sheets file.

Hi all,
Thank you very much for your replies.

Actually I can read the variable values, but not the variables setup message where in particular there is the fundamental information on the variableNames.
I do not receive that message neither at the beginning when I start the robot program…

I tested in several robot programs but without any success.

If you have any suggestion, please let me know.
Have a nice day,
Edoardo

Maybe you are reading the latest messages sent by the controller and you are skipping the first ones which contain that message.

PrimaryConnector.zip (6.5 KB)

I dug up my old source code. It is python 2 and worked with UR v.3. I am totally not up to date with UR these days.
I have no idea what I was thinking back then, so don’t ask me any questions. :smiley:

First you check what type of message it is…

while data:
        try:
            data = s.recv(4096*4)

            if data:
                #initialise i to keep track of position in packet
                i = 0
                while i+5 < len(data):
                    #extract packet length, timestamp and packet type from start of packet and print to screen
                    (length, type_) =  struct.unpack(packageHeaderFmt, data[i:i+5])
                    assert i + length <= len(data), '{}+{}<={}'.format(i, length, len(data))

                    package = packageFactory(type_, data[i+5:i+length])
       ...

and then process it according to its type.

def packageFactory(type_, content):
if type_ == 16:
    return RobotStatePackage(content)
elif type_ == 20:
    return RobotMessage(content)
elif type_ == 25:
    return ProgramState(content)
else:
    return None

What you are looking for @etrebalzini is in ProgramState.py module.

#!/usr/bin/env python

from collections import namedtuple, defaultdict
import struct

# Author: Daniel Ozminkowski

# PROGRAM_STATE_MESSAGE = 25

programStateMessageHeaderFmt = '!Qb'

ProgramStateMessageHeader = namedtuple("ProgramStateMessageHeader", "timestamp robotMessageType")

class ProgramState():
    '''
    Object decoding Program State messages from Primary Interface.
    '''

    variableNames = []
    variableValues = []
    

    def __init__(self, content):
        self.content = content
        self.type_ = None
        self.programRestarted = False
        self.updatedVariables = {}
        self.missedVariableSetup = False
        self.process()

    def process_setup(self):
        '''
        Decode variable names.
        '''
        self.type = 'setup'
        (startIndex, listOfVariables) = \
                         struct.unpack(
                             '!H'+ str(len(self.content)-9-2) + 's',
                             self.content[9:]
                             )
        listOfVariables = listOfVariables.split('\n')[:-1]
        
        # Assuming messages will just come in order
        # Not checking startIndex
        if startIndex == 0:
            self.programRestarted = True
            ProgramState.variableNames = []
            ProgramState.variableValues = []
        if startIndex >= len(ProgramState.variableNames):
            ProgramState.variableNames.extend(listOfVariables)
            ProgramState.variableValues.extend([None] * len(listOfVariables))

    def process_update(self):
        '''
        Decode new variable values.
        '''
        self.type_ = 'update'
        i = 9
        startIndex, = struct.unpack('!H', self.content[i:i+2])
        i += 2

        varNr = startIndex
        while i+1 < len(self.content):
            type_, value, size = self.__decodeTypeValue(self.content, i)
            i += size 
            if varNr >= len(ProgramState.variableValues):
                # Program was already started, but we didn't get the memo
                self.missedVariableSetup = True
                return
            if ProgramState.variableValues[varNr] != value:
                ProgramState.variableValues[varNr] = value
                self.updatedVariables[ProgramState.variableNames[varNr]] = value
            varNr +=1
            assert self.content[i] == '\n'
            i += 1
        
    def process(self):
        '''
        Check message type and call process_setup() or process_update().
        '''
        (timestamp, type_) = ProgramStateMessageHeader._make(
        struct.unpack(programStateMessageHeaderFmt, self.content[:9])
        )

        # Global variable setup
        if type_ == 0:
            self.process_setup()
            
        # Global variable update
        elif type_ == 1:
            self.process_update()
            
        else:
            print 'Unknown package. Package type/length:',  packtype, '/', packlen, \
              'msgType:', programStateMessageHeader.robotMessageType

    def __decodeTypeValue(self, data, i):
        '''
        Input parameters:
        data:  raw data received from UR
        i:     position where to start reading data
        Output parameters:
        type:  type of variable
        value: value
        size:  size of decoded data
        '''
        start_i = i
        variableType, = struct.unpack('!B', data[i])
        
        i+=1
        
        # None
        if variableType == 0:
            value = None
        # Constant string
        elif variableType == 3:
            length, = struct.unpack('!H', data[i:i+2])
            i+=2
            value, = struct.unpack('!'+str(length)+'s', data[i:i+length])
            i += length
        # Variable string
        elif variableType == 4:
            length, = struct.unpack('!H', data[i:i+2])
            i+=2
            value, = struct.unpack('!'+str(length)+'s', data[i:i+length])
            i += length
        # List
        elif variableType == 5:
            listLength, = struct.unpack('!H', data[i:i+2])
            i += 2
            list_ = [0] * listLength
            j = 0
            while j < listLength:
                itemType, itemValue, itemSize = self.__decodeTypeValue(data, i)
                i += itemSize
                list_[j] = itemValue
                j += 1
            value = list_
        # Pose
        elif variableType == 10:
            value = struct.unpack('!ffffff', data[i:i+24])
            i += 6*4
        # Bool
        elif variableType == 12:
            value, = struct.unpack('!?', data[i:i+1])
            i += 1
        # Num
        elif variableType == 13:
            #print len(data[i:])
            #print [ str(ord(ch)) for ch in globalVariableUpdatePayload ]
            exit()
        # Integer
        elif variableType == 14:
            value, = struct.unpack('!i', data[i:i+4])
            i += 4
        # Float
        elif variableType == 15:
            value,  = struct.unpack('!f', data[i:i+4])
            i += 4
        else:
            print 'Unknown data type in GlobalVariableUpdateMessage'
        
        return variableType, value, i-start_i

Thank you for your replies, suggestions and code.

I hope to solve this issue ASAP
:smiley:

Thanks for your code @dozminkowski . I am using that I can unpack first packet of type 20 and message type is 3(version) but I can’t unpack second packet of 20 because its message type is 12 that is no defined in primary Interface sheet .