LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

1-to-1 Relationship Between UI and subVI Data Cluster

Discussion continued from here.

 

In summary:

 

 


JackDunaway wrote:


 

 

Yes, I can see clear benefits in implementing this Idea - that is, if your underlying datatype elements have a 1:1 relationship with the UI elements.

 

I will illustrate this point by showing some potential flaws in your example: "Profile Running" and "Profile Complete" are mutually exclusive, no? Wouldn't it be better to have a single enum named "Profile" with three elements "Idle, Running, and Complete" for the underlying datatype? Having two mutually exclusive pieces of data in an underlying datatype is among my favorite of code smell indicators. Also, the underlying datatype probably only needs "Forward Miles" and "Reverse Miles" since "Total Miles" is derived. Exclude "Total Miles" from the underlying cluster and just show the sum for display.

 

Another argument against using a 1:1 relationship: the customer now wants to multiply speed by -1 if Direction==Reverse and not show the Direction enum on the UI. The data source (the VI that generates the data) would need to be updated using your 1:1 relationship. Using underlying data different from the display data, only the data client (the UI front panel) needs to change. I would be much more inclined to service the UI FP for a cosmetic upgrade rather than tracing the data source back through the HMI framework, through TCP, back to the RT, back to FPGA...

 

Basically... I question a perfectly overlapped Venn Diagram where the set of data shown to the user equals the dataset used for underlying data processing/messaging/storing. The underlying datatype should be as stripped and streamlined as possible, while the display datatype can inherit all the flair and post-processing that Upper Management wants to see in a UI.

 

 

 


LabBEAN wrote:



<JackDunaway wrote:>
I will illustrate this point by showing some potential flaws in your example...

 

<LabBEAN response:>

The data you see maps directly to tags on the PLC.

<JackDunaway wrote:>
Yes, I can see clear benefits in implementing this Idea - that is, if your underlying datatype elements have a 1:1 relationship with the UI elements.

 

<LabBEAN response:>
  😄

 

 


JackDunaway wrote:


 

This is a good indicator that we're both aware at this point that I'm missing something... in all seriousness, could you reply to the 1:1 argument? I really want to understand this Idea and learn how/if I need to apply it to my own style (our last back-and-forth turned out to be an enlightening and introspective exercise for me).

 

***EDIT: By all means, please start a discussion on the LabVIEW board so we're not hindered by the Exchange's interface. ***

 

 

 


My long delayed response:


 

 

The indicators you see map to tags on the PLC.  That is, we were connecting through OPC to an application on a PLC that was written ~15 years ago.  I have a VI where I read a bunch of SVs (Shared Variables).  Each SV is bound through OPC to a PLC tag.  In the interest of disclosure, two 16-bit tags are required to represent each 32-bit mileage number.  In the same subVI, I read each set of mileage tags, convert, and feed my subVI cluster indicator.  The same is true for wheel size:  three bits get converted to the enum.  Regardless, though, I have one subVI that reads SVs and outputs the same "underlying data" cluster that is seen on the UI.  The UI has a "Faults" cluster full of fault Booleans that follows the same logic.  When the user configures a profile of steps, they do so via an array of "step" clusters (although the cluster look is hidden for aesthetics).  It's the same thing as above except we write tags instead of reading them.

 

In my case, each set of 16-bit tags is worthless as two 16-bit numbers.  They are only useful as a 32-bit mileage, so I don't pass around the raw 16-bit data.  The same is true for the wheel size bits. My software can just as easily (in fact, more easily) operate on the enum.  So, the underlying cluster from the subVI is programmatically useful and applicable to the UI.  I would guess that the same is true for a lot of RT applications, where the read VI can have some intelligence to process the data into useful / applicable clusters.

 

