Jump to content

Does anyone know how to generate a user event from Python code?


Recommended Posts

Argold,

As I mentioned in your previous post, there are a couple of ways to go about this, but there's no magic command in Python that will trigger a LabVIEW event. Your best bet is to create a TCP server in LabVIEW then connect to that server with Python. I attached a quick and dirty example (LV 2015). Run the LabVIEW code first, then run the Python file. The LV code will read the message one byte at a time.

Now that you've got Python and LabVIEW connected, you've got your work cut out for you to make it more robust and full featured so it works for your application.

client.py

Simple TCP - Server.vi

Link to comment

You can call the "PostLVUserEvent" in the functions exported by the LabVIEW executable. 

The C prototype is in <LabVIEW Version>\cintools\extcode.h so you can see what parms you need.

TH_REENTRANT EXTERNC MgErr _FUNCC PostLVUserEvent(LVUserEventRef ref, void *data);

 

Link to comment

Here's a version that should work in 2014. I started with the LabVIEW TCP server example. Note that it's reading one byte at a time which is probably not how you would implement this in your application. If your messages from Python were terminated with CRLF then you can configure the TCP Read Function in LabVIEW to read until it sees the terminator character.

Simple Server-14.vi

Link to comment

BTW, while ShaunR did answer your exact question, I think you're going to hit a dead end pretty quickly if you try to go down that path. Notice one of the arguments required for that function is the user event ref. Since those references change every time you start your LabVIEW application you're going to have to first pass those references out of your LabVIEW application so that you know what to call from external code.

If you know how to generate a user event, then you've already got everything figured out.

Your Python code can send strings via TCP:  command1, command2, command3.

Your LabVIEW code can receive those strings to control a case structure. Each case fires a different user event.

Link to comment
1 minute ago, planet581g said:

...Since those references change every time you start your LabVIEW application you're going to have to first pass those references out of your LabVIEW application so that you know what to call from external code.

(...)

Your LabVIEW code can receive those strings to control a case structure. Each case fires a different user event.

I don't see how getting the reference from LV each run would be a problem.  The communications would need to be two-way but they need to be anyway, so it should be do-able.

What you suggest about passing strings to LV is what a wrapper for the clonable modules would need to do.  Again, I'm looking for a solution where I can use the modules pretty much as designed (much more elegant and does not break the way they are already used within a LV framework).  I'm still hoping it can be done, and thank's for all your advice so far, Eric.

Link to comment

I guess I'd need to see your code. Are your modules simply VIs that you call? If that's the case, you don't need to user events at all. Just stick each module in a different case of your case structure then send the correct string: module1, module2, module3. There's less work involved in doing that than there is in sticking each of those modules in an event structure.

I wish ShaunR would chime in and try to dissuade you from going down the path of trying to call into the EXE using references since I doubt he would try to solve the problem that way. He was just providing you with an explicit answer to your exact question. I doubt he would suggest doing that if he were considering the bigger picture of what you are trying to accomplish.

Eric

Link to comment
21 hours ago, ShaunR said:

You can call the "PostLVUserEvent" in the functions exported by the LabVIEW executable. 

The C prototype is in <LabVIEW Version>\cintools\extcode.h so you can see what parms you need.


TH_REENTRANT EXTERNC MgErr _FUNCC PostLVUserEvent(LVUserEventRef ref, void *data);

 

 

So i did a little searching down this path, and it does look like you can make calls to/from Python via LabWindows/CVI.  However I do not have that (yet) and wonder if I need to get it.  I'm thinking instead if there is a similar thing like a PVI" that anyone has thought about...

 

This actually looks promising: http://www.ni.com/white-paper/8911/en/  It talks about calling C-style DLL's from Scripts..

Edited by Argold
Link to comment

The PostLVUserEvent function exists so that LabVIEW can call a function in a DLL that will trigger a user event. For example, if you are trying to use a DLL that requires a callback, you can create a callback function (in C or similar) that generates a user event, and pass that function as the callback to the DLL. Then, when the callback is triggered, a user event is generated.

As I understand it, what you're trying to do here is have Python make the initial call to LabVIEW, rather than a LabVIEW application making a call to an external DLL. Is that correct? If so, your Python code and your LabVIEW code are two separate processes (in the operating system sense of the word) and you won't be able to have one of them call a function in the other one (ie, you can't have Python call a function inside the LabVIEW process). You need some intermediate inter-process communication layer, such as TCP as already suggested (if everything is running on the same computer I'd vote for UDP instead since it's faster and simpler and you won't lose packets over a loopback interface).

