Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple Hardware Resources On Same Communication Bus

I am developing an Actor Framework based application that sometimes needs access to hardware resources.  For now, I will just keep it simple and say that the application (on a laptop) needs to monitoring temperature in 1 or more machines.  The application would maintain the communication and always attempt to initialize or recover without operator intervention.  A system configuration would say how many channels and where they are.  The application would be able to scale up or down.

This all sounds resonable, but I am hung up on one issue.  I would like to just create a temperature class and spin one up for every channel.  The problem is that I am talking to multi-channel temperature controllers over Modbus and/or Modbus/TCP.  This means that multiple groups of channels will share the same communication bus (either by serial port or by IP address).  My initial solution to get something going was to contain each communication bus in a DVR in a class, open communication, and pass it into each temperature constructor that shares it.  This works fine until something goes wrong with the connection.  Note that a singleton doesn't seem appropriate for this because there could be multiple groups of temperature devices, so I would need multiple shared resources.

Now what I am missing is a concept for having the communication maintain itself and provide status to the temperature instances and the application.  What happens if the connection goes down (someone walks away with their laptop)?.  What happens when the connection is available again (someone plugs in the ethernet cable)?  I would also like to here thoughts on whether it is appropriate to have the temperature instances and/or the communication busses be Actors (as opposed to being directly handled by a different actor).

Thanks for any suggestions,

Greg

Message 1 of 10
(5,329 Views)

It seems like you are thinking about the correct things.

To answer your list of questions with a question: What do you want to happen? These are all cases that you need to define, design, and test to validate. Customer, System and Engineering requirements should drive your design.

For example: "a remote system shall connect to central system when available"

It sounds like you definitely need something to manage connections. Perhaps something Publish/Subscribe with an array of enqueuers and message types.

It sounds like data might be different for each machine, so you may want to think of a way to either encapsulate it or make it generic for consuption.

I don't think I would mix AF and DVRs. Actors own their data. If you need to share data you send a message. If you need central storage of all data then you have all actors send data messages to the storage actor.

Good luck,

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 2 of 10
(3,990 Views)

Yes, there is a lot to think about.  I would like to understand what my options are for sending my data to a central storage.  In the past, this would be easy through FGVs or some similar method.  If each temperature channel is treated as an Actor, what is a good method to route the result to the central storage?  I can think of zero-coupling or events, but it seems like this would need maintenance and not be as flexible (in the context of identifying every channel).  Another approach could be to bundle my data with an identifier?  When each Actor is launched, it could be assigned the identifier and then the central storage could find a way to handle this (Type of instrument, type of result, channel name, value).  Maybe a result class from which different results types inherit from....  Have I just missed an easy solution for this?  My temperature actors can't just enque a result to the caller because the caller won't know where it came from (or could it?).

0 Kudos
Message 3 of 10
(3,990 Views)

I have a logger class (Actor) that is overriden with a telemetry logger. All my actors can send telemetry to that logger. I hand out the EnQr at startup. I keep track of the telemetry source and type with a dotted string. Ex:

dutModel.dutSN.rackID.HWID.HWCh.type.friendlyName

Some of this info comes from the input configuration data. By capturing all the info into a single dotted string, it gives a complete picture how and where the data was generated, no matter the source or type. The dotted string is paired with the actual data value of course and a time stamp, either in a cluster or a class.

My telemetry logger can then choose how it wants to log (i.e., I can create any sort of child override to log to text files or csv or database or you name it). I needed that flexibility because I have to start easy (say text files) and when I get some more time work my way into a fully parametric database. That's one of the beauties of AF, being extensible without changing previous work.

0 Kudos
Message 4 of 10
(3,990 Views)

I have moved away from identifiers and operate completely with different children message classes of the zero coupled message.

You do enqueue to the caller.

When the caller launches the nested actor it provides a child of the zero coupled message class. If you need to store data in different places you have to create methods for storing the data (maybe just a write accessor) and then you need to create a message for that method and make the message inherit from the zero coupled message. You repeat this for each different place you are going to store data.

Note: these children messages don't store the data, the parent class does. Then in the Do.vi you need an accessor to read the data from the parent class and use that data as input to your method within Do.vi.

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 5 of 10
(3,990 Views)

A quick question about the zero coupled solution.  If a caller had 2 nested Temperature actors there would be 2 overides which I think need 2 methods to back them up.  By passing the concrete message at launch, then Temperature can send a message to the proper method.  Each method would already know where the data came from so the Temperature actor wouldn't need to.

My question or concern comes from scaling.  If my application decides there will be 10 channels or 20 channels by changing the configuration, I don't want to have to manually handle this.  That would leave me with a generic response message which at that point I think it would need to identify itself.

0 Kudos
Message 6 of 10
(3,990 Views)

I would make the zero coupled reply message have an array as the payload. The receiver should know what to do with the payload.

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 7 of 10
(3,990 Views)

Thanks for the input.  It is now time that I stop thinking about how difficult this could be and just start building it using the recommendations and rules.  Everything that I think could be a problem would actually still be a problem in any other framework, this just prevents the normal shortcuts...

Greg

0 Kudos
Message 8 of 10
(3,990 Views)

We do this all the time with sensors that are multidropped on different serial links,although it is not based on the actor framework.

The solution we have that has worked beautifully is that each sensor is instantated as a separate process (actor in many ways), and each hardware channel (in our case it is either a serial port or a client-server TCP port) is also instatiated as a communication handler.

The communication handlers expose themselves to the "sensors" (the processes dedicated to aquire and process data from each real sensor) by having a named queue (which the sensors know from their configuration that they are linked to). The queue takes an input containing both the message and timing information for the given sensor polls, and a reply queue which the given sensor process waits for after issuing commands to the channel.

If we need to debug the traffic on a given channel we can call up the front panel of the given channel handlers, and it will display a log of the traffic along with timing statistics etc...very conventient.

Message 9 of 10
(3,990 Views)

Mads,

This is sounds exactly like the path I am heading down.  I have instrument classes which use communication classes, but through the actor framework.  If a communication class changes state, it will propogate back to all the instruments.  Each instrument may make a request to the communication class (and include it's own queue) and then the communication class will eventually send a message back to the instrument if needed.  This way any number of instruments can share a communication channel and none of the instuments will own it.

0 Kudos
Message 10 of 10
(3,990 Views)