From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How to update DQMH status outside of main

Solved!
Go to solution

I have a project (http://forums.ni.com/t5/Delacor-Toolkits-Discussions/Right-tool-to-replace-a-State-Chart-project/td-...) and am curious about the right way to do something in the framework.

 

I really like how the status updated can be watched and used all over the place.  In my app the high level UI may use it to show the user whats happening under the hood.

 

So what is the "correct" way to post status to that, when being called not directly from the DQMH module.  In the above referenced post, my DQMH is a sequencer that at some point calls a step to run.  I want to have that step send "I am starting" "I am done" etc.  I see how inside the DQMH you call "Status Updated".   However, "Status Updated" broadcast is private.

 

So am I correct that I need to create a new request (thus public API) that then just sends the Status Updated.  It seems simple enough, but I wonder if exposing the Status Updated like that is "correct".

 

Thanks

0 Kudos
Message 1 of 7
(4,954 Views)
Solution
Accepted by topic author Evan

Since the DQMH sequencer module is the one starting the step, and presumably knows when the step is done, why not have the DQMH broadcast those status updates? Why does it have to be done by the step itself?

0 Kudos
Message 2 of 7
(4,953 Views)

Hey Darren,

 

Thanks for a quick reply.

 

It turns out the DQMH is really just a sequencer that is starting a sequence (class) and asking it to evaluate if it is done.  It is a few class layers down that the steps actually executes.  So I could expose somehow what step is being looked at, but it would have to travel a few levels up.  The sequence itself is a class that basically returns an array of cycles and the cycles are an array of steps and their order.  So the DQMH says sequence start yourself, sequence are you done.  Then each level decides if it is done and what to do next.  This is a work in progress so it may be that I should re architect that idea.

 

As far as the original question: the more I think about it I think what may be better is a new request+broadcast.  

 

When a sequence is started I can see where some steps may want to tell the user it happened, and some steps may want to be silent. Similiary a sequence to cycle may want to say what it is doing.

 

So I can see the request being 2 things (status string, show main UI bool).  Then the DQMH event simply adds all these strings to the DQMH status, so I can still use the tester as a sniffer to see ALL the steps and thier status.  It also looks at the Show Min UI bools and decides to braodcas the message to the mian UI.  The main UI can just subscribe to the broadcast part, and get only the status udpates that are approproate.

 

I get the feeling I will go through a few iterations of how to do all this, but I appreaciate all the help and the learning I am doing.

 

 

0 Kudos
Message 3 of 7
(4,938 Views)

Hey guys, sorry to keep re-hitting this one, still in the learning curve.

 

So I seem to keep getting myself back into this situation and I have a sinking feeling it is just because I don't quite "get" the DQMH yet.  For other VIs to get data from the DQMH I have two options, 1. poll with a request and wait or 2. Register for a broadcast. Correct?

 

I generally try not to poll something, so I go towards #2.  But for that I keep seeing times where I want to broadcast something from within the DQMH, but the private scope of the broadcast stops me.  See below for a examples.  So I can create a request + broadcast to basically expose the private broadcast, but I get the feeling it is breaking or shortcutting the architecture and I should be doing something different.  

 

An example I can relate to is the HAL DQMH example.  The hardware classes themselves can never broadcast a message correct?  They have to somehow pass data up to the DQMH layer and then it can broadcast that value.  Putting any DQMH APIs in the HW class instances themselves just couples the two in an odd way and is considered wrong.  Correct?  

 

In my specific example I have a sequence of steps executing.  Most do not change the main UI, but a few do.  Example: a step that gets an updated sensor value.  So that 1 step may want to broadcast out a new sensor reading to the main UI, but all other steps won't.

 

Similarly looking at the Thermocouple examples.  The UI in the examples is updated VI polling the request and wait. Could its main be modified that in the HW simulator loop it sends a request+broadcast of the status or  ???   The request is just a pass through of that data to a broadcast. Then the example UI can just watch the broadcast?  Would that be an acceptable usage or am I opening a can of worms.

 

Sorry if these are somewhat vague or overly specific to my application. I am really trying to understand DQMH and get into it so that I am not always using AF in my projects.  Though to be honest I struggle with the AF and getting data from abstracted classes up to the calling architecture.

 

 

Edit: I also was watching the "How to control a State Machine with a DQMH", and am wondering if my entire problem is that I did not put all my steps and classes in the DQMH library.  Then private is not a concern.  This architefture I am building I want to be re-usable, which is why I am looking at coupling etc.  But if each project takes the base library of the DQMH and the sequencing clasess in the same library and then copies that as the starting point, I think I am ok.  Then as each specific project needs to expose data from the steps they can.

 

However, I still have a similair issue with State Data.  I am not sure I like the idea of sending all sorts of state data into the various sup steps.  There is jsut something about the huge state clusters getting passed everywhere that kind of bugs me.  But I still have some white board time before I have a question there.

0 Kudos
Message 4 of 7
(4,883 Views)

Hi Evan,

 

Here are my answers/comments to your questions:

 


Evan wrote:

So I seem to keep getting myself back into this situation and I have a sinking feeling it is just because I don't quite "get" the DQMH yet.  For other VIs to get data from the DQMH I have two options, 1. poll with a request and wait or 2. Register for a broadcast. Correct?

 


There are two type of communication events: Requests and Broadcasts. 

The Request definition is: Code that fires an event requesting the DQMH Module Main.vi to do something.

The Broadcast definition is: Code that fires an event broadcasting that the DQMH Module Main.vi did something.

 

There is no polling needed.

If code external to the DQMH (outside of the DQMH library) needs to communicate with the DQMH, it should use the Request VIs (these are the public VIs that get automatically created by the scripting tools and that wrap the firing of the request event).

If the DQMH wants to announce to external code something, then the DQMH uses the Broadcast VIs (these are the private VIs that get automatically created by the scripting tools and that wrap the firing of the broadcast event).  The way the code external to the DQMH gets that information is by registering to listen to the DQMH broadcasts. 

 


@Evan wrote:

 

I generally try not to poll something, so I go towards #2.  But for that I keep seeing times where I want to broadcast something from within the DQMH, but the private scope of the broadcast stops me.

 


Any code within the DQMH library should be able to call the DQMH Broadcast, the broadcast is private to that DQMH module. This is just a way for the library to encourage the developer to not mix metaphors and end up calling broadcasts from calling code. 

 


@Evan wrote:

 

An example I can relate to is the HAL DQMH example.  The hardware classes themselves can never broadcast a message correct?  They have to somehow pass data up to the DQMH layer and then it can broadcast that value.  Putting any DQMH APIs in the HW class instances themselves just couples the two in an odd way and is considered wrong.  Correct?  

 


I hesitate to call something wrong, there are different ways of coding in LabVIEW. My suggestion would be that if you want to keep the class decoupled from the DQMH module, then yes, the VIs would provide an output that then the DQMH module uses to broadcast. 

If you are OK with coupling your classes with your DQMH module, then just move the class inside the DQMH library and the methods will be able to call the broadcast VIs. A situation where I would see as OK to coupling the two together is where either:

  1. The DQMH is considered the API for the class. For example, you are working with teams of different levels of proficiency and you want to provide a set of VIs that do not involve any classes.
  2. The class relies on a DQMH to work. Examples of this would be classes where you need a module continuously running in the background while the object is active. An example of this would be a class used to simulate hardware, it might launch the DQMH module during "hardware init" method and would keep the front panel open so the developer can inject the messages to be read the next time the "Hardware Read" method is called. Then on the close connection, the simulated version of the class would stop the DQMH module.

@Evan wrote:

 

In my specific example I have a sequence of steps executing.  Most do not change the main UI, but a few do.  Example: a step that gets an updated sensor value.  So that 1 step may want to broadcast out a new sensor reading to the main UI, but all other steps won't.

 

 


If by main UI you mean the main UI of the DQMH module, then I would use Private Requests. Meaning, I would create requests that can only be called by VIs within the DQMH library. This is something that is not supported out of the box, but the way to do it would be to create the Request as you normally do and then mark the Request VI as private. It is up to you if you leave it within the Public API folder that the scripting tools will put it in or if you want to specifically move it to a private Virtual Folder. Setting the Request as private ensures that no other module could register to handle it and it is clear that it is a message that you want to send from the DQMH to the DQMH itself. For this and other best practices, check out this document: http://delacor.com/dqmh-documentation/dqmh-best-practices/

 


Evan wrote: 

Similarly looking at the Thermocouple examples.  The UI in the examples is updated VI polling the request and wait. Could its main be modified that in the HW simulator loop it sends a request+broadcast of the status or  ???   The request is just a pass through of that data to a broadcast. Then the example UI can just watch the broadcast?  Would that be an acceptable usage or am I opening a can of worms.

 


 

I am assuming you are referring to the DQMH shipping example "Thermal Chamber.lvproj". In this example we use the Request and Wait for Reply type events, because the code is called also via a TestStand sequence or by simple VIs that do not have a sequence structure. Look at "Thermal Chamber Controller.vi",  "Thermal Chamber Controller with DUT.vi" and "Thermal Chamber Controller with Multiple DUTs.vi"

 

Now, if you look at the "Test Thermal Chamber Controller_DQMH API.vi", which is there to test and show others how to use the DQMH API, you can see that both approaches are used:

 

  1. If the end user changes the Temperature Set Point or the Ramp Rate from the "Thermal Chamber Controller_DQMH" UI, then the Tester updates their change by handling the "Set Point Updated" and "Ramp Rate Updated" broadcast events.
  2. At the same time, there is no need to broadcast all the time the current temperature, because this is not a headless module. The thermal Chamber Controller_DQMH UI can be shown during the duration of the application and the end user can interact with it. So no need to be handling the "Chamber Status Updated" broadcast from the actual temperature (there might be other applications where you do want to handle the "Chamber Status Updated"broadcast all the time, but this is not the case here). The actual temperature is updated directly on the "Chamber Temperature Chart" on the Thermal Chamber Controller_DQMH UI.
  3. However if any other part in the code needs at a given moment to know what is the actual temperature at that moment, then they can call the Request and Wait for Reply to get that moment's information, this can be seen when the developer presses the "Refresh (Synchronous)" button on the front panel of the "Test Thermal Chamber Controller_DQMH API.vi".

@Evan wrote:

 

 

Sorry if these are somewhat vague or overly specific to my application. I am really trying to understand DQMH and get into it so that I am not always using AF in my projects.  Though to be honest I struggle with the AF and getting data from abstracted classes up to the calling architecture.


Nothing to apologize for. These questions help us figure out where the documentation, examples, videos, etc could be more clear. Also, there might be others who have the same questions as you and now I can just point them to this post. Thanks for taking the time to ask your questions on this forum.

Regarding AF, I am working with another member of the community on ways to highlight the commonalities and differences between both architectures. Stay tuned to our blog. I will make sure to post in this forum as well.

 


@Evan wrote:

 

 

Edit: I also was watching the "How to control a State Machine with a DQMH", and am wondering if my entire problem is that I did not put all my steps and classes in the DQMH library.  Then private is not a concern.  This architefture I am building I want to be re-usable, which is why I am looking at coupling etc.  But if each project takes the base library of the DQMH and the sequencing clasess in the same library and then copies that as the starting point, I think I am ok.  Then as each specific project needs to expose data from the steps they can.

 


Once you get your base reusable DQMH Module, you can create a DQMH Module template. This will add your DQMH Module to the list of types available when adding a new DQMH Module. To do this, you will definitely have to have all the classes be part of the DQMH library and their folders will have to be part of the DQMH folder as well. Instructions on how to create a DQMH Module Template..

 


@Evan wrote:

 

However, I still have a similair issue with State Data.  I am not sure I like the idea of sending all sorts of state data into the various sup steps.  There is jsut something about the huge state clusters getting passed everywhere that kind of bugs me.  But I still have some white board time before I have a question there.


 

Do not use a big cluster, unbundle from the state data and only pass what that VI needs. Here is a visual for you: 



 Regards,

Fab

 

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 5 of 7
(4,867 Views)

Thanks for the very in depth reply.  I have some reviewing, thinking, and reviewing again to really get it.  Below are some quick thoughts\question.

 

A quick question.  I read the Best Practices, and am wondering if you can point to a good document or resource that talks about how to really define a module.  This is more general than DQMH, but I get the sense that where I am struggling is how or what to define as a module.  My application either ends up with a module trying to creap outside its scope, or what may end up being too many modules, that are small so potentially...  The balance seems like an art.  

 

For me I think the balance is a sequencer style DQMH module that only runs steps, but does not really have specific state data or know too much internally about the other modules. The steps themselves will generally call other modules.  I have a UUT module, temp chamber module, pumps etc.  By making each module separate they can keep their own data.  The "coupling" is in the steps that just decide when to tell other things to react (ie Pump turn on, UUT take data...).  However, the steps don't have Pump State data for example, so that it isn't a huge cluster.

 

Lastly for your notes on AF versus DQMH, I think one area I struggle with mentally for the DQMH is "ownership" and relationships of the modules.  With AF and classes there is a distinct reference to the actor or the object, so I somehow can visualize that Module A "owns" module B, even in a "Has a" relationship.  But with DQMH I don't see that as easily.  Back to my sequencer idea.  If I was doing AF there would be an enqueuer somewhere that the steps would have to reference, or messages all the way up to some base level, and then that base level would send messages to other actors.  With the DQMH, I don't have to go through all those levels, I can just call the public API.  I see this as a nice pro, and part of why I am trying DQMH on this project.  However, because the modules can be called anywhere by anyone it muddies my mental image of relationships.  End of the day the DQMH I think is forcing me to define the interfaces between modules\objects earlier, but I can see poor planning now leading to modules being called from unexpected or planned areas.

 

PS the video is spot on.

0 Kudos
Message 6 of 7
(4,854 Views)

You are correct, DQMH projects benefit from modeling your modules and messages before you start creating your code. 

Right now you are separating a DQMH module for each piece of hardware, but maybe you end up making each step a DQMH module. I suggest you start drawing circles for each of your modules and arrows between them for the messages. Also a sequence diagram might help. 

 

It is easier to trash a model than it is to trash a project you have already invested days on (although, we should probably do that a lot of times as well 😉 )

 

I don't have a specific resource for learning how to model and define how to divide your applications. I know my approach has changed over time. One way is dividing by responsibilities. Another is defining how many UIs you will have, then each GUI could have its own DQMH module. 

 

Here is a link to a presentation I gave at NI Week, starting on minute 24, I talk about designing and modeling and how putting things on paper led us to a very different approach than we initially thought we would do. Hopefully it helps:

 

 

Regards,

Fab

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 7 of 7
(4,848 Views)