Link to comment
2 hours ago, Argold said:

 

So i did a little searching down this path, and it does look like you can make calls to/from Python via LabWindows/CVI.  However I do not have that (yet) and wonder if I need to get it.  I'm thinking instead if there is a similar thing like a PVI" that anyone has thought about...

 

This actually looks promising: http://www.ni.com/white-paper/8911/en/  It talks about calling C-style DLL's from Scripts..

I can only echo neds remarks. Calling any of the LabVIEW manager functions from a different process than LabVIEW itself is doomed to fail. If you wanted to call this function through the Python ctypes interface, the according Python interpreter has to run inside the LabVIEW process, just as what LabPython attempts to do.

Trying to do that from a seperate Python execution interpreter is doomed without proper interprocess communication like through nanomsg, ZeroMQ or your own TCP/IP, UDP deamon.

This is no fault of LabVIEW or Python but simply proper process separation through protected mode memory and similar involved techniques, fully in effect since Windows NT.

Edited by rolfk
Link to comment
2 hours ago, rolfk said:

I can only echo neds remarks. Calling any of the LabVIEW manager functions from a different process than LabVIEW itself is doomed to fail. If you wanted to call this function through the Python ctypes interface, the according Python interpreter has to run inside the LabVIEW process, just as what LabPython attempts to do.

Trying to do that from a seperate Python execution interpreter is doomed without proper interprocess communication like through nanomsg, ZeroMQ or your own TCP/IP, UDP deamon.

This is no fault of LabVIEW or Python but simply proper process separation through protected mode memory and similar involved techniques, fully in effect since Windows NT.

Doesn't LabPython run from within the LabVIEW process?

Link to comment
On 1/7/2017 at 2:25 AM, ShaunR said:

Doesn't LabPython run from within the LabVIEW process?

Of course. I never said otherwise. But we were not really discussing LabPython at this point since it has quite a few issues that would require some serious investment into the code. The solutions we were discussing where more along the lines of running Python in its own process and communicate between Python and LabVIEW through some means of interapplication communication like nanomsg, Zeromq or a custom made TCP/IP or UDP server client communication scheme.

Refer to this post for a list of problems that I'm aware of for the current version of LabPython.

Link to comment
12 hours ago, rolfk said:

Of course. I never said otherwise.

Right. ;)

12 hours ago, rolfk said:

But we were not really discussing LabPython at this point since it has quite a few issues that would require some serious investment into the code.

Are you saying no-one should be using it at all? Using Python 2.3 should be OK, yes?

12 hours ago, rolfk said:

The solutions we were discussing where more along the lines of running Python in its own process and communicate between Python and LabVIEW through some means of interapplication communication like nanomsg, Zeromq or a custom made TCP/IP or UDP server client communication scheme.

All this is basically saying "you can't" to the original question and "here are some alternatives". But the OP wants to generate a LabVIEW event with Python. I don't like changing the requirements to fit the code.

However. Saying that. I could knock up the TCPIP in a few minutes in LabVIEW by just wrapping the generate event primitive ..... so I can see the appeal.

Link to comment
9 hours ago, ShaunR said:

Right. ;)

Are you saying no-one should be using it at all? Using Python 2.3 should be OK, yes?

Well Python 2.3 should be indeed ok, although I never tested with numpy and similar in that version. But that is so old, it's like requiring people to work with Linux 2.2 kernels or Windows 2000.

Quote

All this is basically saying "you can't" to the original question and "here are some alternatives". But the OP wants to generate a LabVIEW event with Python. I don't like changing the requirements to fit the code.

However. Saying that. I could knock up the TCPIP in a few minutes in LabVIEW by just wrapping the generate event primitive ..... so I can see the appeal.

Right! You can spend many man hours to get LabPython working correctly with current version, quite a few more man hours to get the PostLVUserEvent() working as well (it's asynchronous operation and while no rocket science really, involved enough that I have to wrap my mind around it every time again, when trying to implement it somewhere).

Or you implement a client server RPC scheme in LabVIEW and Python and just pass around the information that way. The second is a lot easier, easily expandable by other people with absolutely no c knowledge, and much easier to debug too.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.