There are going to be cases where "Upper Management" would like to see "flair and post-processing" as you say.  Your speed illustration is a good example of this.  There are also instances where the cluster works fine on the UI the way it is (like this one and many others that we've seen).

 

<JackDunaway wrote:>

"Profile Running" and "Profile Complete" are mutually exclusive, no? Wouldn't it be better to have a single enum named "Profile" with three elements "Idle, Running, and Complete" for the underlying datatype?

 

<LabBEAN response:>

Did you mean "not" mutually exclusive?  We combined 3 "dependent" (not mutually exclusive) Booleans into an enum for Wheel Size, as I mentioned above.  Not sure now why we went the other way with these two (this was 2 years ago).  In any event, with regard to UI representation, I still pass a cluster out of my read-raw-data-and-process-into-cluster subVI up to the applicable queued state machines and to the UI.

 

<JackDunaway wrote:>

Having two mutually exclusive pieces of data in an underlying datatype is among my favorite of code smell indicators.

 

<LabBEAN response:>

Working with applications written in ladder logic, it is not uncommon to see separate Booleans that indicate the same condition.  This seems to be especially true when safety is a concern.  That is, ladder Coil A ON and Coil B OFF == switch open.  Coil A OFF and Coil B ON == switch closed.  If you ever read OPC tags from Coil A and Coil B and the two are the same, you know the ladder is in transition (hasn't updated the tags).  Throw that point out and read again.

 

I, too, appreciate our back-and-forths.  Good discussion.


Certified LabVIEW Architect
TestScript: Free Python/LabVIEW Connector

One global to rule them all,
One double-click to find them,
One interface to bring them all
and in the panel bind them.
Message 1 of 3
(4,204 Views)

Thanks for replying, Jason. Let me see if I can craft a coherent response after getting back up to speed...

 

(...later)

 

OK, let's go. I'm going to fully agree with you that LabVIEW imposes a strange constraint unique from most other languages where a Typedef defines two things: the underlying data structure, and also the view. A Strict Typedef should be more accurately deemed the Datatype-View-Definition, and a Typedef would be more accurately called the Datatype-Definition-and-View-Suggestion. And to be clear, there are two types of views: the programmer's view (a SubVI look and feel) and the UI view (what the user and Upper Management sees). (Finally, I admit I'm ignorant whether view or View is more a more appropriate term)

 

Linking the programmer's view to the datatype is perfectly fine with me, and based on your original Idea I think we both agree that's OK. I think we run into a disagreement where you have loosely tied the concept of "Strict TD" to "UI View".

 

Historically, I have used Strict Typedefs for the programmer's view (SubVIs), since I like to maintain a "functional UI" at the SubVI level. I don't use type definitions on User Interfaces - only Controls. That's the reason your Idea does not appeal to me, but perhaps if your Idea were implemented, it would appeal to me since View and Implementation would be divorced as separate entities within the Type Definition. (Does that classify as a Catch-22?) So, you're Idea is fundamentally suggesting that Type Definition .ctl files should be more accurately called "a container that holds both a Type Definition and any number of View Definitions as well".

 

Fundamentally, I think I finally understand the gist of your Idea: "let's ditch this weird constraint where View and Datatype are inextricably defined together in one file", and for that, I'll give Kudos to the original Idea. I got really tied up with the example you used to present the Idea, and plus I'm still learning a lot.

 

Additional thoughts:

 

 

  1. This Idea reminds me of another: Tag XControl as Class View
  2. We've still got some arguing to do on a 1:1 relationship between underlying datatype and UI presentation, so put your mean face back on: Smiley Mad
  3. Since our last conversation, interestingly, I have been on an anti-Typedef kick altogether. Smiley Surprised Why don't you drop some feedback on my attempt at a completely typedef-free UI framework?

 

Message 2 of 3
(4,185 Views)

 


JackDunaway wrote:

I think we run into a disagreement where you have loosely tied the concept of "Strict TD" to "UI View"

...

We've still got some arguing to do on a 1:1 relationship between underlying datatype and UI presentation


 

Maybe our difference in experience is style related.  I tend to process/scale/convert raw data before passing it to a cluster (e.g. reading the two 16-bit registers and passing out a 32-bit number OR reading various Booleans and passing out an enum).  So, the underlying datatype is immediately useful to the UI in some (most?) cases.

 

If I understood, one of your arguments against this was to keep an underlying data cluster with "Profile Data" and "Profile Complete", which I read from the PLC, and use a UI cluster with a Running, Idle, Complete, Error enum.  This is where I think our styles differ.  If I wanted an enum on the UI, then I would convert to an enum in the underlying data cluster as well.

 

 


JackDunaway wrote:

Exclude "Total Miles" from the underlying cluster and just show the sum for display.


 

Total Miles was just another tag that I read, but even if I calculated it, I would have done so in the read-raw-data-subVI and added it to the outgoing subVI cluster.  This is for simplicity.  The data structure becomes useful to the UI and I only calculate total miles in one location, rather than calculating total miles for display on the UI and then again in other subVIs that need it.  In all seriousness, because of our previous conversation, I'm surprised this extra info bothers you.)

 

There will be cases where this doesn't make sense and we have to manage two clusters (underlying and UI).  But, where possible, I prefer to just have the one.

 

 


JackDunaway wrote:

I like to maintain a "functional UI" at the SubVI level [with Strict Type Defs]



The beauty of this idea is that the developer can define whatever kind of views he/she wants.  Controls and indicators of the same type def could have different views.  That is, Cluster.Boolean1 could be a button or an LED depending on whether you place the containing cluster as a control or indicator.  The same would be true for non-cluster data types.

 

 


JackDunaway wrote:

so put your mean face back on: :smileymad:


 

What mean face?  😄

 

 


Certified LabVIEW Architect
TestScript: Free Python/LabVIEW Connector

One global to rule them all,
One double-click to find them,
One interface to bring them all
and in the panel bind them.
Message 3 of 3
(4,128 Views)