Remote LabVIEW call from Python
LabVIEW includes some native functions to interact with other programming languages. For example, it is possible to use Python Nodes to send data from LabVIEW to Python, call a Python function to perform calculations, and obtain the results in LabVIEW.
It is important to realize that, in this case, LabVIEW makes use of Python. But how about the other way around? Suppose that you would like to call LabVIEW functions in Python. How would you do that?
Actually, one of our customers wanted to find an answer to exactly that question. The customer’s engineers and scientists were more familiar with Python and other programming languages than LabVIEW. They daily had been using Python for data analysis and data processing. In addition, they decided to use LabVIEW for controlling hardware and acquiring measurement data. However, they wanted to use Python to also control the functionalities provided by LabVIEW.
The challenge lies in the fact that neither LabVIEW nor Python include native functions for doing that. Therefore, it would be necessary to develop your own code. Our customer initiated the development of the necessary code which we continued to develop and improve upon. These efforts resulted in a tool that we call the Remote LabVIEW Interface.
So, what is the Remote LabVIEW Interface?
In terms of computer software, an interface represents the shared boundary between two or more software applications across which they can exchange information. This means it enables the exchange of information between a LabVIEW application and an application written in another programming language, like Python or MATLAB. In addition, this could also be used as an interface between two or more LabVIEW applications. But in this context, the focus lies on the interface between LabVIEW and Python.
It is important to mention that at VI Technologies we make use of Object-Oriented Programming. For this reason, the Remote LabVIEW Interface was specifically designed to use LabVIEW classes and methods in Python. This also means that the tool itself consists of classes that can be divided into four task areas:
The following UML class diagram gives an overview of these classes and some important methods:
The Communication class forms the center of the Remote LabVIEW Interface. As its name already indicates, it is responsible for communication between LabVIEW and Python.
The Execute method runs a LabVIEW class method that is called in Python. Here are the steps involved:
- First, it receives a string input from Python which contains the class name, method name, and the values to be set for the method’s input controls.
- The Execute method uses the Serializer’s DeserializeMethod to separate this information.
- It calls the Executer’s GetInputType method to obtain the data types for the input controls.
- It then uses the Serializer’s DeserializeInputs method to format the input values and data types such that each input value is correctly matched with its corresponding data type.
- It now passes on all this information to the Executer’s DoExecute method which sets the values to the input controls and runs the method that should be executed.
- The DoExecute method returns possible output values of the executed method.
- The Execute method passes on the possible output values to the Serializer’s Serialize method which formats this information into a string output.
- The output string will be sent back to Python.
As previously mentioned, the Communication’s Execute method runs a LabVIEW class method that is called in Python. However, this requires that LabVIEW and Python can communicate with each other. In brief, Zero MQ is used as a messaging library to enable this kind of communication. The Remote LabVIEW Interface includes the ZeroMQ class, a child class of the Communication class, which makes use of the ZeroMQ Socket Library developed by Martijn Jasperse. For more information about that, check out a previous blog post about ZeroMQ.
LabVIEW natively includes the Flatten To JSON and Unflatten From JSON functions to make use of this data format. In addition, more sophisticated third-party tools are available, like the JSONtext library developed by James Powell. This library was wrapped into one of the JSON child classes.
As you might have guessed by its name, the Executer class is meant to run LabVIEW code. Its task is to run two different types of LabVIEW code:
- The LabVIEW class methods called by Python
- The Scripting class
Considering the first type of LabVIEW code, the DoExecute method is the most interesting one. As previously mentioned, this method is called by the Communication’s Execute method. It receives the class name, method name, and input values for the method to be called. It then sets the input values, runs the method, and gets the output values.
The key pieces for this method are the Set Control Values by Index and Get Control Values by Index functions. The first function sets the values to the input controls of a VI. The second function returns the output control, i.e. indicator, values. Note that the control indices are related to the order the controls were added to the VI and e.g. not how they are arranged in the VI terminal.
Considering the second type of LabVIEW code, the Executer class calls methods provided by the Scripting class. One example is the ScriptClass method which scripts a class including its methods.
Before you can actually use the Remote LabVIEW Interface, it is necessary to translate the LabVIEW classes and methods that should be able to be called from Python into Python code. This is what the Scripting class does. In brief, it converts all important information about a class and its method, including descriptions, into a string format that meets the criteria of written Python code, and saves the resulting code as a .py file. The LabVIEW code for doing that primarily consists of large structures for correctly formatting all information into strings. For example, the following screenshot gives an extract of the LabVIEW code used to format a LabVIEW class method into Python code.
But how to actually use the Remote LabVIEW Interface?
Let’s take a look at a simple example. Suppose that you created a LabVIEW class called “Calculations” which contains the method “Add”.
Further, assume that you would like to call this method in Python. The first step would be to create a VI that scripts the Calculations class and its methods, using the Executer class:
After running this VI, the Python file “labview_functions.py” is generated. This file includes several lines of code. The first two lines are used for importing JSON and Zero MQ:
Furthermore, the Python file includes, among other things, a class called “LabVIEWControl”. This was not previously mentioned, but it is necessary for calling LabVIEW class methods.
In addition, this file includes, of course, the code representing the Calculations class and its methods:
The second step would be to create a VI that makes use of all necessary classes. For this example, the VI should include the Zero MQ class for communication, the Executer class for executing the Calculations classes, and of course the Calculation class itself.
The third step would be to create a Python script that makes use of the code provided by “labview_functions.py”. An example of such a Python script is shown below. In this case, “Example.py” calls the “Add” method of the “Calculations” class to add 1 by 1. Note that both files need to be located in the same directory.
It is important to realize that the example VI which makes use of all necessary classes needs to be running while the Python code is executed. The final step would be to run the Python code. In this case, the result would look as follows:
The Remote LabVIEW Interface is a tool that allows the exchange of information between a LabVIEW application and applications written in other programming languages, such as Python or MATLAB. The tool was developed to call LabVIEW functions from Python. It consists of classes that are divided into four task areas: Serialization, Communication, Execution, and Scripting.
- The Communication class forms the center of the Remote LabVIEW Interface and is responsible for communication between LabVIEW and Python.
- The Serializer classes are responsible for translating the data into a format that can be transmitted between LabVIEW and Python.
- The Scripting class is used to script Python code to be used to call the LabVIEW code via the remote interface
- The Executer class’ task is to execute the LabVIEW code called via the remote interface.
The Remote LabVIEW Interface uses Object-Oriented Programming and Zero MQ as a messaging library to enable communication between LabVIEW and Python. The tool is an interface between LabVIEW and Python but could also be used as an interface between two or more LabVIEW applications.