Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Configuring an actor to forward a message

Hello all,

Thought I would throw this out for discussion to see if anyone had any thoughts on this.  I have run into a couple of problems in a large application that I am putting together.  One of these problems involves how to handle the case where data collected by one actor is required by another.  This is further complicated by the fact that several devices may provide the same data and I would like the user to be able to select this via a configuration file.

So, here is the architecture in a nutshell - I have a controller actor in an embedded system that can launch a rather large array of devices/instruments depending on system configuration.  The number of devices and the method of communication is governed by the configuration file.  For the most part, these devices are independent and data is sent from each device to the controller and aggregated by the controller for file writing and display by the UI (its a little more complicated than this, but this is a simple description).  However, there are two instruments launched by the controller that actually require some of these measurements to complete data processing and make future decisions (i.e. it is not sufficient to just do the calculations at the controller level).  AND, multiple devices may be able to provide this information.

My question here is - does anyone have any thoughts about how to tell a device to send a specific message? (Actually, what I think will be happening is that the message from the device containing the device data will also contain a message to forward from the controller to the instrument that requires a subset of that data).

Cheers, Matt

0 Kudos
Message 1 of 8
(5,622 Views)

Hi Matt, any chance you could do a simple block diagram that shows the relevant actors/messages in your system? I've been playing around with code that may be close to what you're looking for, but I can't quite understand your system.

For example, something I've been doing as standard lately for reply messages is to embed the Reply Enqueuer and Reply Msg Type in the Send Msg, see below. (Internally in "Send request- I2C Transaction.vi" I bundle up the message details cluster and data cluster into the Msg object). This may be similar to what you're looking for? This is probably just an example of loose/zero coupling though, so maybe you've already tried something similar.

Send Message with Embedded Reply Details.jpg

0 Kudos
Message 2 of 8
(4,445 Views)

Matt,

I think you need to use "Zero Coupled" messages for your devices.

https://decibel.ni.com/content/message/41428#41428

Here is a description with images of code that I wrote a while back:

https://decibel.ni.com/content/thread/27543?tstart=0

When you launch a device as a nested actor you can tell it reply with "Child Message A" or reply with "Child Message B". Those child messages can put the data in different places.

In my opinion, this method of messaging is central to AF and you must employ it.

After you look at those other threads let me know if you have any questions.

Casey

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

0 Kudos
Message 3 of 8
(4,445 Views)

A second answer...

I would consider using an intermediate actor between the controller level and the device level in the case of needing data from multiple devices to make one "Virtual Instrument". An example from my project is needing two thermocouples and a flow meter to calculate the heat load in a virtual calorimeter. My controller launches a calorimeter which launches two thermocouples (TC) and a flow meter.

The controller doesn't know about the TCs or the flow meter it only knows about a calorimeter.

Additionally, each TC is given a different "Child Message" to reply with, one gets the "Upstream TC" message and the other gets the "Downstream TC" message.

As a further detail I do have several places where the controller does just use a TC. A TC can be used by anything that needs one. The reuse comes from the fact that the TC doesn't know what launched it or what the child message is. It only knows the Enqueuer for its caller and the parent message type.

Casey

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

0 Kudos
Message 4 of 8
(4,445 Views)

Interesting, I do something similar where I have an I2C Adapter at the lowest level, and I have "virtual" I2C devices as intermediate actors, which take commands (messages) from a higher-level actor and convert them to byte form to send as messages to the I2C adapter actor. But a higher level GUI or test program actor could also communicate directly with the I2C adapter actor if it wanted to (it creates both the I2C adapter and the intermediate actors, so it has direct access to the I2C adapter if it wants). Also, my system is inverted in comparison to yours in that I only need one I2C adapter but I can have as many virtual intermediate I2C devices as I want (up to the I2C protocol limit, at least).

0 Kudos
Message 5 of 8
(4,445 Views)

Hey Casey,

This was actually what I originally was shooting for.  The question was not how, but how do you tell which device is the correct one to send the message using a configuration file (i.e. the user wants to select a particular device to get the data).

Now, all of that being said, I realized a couple of things after I sent this message.  First, there are several ways to approach this.  The device data message can encapsulate a message to forward and the controller can forward that message when it handles the original data message.  This was my original thinking.  Another way to do this is to have the device interested in the data send a self addressed message requesting it.

But then, I realized that the AF has me waaaaaay overthinking this.  And I suspect I am not the only one to be dazzled by it.  In my system, I generally make a distinction between a device which encapsulates a set of measurements that are not dependent on any externals and an instrument which will likely depend on outside data is central to the system.  Its a weak distinction, but it helps me keep things straight. In this case, this instrument desires data from outside sources (flow meters and pressure transducers).  This instrument itself is so central that it is unlikely the system will run without it (in fact, there is not switch in the configuration file to NOT run it).  So, in order to maximize the configurability I decided to create a map using variant attributes that associate device data with an ID.  In the configuration file, you can map the measurement desired to a device ID.

This also addressed another issue I was facing - how to handle whether an actor was active in the system.  In my system, I use the Last Ack to shutdown the system.  When an external signal is sent to stop the system, the controller send the call out to all devices to stop.  As the Last Acks are handled, the different actors are removed from the list of active actors and when the last nested  actor is no longer active the system shuts down. 

Now, given that all of my devices are actors, I can use the IDs of the actors to also map the enqueuers..  When the last ack is handled, we use the ID (stored in the actor) to get the variant atribute containing the enqueuer data and remove the one of interest from the system.  Prior to this, I was checking enqueuers to find the one of interest and the logic was getting silly.  So now, using a map, I think I have killed two birds with one stone.

And that was likely clear as mud.

Cheers, Matt

Message 6 of 8
(4,445 Views)

I suspect that here in your example, the calorimeter is a natural grouping of measurements (at least I would hope so).  That might make sense, but often I have devices that do not naturally fit into a group and the addition of a mid-level actor just introduces unnecessary complexity.

0 Kudos
Message 7 of 8
(4,445 Views)

Here is something to consider...

The controller is launched. Controller reads the config. It launches nested device actors but doesn't give them a reply message. Have a conditional boolean in your device actors for whether the child reply message is set. Initial value is false. At this point the device actors are running but not sending messages.

Launch the UI. Send a config message from the Controller to the UI with the available devices. UI knows how to parse this message and present options for the user to select.

User selection of which device to use where sends a message to the controller. This in turn sends a message to each device that could be used in a number of location the type of child message to send this run. You will need a message to the device that is something like "Set Device Child Message" and the data type is the parent message class and you write a child class when the user makes the UI selection. You also set the conditional boolean for sending the message to true when the device receives the Device Child Message.

C

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

0 Kudos
Message 8 of 8
(4,445 Views)