06-10-2017 04:53 AM
Dear NI Community,
let me, please, ask you about the following.
I have two HAL classes, which represent DMM and Switch devices. They have methods like Read configuration, Init, Deinit, specific configuration, do some actions (depends on the device, DMM or Switch). These classes are separated, as two different HALs, libraries.
Now, I have device which is Multifunctional Switch/Measure Unit - it has slots, where one can put switch modules, matrix modules, relays modules, etc.; and it has internal DMM which allows to measure current, voltage, resistance, etc.
I can communicate with device, let's say, by VISA. There are drivers for the device, via which I can control it.
And I'm just thinking - can I combine my two HALs for DMM and Switch to one HAL Switch/Measure Unit? B/c indeed, it includes those two devices. But the problem is, that DMM and Switch units are implemented in a way, that they obtain VISA (or some other) reference for communication with device in method Init, and then keep that reference in private data.
With this approach, I can't two times init my Switch/Measure Unit, b/c it's simple COM port, and I'll have error during opening it the second time.
The solutin could be, to create some abstract class/interface, which will allow to pass into DMM HAL and Switch HAL opened reference to the device. And then, my Switch/Measure HAL will have method open reference to device, and pass it to DMM HAL and Switch HAL.
But, this will break DMM HAL and Switch HAL, because as stand-alone devices they don't need this method at all.
Are there some common approaches to this task? Some examples of how to combine several HALs to one, when they indeed share some resource, which is private in their implementation? I've heard about MAL example from Elijah Kerry, but I'm not sure whether this is what I need... Are there some examples for this task?
Or I am doing something wrong, and my HALs are not properly designed then; and I don't need to keep reference to device in private data of HAL implementation, but it should be some abstraction, which will be contained in HAL definition?
Thank you very much in advance!
Sincerely, kosist90
JKI VI Tester – useful tool for LabVIEW developer
Solved! Go to Solution.
06-10-2017 08:17 PM
I found myself if a similar situation. In my case, I wanted an object for each power supply in my system. But in said system was a modular power supply mainframe that had 4 power supplies in it. To be more precise, I had two of those mainframes for a total of 7. Then there was a large power supply making the total 8. But that is not important here. Anyways, I could only have 1 VISA reference for each mainframe. So what I ended up doing is making a class for the mainframes and storing those objects in an Action Engine. So when I initialized my power supplies in those mainframes, I called the AE to get a Data Value Reference to the mainframe object I needed. So the power supply objects then used the DVR to do the sending of the messages (basically replace VISA Write and VISA Read with methods for the mainframe). Do note that the mainframes must be initialized before initializing the power supplies.
06-11-2017 12:33 AM
Can you perhaps use a setup with 3 sibling classes under some 'Unit' parent class?
In this case, your first two classes can be the existing DMM and Switch classes. Your third class could be a SwitchMeasure class, which in its private data contains an instance of each of the other classes. Your methods can call the appropriate subset of functionality from the instances initialised in the SwitchMeasure object and stored in private data.
I'm not sure how you're currently implementing measurements - perhaps a polymorphic VI can hold different measurements for a specific class, and for the SwitchMeasure class you just have a larger number of options?
Since you wouldn't have to modify the DMM or Switch classes at all to do this, it shouldn't break anything. It would probably involve a large quantity of 'boiler-plate' code though... many wrappers on other methods that just unbundle the appropriate instance and call a method.
06-11-2017 03:58 AM - edited 06-11-2017 03:59 AM
Thank you, crossrulz - your idea seems to be the most suitable one; somehow I was stucked to idea of retreiving reference to device from HAL's private data, but forgot to realize, that I can keep it in some shared storage, as FGV (Action Engine). Thanks a lot!
Sincerely, kosist90
06-11-2017 04:10 AM
Thank you, cbutcher, for your idea!
I was also thinking about it, but it seems to me, that there is one issue with it. As DMM HAL and Switch HAL instances, which will be kept in some Unit class are not childs of SwitchMeasure class, I can't retreive private data from SwitchMeasure class inside DMM and Switch class. Thus, I need to pass reference of the device from SwitchMeasure class inside DMM class, and Switch class - what I can't do with current implementation of HAL.
If I'd have in DMM and Switch class method "Set Device Reference" - then it would be a solution, b/c instead of calling "Init" method for each of them, I'd init SwitchMeasure class, and then for each of DMM and Switch execute method "Set Device Reference" -> save it in their private data, and work with that...
So I'm gonna implement it as crossrulz suggested, and see how it will go...
Sincerely, kosist90
06-11-2017 05:20 PM
Another idea very similar to those posted already is the idea of an Application Layer that implements your application actions (such as switch and measure) into a set of APIs that can be used by your actual application. It performs the necessary sequences of activities and takes, as input, your DMM and Switch class objects - most likely injected into your constructor and part of the new API private data. This is composition and is more flexible than inheritance for combining functionality.