LabVIEW Development Best Practices Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Messenger Library Actor Extensibility

I have been tyring out the drjdpowell Messenger Library https://lavag.org/files/file/220-messenger-library/.  The videos on how to use it are very helpful along with the included examples.

One thing that is bothering me is how to extend an actor.  For example, say I have a basic Temperature controller.  I can overide Actor.vi and create some messages and events.  How can this be extended to something like a TemperatureWithAutotune controller?  Of course I can inherit from Temperature, but it seems like I would need to recreate all of the messages and events in the new Actor.vi, and then add a few more.  Am I missing a more obvious way where I can reuse instead of replicate the original messages? 

0 Kudos
Message 1 of 10
(8,701 Views)

In Messenger Library, the "Actor" class objects are actually analogous to the "Enqueuer" object in the Actor Framework: it's the "address" or way of sending messages to the actor process.  The "Actor" object in the AF is serving as the internal state data of the actor process.   I don't build such a thing into my standard templates because I think such objects are often better not tied directly to the actor itself.   For example, your PID control actor doesn't just have to extend its control method to autotuning; you also have multiple potential output types (AO, pulse-width modulation, simple software-timed on-off) and multiple possible inputs (Temperature, Pressure, flow, etc.).   So you would be better off with independent class hierarchies for "Control Strategy", "Output", "Input", etc. that you can inherit off separately.  Note that these more-focused classes may be more reusable.  Your "Data Acq Actor" can reuse the "Input" class, for example.  Your "Multi-zone Furnace" actor might use arrays of Input and Output objects allong with an entirely different multi-zone control method.

Here is a screen shot of an actor that "augments" a graph with added functionality.  It, itself, does little more than register for graph UI events and call methods on a parent "Graph Augment" object (including a method to handle any extra messages it receives, called in the default case).   Child classes of "Graph Augment" override these methods, and the child objects are pre-configured before starting the actor.   This is very similar to how AF "Actor" object can be pre-configured.

Actor for Graph Augment.png

There are currently three different children of "Graph Augment", but they all run in the same type of "actor".

Graph Augment Inheritance.png

Message 2 of 10
(7,528 Views)

You make some great points.  I will explore some of the techniques you described and see how I can use them best in my project. 

This is a great library, I appreciate that you provided it to the community.  Looking forward to some more great tutorial videos...

0 Kudos
Message 3 of 10
(7,528 Views)

Hi:

I agree that the messenger library is very interesting and powerful. I am trying to learn better its functionalities and I wonder if there is a way to connect with an external program via a TCP connection, for instance.

If I have understood correctly the library (I have been playing with it very recently),  the server presents "services" which can be seen by other Vis (clients). Is it possible to get those services from code outside LabVIEW?

Thank you in advance

josu

0 Kudos
Message 4 of 10
(7,528 Views)

josujugo wrote:

I am trying to learn better its functionalities and I wonder if there is a way to connect with an external program via a TCP connection, for instance.

If I have understood correctly the library (I have been playing with it very recently),  the server presents "services" which can be seen by other Vis (clients). Is it possible to get those services from code outside LabVIEW?

Are you talking about the "TCP Messenger" stuff?  That isn't designed for communication outside the library; instead it supports Request-Reply and Register-Notify between Messenger-Library code on different computers.   But the user monzue on LAVA did show me how he had made modified versions the TCP actors to communicate with non-LabVIEW programs.  You might want to message him on LAVA. 

Actually, I just remembered some prototype code intended to talk to another program by another developer.  Unfinished, but I think I used the JSON library from the LAVA Code Repository to use JSON as an interchange format (JSON is a standard widely available in multiple languages).

0 Kudos
Message 5 of 10
(7,528 Views)

Ok, thank you very much for the reply. I will try to contact with monzue to obtain some clue about that solution.

On the other, I agree that JSON library is a good option for me.

Thanks!

Best regards

josu

0 Kudos
Message 6 of 10
(7,528 Views)

@drjdpowell wrote:

In Messenger Library, the "Actor" class objects are actually analogous to the "Enqueuer" object in the Actor Framework: it's the "address" or way of sending messages to the actor process.  The "Actor" object in the AF is serving as the internal state data of the actor process.   I don't build such a thing into my standard templates because I think such objects are often better not tied directly to the actor itself. 

 

Could you possibly elaborate on this? I'm pretty new to AF and have only glanced at Messenger Library and struggling to understand the implications of the differences here. The difference I see is that in AF, the class data is accessible through the wire (e.g. before launch), whereas Messenger Library it is totally hidden in Actor.vi.

 


@drjdpowell wrote:

Here is a screen shot of an actor that "augments" a graph with added functionality.  It, itself, does little more than register for graph UI events and call methods on a parent "Graph Augment" object (including a method to handle any extra messages it receives, called in the default case).   Child classes of "Graph Augment" override these methods, and the child objects are pre-configured before starting the actor.   This is very similar to how AF "Actor" object can be pre-configured.

 

Actor for Graph Augment.png

 

There are currently three different children of "Graph Augment", but they all run in the same type of "actor".

Graph Augment Inheritance.png


 These augmented graphs look fantastic. Is there any possibility of this code ever being public?

While I am posting, this is a topic that probably deserves it's own thread, but I just want to tack it on here while I am at it. In the Messenger Library videos and example you use string constants to define the messages. This is significantly different from the class/vi heavy approach of the AF.

Do you accept the responsibility that comes with maintaining the strings since an actor should be a well defined, closed unit that shouldn't change? I would be worried about changing an internal method and having to hunt down all the instances of sending the message. Would you recommend making subclasses of messages with the message command hardcoded, so any changes are maintained throughout the code?

I just want to add, thanks for the work you've put into offering such a well thought out package to the community. I really like the observer registry system and it is one of my main draws to consider Messenger Library over AF. I got quite used to such behavior from using 'signals' with Qt stuff I was doing for a private project a while ago.

0 Kudos
Message 7 of 10
(6,380 Views)

I posted the "Graph Augment" stuff on LAVA a while back.  It's an example of how one can do advanced OOP stuff with Messenger Library, including configuring an object before setting it off running in its own "actor" (like in the AF) and having child-class inheritance.  However, I hesitate to demonstrate these things as I don't want to give the impression that Messenger Library requires one to be an OOP wiz.   Messenger Library should be usable in a wide variety of ways and levels of sophistication, which is why I called it a "library" rather than a "framework".   

Message 8 of 10
(6,367 Views)

 wrote:
While I am posting, this is a topic that probably deserves it's own thread, but I just want to tack it on here while I am at it. In the Messenger Library videos and example you use string constants to define the messages. This is significantly different from the class/vi heavy approach of the AF.

Do you accept the responsibility that comes with maintaining the strings since an actor should be a well defined, closed unit that shouldn't change? I would be worried about changing an internal method and having to hunt down all the instances of sending the message. Would you recommend making subclasses of messages with the message command hardcoded, so any changes are maintained throughout the code?

In practice, I don't find hardcoded strings a particular problem.  The "relabelling" and other features of the "Observer Addresses" in Messenger Library mean that all my messages names are very "natural" and make sense in both the context of the sender and receiver.   So, for example, a Temperature Controller would publish a "Temperature (degC)" message, but the Caller might relabel the message as "Main Furnace-->Temperature".  There's not a lot of message reworking needed if you can define them naturally the first time.  Also, I tend to favor simple messages containing only one thing (and the natural thing; you can easily guess what data the "Temperature (degC)" message carries).  

 

However, if your actor is going to be used in many places, you can write an "API" for it.  Rather than message subclasses, I would just create subVIs.  These can either be method of the Actor (address class) or an independent set of subVIs.  The "Metronome" actor (under the "Useful Actors" menu) has a couple of such subVIs, including "Start Metronome":

Start Metronome.png

 

Another trick is to make the message-label strings unique, so one can use Find and Find-Replace to identify all of them.  This does lead to annoyingly long message labels, though.

0 Kudos
Message 9 of 10
(6,362 Views)

@drjdpowell wrote:

However, I hesitate to demonstrate these things as I don't want to give the impression that Messenger Library requires one to be an OOP wiz.   Messenger Library should be usable in a wide variety of ways and levels of sophistication, which is why I called it a "library" rather than a "framework".   


If I can elaborate on this, I don't just mean that Messenger Library should work for programmers without the experience to handle OOP-heavy design.   I also mean that any programmer may want to use it in different ways for different things.  My "Graph Augments" are trying to be extendable using LVOOP, but my applications written for clients are more intended to be quick to write and easy to rework (rather than being extendable without modification).  And I still have reasons to have very simple code, such as with Unit Testing, where I need to test a (more complex) actor's proper handling of messages.   Here is part of a Unit Test of a Modbus TCP Server actor, where I have a very simple "simulated Device" loop to reply to control messages with dummy data:

Simple Loop in Unit Test Harness.png

Message 10 of 10
(6,353 Views)