<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" >

<channel><title><![CDATA[LabVIEW Craft - Blog]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog]]></link><description><![CDATA[Blog]]></description><pubDate>Sat, 21 Mar 2026 19:32:34 -0400</pubDate><generator>Weebly</generator><item><title><![CDATA[Learning the MVA Framework - Tutorial 2: A community of Two]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/learning-the-mva-framework-tutorial-2-a-community-of-two]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/learning-the-mva-framework-tutorial-2-a-community-of-two#comments]]></comments><pubDate>Wed, 02 Oct 2019 15:27:06 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/learning-the-mva-framework-tutorial-2-a-community-of-two</guid><description><![CDATA[-By Chris Cilino, Composed Systems Partner  Introduction  In my first tutorial, I introduce the Composed Systems' open source framework called the MVA Framework. We looked at how to port a common UI application to the MVA style of programming. This tutorial picks up where I left off and covers how to have more than one UI in an application.&nbsp;      The Main course: Our task for this meal...  Our last application was largely unremarkable on the surface, but under the hood we architected it to  [...] ]]></description><content:encoded><![CDATA[<div class="paragraph">-By <a href="https://www.linkedin.com/in/chriscilino/" target="_blank">Chris Cilino</a>, <a href="https://www.composed.io/" target="_blank">Composed Systems</a> Partner<br /></div>  <h2 class="wsite-content-title"><font size="5">Introduction</font></h2>  <div class="paragraph">In my <a href="http://www.labviewcraftsmen.com/blog/learning-the-mva-framework-tutorial-1-start-by-stopping" target="_blank">first tutorial</a>, I introduce the Composed Systems' open source framework called the MVA Framework. We looked at how to port a common UI application to the MVA style of programming. This tutorial picks up where I left off and covers how to have more than one UI in an application.&nbsp;</div>  <div>  <!--BLOG_SUMMARY_END--></div>  <h2 class="wsite-content-title"><font size="5">The Main course: Our task for this meal...</font></h2>  <div class="paragraph">Our last application was largely unremarkable on the surface, but under the hood we architected it to let us easily swap out one UI for another. What if my application needs more than one UI? How do I decompose a single UI into more modular UIs? In this tutorial I'm going to introduce a few more classes and concepts that'll allow us to host multiple "widgets" in a UI.&nbsp; We're going to make the UI you see below composed of two "widgets". One widget is given the responsibility of stopping the application by presenting a stop button to the user. The other widget simply has a ring control that presents options to a user.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-11-25-11h02-25_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <h2 class="wsite-content-title"><font size="5">Let's get Cooking</font></h2>  <div class="paragraph">Using our same abstract graphics from the first tutorial, the goal is to create the following:<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-11-25-11h09-12_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Here, the red class (IViewModel.lvclass) is a thing designed to host other things. In the first tutorial we hosted a UI (IViewable.lvclass, the purple class). Now I'm going to introduce a new concept: the view manager (IViewManager.lvclass; that's the green class above). Among its other responsibilities, the View Manager is responsible for defining the layout of the widgets. We'll talk about other responsibilities in later tutorials. Our two widgets are are both of type IViewable.lvclass (the purple and the yellow classes).</div>  <h2 class="wsite-content-title"><font size="5">&nbsp;Organizing Your UI Layout- The View Manager</font></h2>  <div class="paragraph" style="text-align:justify;">As mentioned above, one of the View Manager's responsibilities is to define the layout of a UI. Defining a layout means putting down one subPanle per widget. To create a View Manager:<br />1. create a new Actor Framework actor and inherit from IViewManager.lvclass:</div>  <div class="paragraph" style="text-align:left;">&#8203;<span>&nbsp;&#8203;"...\MVA Tutorials\2 - A Community of Two\gpm_packages\@cs\mva-framework\Source\Framework\IViewManager\IViewManager\IViewManager.lvclass"</span></div>  <div class="paragraph">2. Create an override of the Actor Core.&nbsp;<br />3. Place your sub panels on the front panel.<br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-12-03-13h05-01_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">We need to make the MVA framework aware of these subpanels. To do that we call<br /></div>  <div class="paragraph" style="text-align:left;">&#8203;<span>"New Protected Subpanel.vi" (...\MVA Tutorials\2 - A Community of Two\gpm_packages\@cs\mva-framework\Source\Framework\IViewable\ProtectedSubpanel\New Protected Subpanel.vi).</span></div>  <div class="paragraph"><span>Then we add the subpanel references to our Actor's private data</span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-12-03-13h08-13_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Creating the widgets follows same procedure described in the first tutorial. So now we have all the ingredients we need. We have a thing that hosts layouts (the red class, aka IViewmodel), a thing that defines the number and layout of widgets (the green class, aka IViewManager), and two widgets (the yellow and purple classes, aka IViewables).<br /></div>  <h2 class="wsite-content-title"><font size="5">A widget Handling Events</font></h2>  <div class="paragraph">In our previous tutorial, the stop button value change event was conveyed out of the View (Purple class) to the ViewModel (red class) in the override of "catch nested updates". Then the view model stopped itself which caused the framework to shutdown all nested views.&nbsp;<br /><br />What if we don't want to convey an event outside of a view for handling, but rather handle the event in the view itself? There are two concepts I'll need to introduce here: 1. The Framework API that allows us to register things for events, 2. The thing that handles the event.&nbsp;<br /><br />In the actor core of the yellow actor you'll see a new VI called "Register For Control Events.vi".</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-12-18-13h16-05_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Register for Control Events takes an array of control references and an array of event types as inputs. What we're telling the framework is "Hey MVA, when you see any of these controls do any of these events, then receive and act on the value change event." Note the array of control references and the array of events is NOT parallel. If the framework sees any of the events in the event array for any of the controls in the control reference array, it will act.<br /><br />The thing doing the acting is an override of an IViewable called "Receive Value Change Event.vi". On an event, this VI will execute and looks like:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-12-18-13h20-17_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">In this VI, we take the user's selection from the ring control and show it in a one button dialog. Think of this case structure to be similar to the frame of an even structure. But like our deconstructed hamburger from the first tutorial, we've cut up the even handler into more granular parts. Here's what I mean:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-12-18-13h29-09_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">The block diagram on the left is our standard event structure set to handle a value change on control labeled "Choose An Option". It provides the control reference, old and new values, and time. Our MVA block diagram on the right does the exact same thing using APIs instead of the event structure.</div>  <h2 class="wsite-content-title"><font size="5">Paging our Chef. Time to Plate our food!</font></h2>  <div class="paragraph"><span>&#8203;Now we just need a chef to assemble our ingredients. And if you'll recall from the first tutorial, that's the responsibility of the Assembler.&nbsp; &nbsp;</span>&#8203;Below is our assembler for this application. Again, I've included pictures to help illustrate what's going on.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-12-03-13h18-18_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Something to note: we've introduce a new VI called "Write Startup Views". This framework VI does two things: 1. Indicates nesting, 2. Assigns a name to a widget (we'll see where the name is used shortly). "Write Startup Views.vi" embeds views into a View Manager. You'll notice our green class (view manager) is passed in as the top left input, and views and names are passed in as parallel arrays. We're directing the framework to insert the view classes into this specific view manager and then we give those views names.<br />We give the views names so the view manager knows which subpanel will host which view. Inserting the correct view into the desired subpanel happens in the "Initialize Front Panel" of our View manager, shown below:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-12-03-13h26-09_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">In our override we use a for loop to scan through the array of names. In each case, we select the specific Protected subpanel reference (we created the subpanel references earlier in this tutorial) and pass in the enqueuer of the view to host. "Send Insert Front Panel" is the framework VI responsible for insert a view into a subpanel.</div>  <h2 class="wsite-content-title"><font size="5">Bon Appetit</font></h2>  <div class="paragraph">Done and Done! We now how a modular UI composed of two widgets.&nbsp;<br /><br />So was it worth it? Well... now I can easily swap in any widget I want. But here's a cool bonus. Let's imagine you like the UI of the widget but not it's behavior. Since events are handled in an override called "Receive Value Change Events" all you would have to do to create new behavior is make a child View from the parent and override its&nbsp; "Receive Value Change Events" and call the child in the assembler. That's kinda cool!<br /><br />To whet your appetite (aka preview for the next tutorial), our two widgets compose the UI, but we'll likely want them to communicate with each other. I'm going to borrow from one of my all time favorite TV shows "Star Trek" to demonstrate how we open hailing frequencies between the two views. Prepare to make it so!</div>]]></content:encoded></item><item><title><![CDATA[Learning the MVA Framework - Tutorial 1: Start by Stopping]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/learning-the-mva-framework-tutorial-1-start-by-stopping]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/learning-the-mva-framework-tutorial-1-start-by-stopping#comments]]></comments><pubDate>Tue, 01 Oct 2019 15:56:28 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/learning-the-mva-framework-tutorial-1-start-by-stopping</guid><description><![CDATA[- By&nbsp;Chris Cilino,&nbsp;Composed Systems&nbsp;PartnerI recently became a partner at Composed Systems in July 2019.&nbsp;&nbsp;I hope you'll join me in my journey as I come up to speed on our tools set. One tool I want to highlight is the MVA Framework. The MVA Framework accelerates our development and give us flexibility to rapidly respond to changing requirements. And it can do the same for you since Composed Systems has made the&nbsp;framework open sourced.I've found that I learn best whe [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><span>- By&nbsp;</span><a href="https://www.linkedin.com/in/chriscilino/" target="_blank">Chris Cilino</a><span>,&nbsp;</span><a href="https://www.composed.io/" target="_blank">Composed Systems</a><span>&nbsp;Partner</span><br /><br /><span>I recently became a partner at Composed Systems in July 2019.&nbsp;</span><span>&nbsp;I hope you'll join me in my journey a</span><span>s I come up to speed on our tools set. One tool I want to highlight is the MVA Framework. The MVA Framework accelerates our development and give us flexibility to rapidly respond to changing requirements. And it can do the same for you since Composed Systems has made the&nbsp;</span><a href="https://bitbucket.org/composedsystems/mva-framework/src/master/" target="_blank">framework open sourced</a><span>.</span><br /><br /><span>I've found that I learn best when I first personally succeed at a task, and then share that knowledge with others. So I'm blogging about my journey to master the MVA Framework.</span></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="paragraph" style="text-align:left;">All of the tutorials are available at the&nbsp;&nbsp;<a href="https://bitbucket.org/composedsystems/mva-tutorials/src/master/" target="_blank">MVA-Tutorial Bitbucket Repository</a>. Each tutorial is a LabVIEW project designed to present the smallest set of concepts possible to accomplish a meaningful task. And each tutorial builds on the concepts of the previous one. So DON'T SKIP!<br /><br />To view any of the tutorials<br />1. Clone the <a href="https://bitbucket.org/composedsystems/mva-tutorials/src/master/" target="_blank">repository</a> using <a href="https://www.sourcetreeapp.com" target="_blank">Sourcetree</a> (or your favorite Git method).<br />&#8203;2. <a href="https://gitlab.com/mgi/gpm/gpm/wikis/Installation#manual-install" target="_blank">Install GPackage manager</a>.<br />3. Open GPackage manager and navigate to the directory containing the LabVIEW project for a given tutorial.<br />4. Install the dependencies:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-11-23-10h56-26_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><span>5. Use this blog in conjunction with the comments on the block diagrams to go on the journey with me.</span><br /><br /><span>The longest journey begins with a single step, so what better way to start than by learning to stop? Wait for it.... here's what I mean. Whenever I learn a new framework or look at someone's code, my very first question is "How does it stop?"&nbsp; In learning how code stops, I find I learn the most fundamental notions of the code. So that's where I'll start with the MVA framework (hence the clever title "Start by Stopping").<br /><br />In this first tutorial I'm sharing how I migrated the following application into an MVA application.</span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-10-01-15h31-23_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">There's nothing terribly fantastic about this VI. It's designed to start, wait for the Boolean button value change, and then stop. The MVA framework allows us deconstruct the front panel and block diagram into more granular parts you can programmatically interact with. Deconstructed food is a good analogy here, mostly because I like food. You might be used to a hamburger that looks like</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/editor/the-ultimate-hamburger.jpg?1569963787" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">But the MVA Framework deconstructs it to look like</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/editor/deconstructed-stock.jpg?1569962564" alt="Picture" style="width:502;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">so you can eat any part independently of the other and in whatever order you'd like.&nbsp; Let's deconstruct our VI into is separate parts.&nbsp;<br /><br />First we will split the front panel from the code by using <a href="https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019OX6SAM&amp;l=en-US" target="_blank">subPanels</a>,&nbsp;and we'll insert our UI into something designed to host UIs. I'm going to concentrate more on "What we are doing" and less on "Why" for the time being.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-10-01-15h48-44_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;">We'll make both the thing hosting the VI (aka the "hoster") and the hosted VI Actor Framework actors.<br />&#8203;WAIT! Actor Framework?! Ruuunnnn!!!! Deep breaths...before panic sets in, I'm a noob with the Actor Framework (AF), so I'm with ya. There isn't much AF stuff you'll need to know to use the MVA Framework. You'll see... just keep with me.&nbsp;<br /><br />To create the "hoster" MVA actor<ol><li>From a LabVIEW project right click on "My Project" and select "Actor"</li><li>Inherit from <strong>\gpm_packages\@cs\mva-framework\Source\Framework\IViewModel\IViewModel\IViewModel.lvclass</strong></li></ol> To create the "hosted" MVA actor<ol><li>From a LabVIEW project right click on "My Project" and select "Actor"</li><li>Inherit from<strong>&nbsp;gpm_packages\@cs\mva-framework\Source\Framework\IViewable\IViewable\IViewable.lvclass</strong></li></ol> &#8203;<br />So this is what we're putting together.<br /><br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-11-24-11h17-29_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><span>Next we cut up the block diagram and represent elements of the block diagram with VIs. The while loop becomes the actor core and, instead of the event handler, we introduce an API to Register For Control Events. The VI used to register for events is called "Register For Control Events.vi" and looks like&nbsp;</span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-11-23-11h18-01_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;">&nbsp;Path: <strong>gpm_packages\@cs\mva-framework\Source\Framework\ActorEvents\IEventAggregator\Register For Control Events.vi</strong><br />We pass in an array of control references to dynamically register to an event handler (we'll get there). We also pass in an array of event types we want to handle. In this case we are saying "Something execute when the value of "stop" changes." In effect the code above is a programmatic version of:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-11-23-11h21-23_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Since we have two actors running (our hoster actor and hosted actor) we want our stop command to be handled by the hoster. The MVA framework propagates the "stop" to the hosted Actor. So we need to create an override in the hoster called "Catch Nested Value Update.vi". While each UI can (and often does) handle each value change event, stop is a little special because we want to close the hoster as well as the hosted VI. So in the hoster we create an override of "Catch Nested Value Update.vi". This VI is designed to handle messages sent from any sub actors or "nested" actors. The block diagram of the override looks like:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-11-24-11h23-34_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">In the override we use an MVA function called "Unpack Nested Value Update" that outputs the label and value of the registered item (in this case the "stop" button). So in the "stop" case we stop the hoster actor which will in turn stop the hosted VI.<br /><br />So now we'er almost done! We just need a "chef" to assemble our deconstructed hamburger on the serving plate. In every MVA application, the "Assembler" is responsible for inserting actors into actors. Let's take a look at the Assembler of our application.&nbsp;</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/2019-11-24-11h30-42_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">I've added pictures and comments in the code to explain what's going on here. The red class is the hoster and the purple class is getting hosted. We use the MVA framework function called "Construct MVA Application" to stitch everything together. The "IViewModel" is the hoster (red class) and, in this case, the startup view is our UI being hosted (IViewable, purple class). When the program starts the MVA starts the actors and stitches them together.&nbsp;</div>  <h2 class="wsite-content-title">What?! All that work for...??</h2>  <div class="paragraph">Soooo what gives? This seems like a whole lot of complexity for not a whole lot of return. Here's the payoff:<ol><li>I can easily swap out the purple class for any other class instantly without changing anything else in the code. And at this point, all we assume is the hosted VI&nbsp;is sending a "stop" message. (actually, the hosting vi automatically handles the panel close event too!)</li><li>Developers can work on separate sections of the UI without stomping on each other's work.</li><li>UIs become more modular. It's almost like we are developing "widgits" of a UI instead of monolithic sets of code.</li></ol><br />In the next tutorial I'll show how the MVA framework let's us have N widgets in a UI working together. We'll start with "A Community of Two". So stay tuned!</div>]]></content:encoded></item><item><title><![CDATA[Ambitious Brewing]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/ambitious-brewing]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/ambitious-brewing#comments]]></comments><pubDate>Wed, 10 Apr 2019 15:22:11 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/ambitious-brewing</guid><description><![CDATA[Steve BallWhat am I doing here?&#8203;&#8203;I gave a presentation at the 2019 European CLA summit titled &ldquo;Applying a SOLID Framework for Cleaner Code&rdquo;.&nbsp; The slides can be found on the &#65279;Composed Systems website&#65279;.&nbsp; I had a great time at the Summit and it was great to meet and talk about LabVIEW with the hundreds of CLAs who attended.&nbsp; I made a large open-source demo project for the presentation that I&rsquo;d like to expand on and give more design detail.  [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><strong><a href="https://www.linkedin.com/in/steveball2/" target="_blank">Steve Ball</a><br /><br />What am I doing here?</strong><br />&#8203;&#8203;I gave a presentation at the 2019 European CLA summit titled &ldquo;Applying a SOLID Framework for Cleaner Code&rdquo;.&nbsp; The slides can be found on the <span>&#65279;</span><a href="https://www.composed.io/presentations" target="_blank">Composed Systems website</a><span>&#65279;</span>.&nbsp; I had a great time at the Summit and it was great to meet and talk about LabVIEW with the hundreds of CLAs who attended.&nbsp; I made a large open-source demo project for the presentation that I&rsquo;d like to expand on and give more design detail.</div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/ambitious-brewing_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><strong>Demo Project Selection</strong><br />&#8203;As an experienced homebrewer, I picked an automated home brewing system as a demo project.&nbsp; There are some open source projects like <a href="https://shop.theelectricbrewery.com/" target="_blank">The Electric Brewery</a> and <a href="http://web.craftbeerpi.com/" target="_blank">CraftBeerPi</a> that are similar, along with a plethora of PLC-based commercial offerings.&nbsp; The hardware complexity is relatively simple, with a few temperature sensors, heating elements, and assorted pumps and valves.&nbsp; There are a half dozen brewing steps that always run in the same sequential order, limiting the control complexity.</div>  <div class="paragraph"><strong>The Challenge&nbsp;</strong><br />&#8203;With these existing open source and commercial solutions, is it possible to create a fully featured, single board system with a rich user interface and feature set while keeping the cost about the same?&nbsp; Could it be configurable enough to work on systems with different plumbing configurations? Could it be done with LabVIEW?<br />&#8203;<br />In my opinion, the answer is YES!</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/20180411-083910_orig.jpg" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">The 20 gallon homebrewing system before automation</div> </div></div>  <div class="paragraph"><strong>Making it Real</strong><br />&#8203;I&rsquo;m working with a friend to turn his 20 gallon, propane-fired homebrewing system into an automated brewing system.&nbsp; This will involve purchasing solenoid valves and swapping the propane burners out for electric resistive elements.&nbsp; I&rsquo;ve selected a single board <a href="https://www.udoo.org/udoo-x86/" target="_blank">UDOO x86 </a>computer to act as the brain of the operation.&nbsp; It has an Arduino-compatible module with GPIO onboard.&nbsp; Its low cost and integrated DAQ makes it a good match for a hobbyist project like this one.&nbsp; I&rsquo;ll include a full parts list in the source code as we build the system.&nbsp;</div>  <div class="paragraph"><strong>The Brewing Process</strong><br />The system consists of three vessels: the Hot liquor tank (HLT), Mash Tun (MT), and Boil Kettle (BK).&nbsp; In the current system, the hoses are moved manually depending on the brewing step.&nbsp; The steps are as follows:<br /><em><strong>Preheat</strong> </em>&ndash; The water in the HLT is heated and maintained at the <em>strike temperature</em>.<br /><em><strong>Mash</strong> </em>&ndash; the water is pumped into the MT where it steeps a barley tea called <em>wort</em>.&nbsp; The wort drains into a <em>grant </em>and is then pumped through a heat exchanger in the HLT to maintain temperature and recirculated&nbsp; into the MT.<br /><em><strong>Lauter</strong> </em>&ndash; The mash tun drains into the grant and the wort is pumped into the boil kettle.<br /><em><strong>Boil</strong> </em>&ndash; The wort is then boiled and additions like hops are added at scheduled intervals.<br /><em><strong>Cool</strong> </em>&ndash; The wort is pumped through a plate chiller and is cooled to near ambient.<br />&#8203;<br />At this point the wort is done and can be drained from the system into the primary fermentation vessel and the yeast can be pitched along with any dry hop or other post-boil additions.&nbsp;&nbsp;</div>  <div class="paragraph"><strong>Why automate a homebrewing&nbsp;system?</strong><br /><strong>&#8203;</strong>Adding controls and instrumentation to the system adds cost and complexity.&nbsp; Brewers have been making beer without any of this for literally thousands of years.&nbsp; What are the advantages that this brings?&nbsp; First, controlling the temperatures precisely aids in the repeat-ability of the recipe, as the temperature of the mash controls the activation rate of the starches and sugars in the barley.&nbsp; This leads to the density, or original gravity measurement, which effects everything from alcohol content to body and mouth feel of the finished brew.&nbsp; Most home brewers use a <em>step mash</em> of one temperature.&nbsp; Advanced home brewers and professionals can use a multi-step mash, with rests at several temperatures to get a specific and more complex wort.&nbsp; Automating this step takes out the manual work of controlling the temperature and timing, so you can get a great mash every time.</div>  <div class="paragraph"><strong>The Framework<br />&#8203;</strong>For this project I selected the <a href="https://bitbucket.org/composedsystems/mva-framework" target="_blank">Composed Systems MVA Framework</a>.&nbsp; MVA stands for Mediated Viewable Actors.&nbsp; Not only did I choose it because it is the subject of the presentation, but it is the daily driver that I use every day for my clients.&nbsp; Ethan Stern did a great job following SOLID design principles while adding two critical pieces on top of NI&rsquo;s Actor Framework: A mediated message bus and Model-View-ViewModel design pattern.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/mvvm_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><strong>Separation of Concerns</strong><br />The most fundamental design principles in my mind are how to separate my user interface code from the model/business logic in the application, and how to bind these two entities together.&nbsp; The MVA framework provides this functionality through the use of abstractions for Views, Models, and the ViewModel.&nbsp; Views are thin, Models do the computational work, and the ViewModel binds them together.&nbsp; The mediator pattern is used for messaging and the API imposes rules on how to do so.&nbsp;&nbsp;</div>  <div class="paragraph"><strong>The ViewModel&#8203;</strong><br />The MVA ViewModel has a few responsibilities.&nbsp; As the root actor in the system, it must launch all the startup models and views.&nbsp; It is also the top level View and can handle menu events.&nbsp; Last but not least, it can publish data to the mediator bus.&nbsp; This is critical because Views cannot do this, and any events originating in the View layer that need to be communicated to the Model layer must percolate up to the ViewModel where the event can be translated and published.&nbsp;&nbsp;</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/thin-view_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><strong>Thin Views<br />&#8203;</strong>The View layer exists to display data to people in a meaningful way, and to provide an interface for interaction.&nbsp; The actor core above handles those two cases elegantly using two framework methods.&nbsp; <em>Bind Terminal Value</em> connects the SystemStatusString to the same name and type on the mediator bus.&nbsp; <em>Register for Control Events</em> will send Value Change messages to this actor whenever the buttons are pressed.&nbsp; The button references are bundled to manipulate the button state and visibility.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/application-control-stack_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%">The application control stack</div> </div></div>  <div class="paragraph"><strong>Application Control</strong><br />&#8203;With a bunch of asynchronous actors merrily doing their own thing, we need a way to perform the brewing steps in a synchronous way.&nbsp; &nbsp;The Process Model and test steps operate synchronously.&nbsp; The test steps publish model data onto the mediator bus that the asynchronous models respond to.&nbsp; The models then send messages as needed to the concrete hardware to perform actions.&nbsp; The results of these actions are published to the mediator bus to be consumed by models, test steps, and/or views.&nbsp;&nbsp;</div>  <div class="paragraph"><strong>The Test Executive</strong><br />Jon McBee has written an excellent, nearly turing-complete sequencer called @cs/test-executive that you can find over on <a href="https://gpackage.io/packages/@cs/test-executive" target="_blank">GPM</a>&nbsp;(That's G Package Manager, a creation of MGI).&nbsp; This project uses it for straightforward, static sequencing, but it is capable of loops, conditionals, and parallelism.&nbsp; To use it, all my process model needs to do is call get next.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/process-model-get-next_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><strong>Get next element</strong><br />The process model is completely separate from the flow control in the test executive.&nbsp; It only needs to know which brewing step is next.&nbsp; In get next, it receives the test step object and its attributes, then spins up the step and sends it the execute message.&nbsp;</div>  <div class="paragraph"><strong>Check it out<br />&#8203;</strong>This code is all open source (MIT license) and is hosted on the <a href="https://bitbucket.org/composedsystems/ambitiousbrewing/src/master/" target="_blank">Composed Systems Bitbucket</a>.&nbsp; It is a work in progress and I will be continuing to develop this over the next few months as we put the system together.&nbsp; All the Composed Systems packages used to build this project are hosted on <a href="https://gpackage.io/" target="_blank">GPM</a>.&nbsp;The slides from the presentation can be found on the Composed Systems Presentations page over at <a href="http://www.composed.io/">www.composed.io</a>.&nbsp; Thank you for reading!</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong><a href="https://www.linkedin.com/in/steveball2/" target="_blank">Steve Ball</a>&nbsp;</strong>is a partner at Composed Systems and is a Certified LabVIEW Architect bent on producing SOLID open-source LabVIEW projects to share with the LabVIEW community.</div>]]></content:encoded></item><item><title><![CDATA[Not-So-Infinite Reset of Death]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/not-so-infinite-reset-of-death]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/not-so-infinite-reset-of-death#comments]]></comments><pubDate>Tue, 03 Jul 2018 22:48:06 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/not-so-infinite-reset-of-death</guid><description><![CDATA[Ethan Stern   I have been working on some pretty large applications lately that have highly dynamic behavior. Actors are getting launched and closed, views are frequently popping into subpanels--that kind of thing. At some point pretty far into my development, I started getting this dialog when my executable (EXE) shut down. It seemed harmless enough, until I realized it was not going away...ever.I did the usual web snooping and stumbled on this LAVA post. Infinite Reset of Death sounds about ri [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><strong><a href="http://www.linkedin.com/in/ethan-stern" target="_blank">Ethan Stern</a></strong></div>  <span class='imgPusher' style='float:right;height:0px'></span><span style='display: table;width:352px;position:relative;float:right;max-width:100%;;clear:right;margin-top:0px;*margin-top:0px'><a><img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/published/irod-dialog.png?1530659062" style="margin-top: 0px; margin-bottom: 0px; margin-left: 20px; margin-right: 0px; border-width:0; max-width:100%" alt="Picture" class="galleryImageBorder wsite-image" /></a><span style="display: table-caption; caption-side: bottom; font-size: 90%; margin-top: -0px; margin-bottom: 0px; text-align: center;" class="wsite-caption"></span></span> <div class="paragraph" style="display:block;">I have been working on some pretty large applications lately that have highly dynamic behavior. Actors are getting launched and closed, views are frequently popping into subpanels--that kind of thing. At some point pretty far into my development, I started getting this dialog when my executable (EXE) shut down. It seemed harmless enough, until I realized it was not going away...ever.<br /><br />I did the usual web snooping and stumbled on this <a href="https://lavag.org/topic/16192-resetting-vi-arrggghhh/" target="_blank">LAVA post</a>. Infinite Reset of Death sounds about right (IRoD, as I now call it).</div> <hr style="width:100%;clear:both;visibility:hidden;"></hr>  <div>  <!--BLOG_SUMMARY_END--></div>  <h2 class="wsite-content-title">First Stab</h2>  <div class="paragraph">In my first act of attempted remediation, I somewhat arbitrarily added explicit (actually&nbsp;<em>redundant</em>) shutdown to my framework. I don't like the idea of adding code just to see what happens, but I thought that I <em>might </em>avoid the problem by enforcing a more orderly shutdown process. Nope.</div>  <h2 class="wsite-content-title">2nd Stage</h2>  <div class="paragraph">When that failed, I tried mass compiling and rebuilding. I pretty quickly learned something about a river in Egypt and that this problem is also intermittent. It tended to happen sometimes rarely...then constantly (and, of course, most often on the customer's embedded PC).</div>  <h2 class="wsite-content-title">Done Messing Around</h2>  <div class="paragraph">This problem is a strange type of nuisance. When it occurs, I've already done everything I can reasonably do to shut down my application. To be clear, this is&nbsp;<em>not</em>&nbsp;a case of an Actor left silently running. Everything is stopped--I'm sure of it--and LabVIEW is fighting with itself to release resources.<br /><br /><span>I spent a while pondering the safety implications and general dirtiness of the following solution. It was the best I could muster--and I <em>think</em> it is absolutely harmless, s</span>ince all my code is completely done executing (hardware set to safe states, data saved, and resources obtained by LabVIEW closed).<br /><br />Meet Reaper:<br /><strong><a href="https://bitbucket.org/account/user/composedsystems/projects/REAP" target="_blank">https://bitbucket.org/account/user/composedsystems/projects/REAP</a></strong><br /><br />The idea is super simple--kill the specified task through Windows command prompt. (Only works on Windows, of course.)<br /><br />Call <strong>Collect Application.vi</strong> when you are ready to reap. You will, of course, want to call this&nbsp;<em>after</em>&nbsp;all of your code is done running. (The same place you might have called the <strong>Quit LabVIEW</strong> function)</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:20px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/collect-application_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><span>Which runs a pre-built LabVIEW EXE that calls a Windows batch file:&#8203;</span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:20px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/reaper-source_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">You see this while reaper works:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:20px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/reaper-dialog_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">...And that's the end of your application. No doubt about it. If you go this route, you'll need to build a reaper in whichever version of LabVIEW run-time you are deploying. You must also include the EXE and its batch file in your buildspec but, if you read this far and understood what I was talking about, you probably already knew that.<br /><br />&#8203;Happy reaping!</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph">&#8203;<strong>Ethan Stern</strong>&nbsp;is a Managing Partner at Composed Systems&nbsp;and is&nbsp;a Certified LabVIEW Architect, Certified LabVIEW Embedded Developer, NI Certified Professional Instructor, and SOLID software enthusiast.</div>]]></content:encoded></item><item><title><![CDATA[LV2017: The Future is Malleable]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/lv2017-the-future-is-malleable]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/lv2017-the-future-is-malleable#comments]]></comments><pubDate>Mon, 09 Oct 2017 15:00:00 GMT</pubDate><category><![CDATA[Malleable VIs]]></category><category><![CDATA[Polymorphism]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/lv2017-the-future-is-malleable</guid><description><![CDATA[Ethan Stern   If you haven't already heard--or tried it for yourself--LabVIEW 2017 offers a simple but powerful new language feature that definitely warrants a deeper look.Somehow, I made it all the way to the CLA Summit in Austin--having used LabVIEW 2017 for months--before learning about this. Obviously I neglected to scan the LabVIEW 2017 Features and Changes list. At the very least, this new feature addresses the common tedium of making typed polymorphic APIs. It also potentially addresses a [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><strong><a href="http://www.linkedin.com/in/ethan-stern-33330414" target="_blank">Ethan Stern</a></strong></div>  <span class='imgPusher' style='float:left;height:0px'></span><span style='display: table;width:auto;position:relative;float:left;max-width:100%;;clear:left;margin-top:0px;*margin-top:0px'><a><img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/malleable-vi-icon_orig.png" style="margin-top: 20px; margin-bottom: 10px; margin-left: 0px; margin-right: 10px; border-width:0; max-width:100%" alt="Picture" class="galleryImageBorder wsite-image" /></a><span style="display: table-caption; caption-side: bottom; font-size: 90%; margin-top: -10px; margin-bottom: 10px; text-align: center;" class="wsite-caption"></span></span> <div class="paragraph" style="display:block;">If you haven't already heard--or tried it for yourself--LabVIEW 2017 offers a simple but powerful new language feature that definitely warrants a deeper look.<br /><br />Somehow, I made it all the way to the CLA Summit in Austin--having used LabVIEW 2017 for months--before learning about this. Obviously I neglected to scan the <a href="http://zone.ni.com/reference/en-XX/help/371361P-01/lvupgrade/labview_features/" target="_blank">LabVIEW 2017 Features and Changes</a> list. At the very least, this new feature addresses the common tedium of making typed polymorphic APIs. It also <em>potentially</em> addresses a design problem I've been banging my head on for months. (A little more on that later.)</div> <hr style="width:100%;clear:both;visibility:hidden;"></hr>  <div>  <!--BLOG_SUMMARY_END--></div>  <h2 class="wsite-content-title">What is a Malleable VI?</h2>  <div class="paragraph">For starters, check out the link above to the LabVIEW 2017 new features page. It covers the basics of Malleable VIs quite thoroughly. It turns out, that the strict typing of data wires in LabVIEW, and the abundant polymorphism in the IDE, permit the compiler to make some pretty powerful (i.e. time-saving) assumptions. Let's consider a simple scenario:<ul><li>Wire two DBL numbers to an add node</li><li>Highlight the add node and select <em><strong>Edit --&gt; Create SubVI</strong></em></li><li>The scripted subVI now has two DBL input terminals</li><li>Save the new subVI to disk</li></ul> ...But perhaps we change the source data type later and our calling block diagram now uses integers instead of DBLs. We'll see coercion dots on the subVI's inputs. If we want them to go away, we must either cast the integers to DBLs upstream of the subVI <em>or</em> change the subVI's input terminals to the new integer type.<br /><br />The thing I never wondered until learning about malleable VIs is, <em>why?</em><ul><li>The input tunnels are conduits for data and&nbsp;they establish an expectation--we could say an&nbsp;<em>interface</em>&nbsp;to the outside world.</li><li>HOWEVER, the add node--the only source code inside the example subVI--is polymorphic</li></ul> If everything inside the subVI is polymorphic and can easily handle a different numeric type, why impose this unnecessary rigidity on its connector pane? Now, we don't have to.</div>  <h2 class="wsite-content-title">Make a Malleable VI</h2>  <div class="paragraph">In case you were too busy to read the LabVIEW 2017 features and changes list linked above, here is a comprehensive list of instructions for converting a standard VI to a malleable VI:<ol><li><strong>Change the ".vi" file extension to ".vim"</strong></li></ol>Voila! Your subVI now defines a malleable (i.e. flexible, adaptable, less rigid, quasi-polymorphic) interface for its caller. Wire something in. If that something works, everyone (and the compiler) is happy.<br /><br />In my world these attributes are more often helpful than harmful. Is it good that LabVIEW doesn't treat every VI as malleable? <em>Sure</em>. On the flip side, the behavior exists if you want it, and with only the tiniest effort. Edit-time polymorphism now traverses VI boundaries!</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/vim-in-project_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">What's the performance penalty for this compiler sorcery? As far as I can tell, <em>absolutely none</em>--and this makes complete sense. There <em>should </em>be no performance difference at run-time. The malleable VI is still called statically (in fact, it is inlined) and the compiler checks and adapts type(s) at edit-time. If you did something silly, like try to add strings inside a malleable math VI, you'll get a broken wire.</div>  <h2 class="wsite-content-title">Goodbye (Most) POLY VIs</h2>  <div class="paragraph">This all felt immediately relevant to me because I just recently spun my own polymorphic array functions (in LabVIEW 2015) for <em><strong>Promote</strong></em> and <em><strong>Demote</strong></em> element. I figured I would do it right and make both functions polymorphic so I could reuse these simple widgets in other projects. After a bunch of tedious tinkering, typing, and testing, I had two polymorphic selector VIs, 26 typed instance VIs, and one big annoying compromise--<em>properly</em> handle only <em>my</em> most common data types.<br /><br />Polymorphic selector VI for&nbsp;<strong><em>Promote Element</em></strong>&#8203;:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:20px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/polymorphic-vi-window_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">And the disk footprint for both functions:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/before-malleable-vis_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">With malleable VIs, there is <u>no</u> polymorphic selector VI, and the footprint shrinks to:</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/after-malleable-vis_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Not only is this far easier to write, maintain, <u>and</u> test--it <em>also </em>handles types I chose not to support because I needed to draw the line <em>somewhere</em>. (I originally added that dirty polymorphic variant instance to handle the types I wasn't willing to code explicitly.)<br /><br />In this slick new world, the only thing that matters is whether the input types play nicely with the subVIs and primitives inside the malleable VI. All array element types work just fine, and I only wrote one VI for each behavior (<strong>Promote</strong>,&nbsp;<em><strong>Demote</strong></em>). &#8203;<span>Ladies and gentlemen, I think we have a winner.<br /><br />But surely this requires some new syntax, terminal type, or <strong><em>something</em></strong>?<br />&#8203;NOPE:</span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:20px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/malleable-front-panel_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">I made my VI icon background orange because that's NI's convention with the new malleable VIs added to the palettes. It was simply a style choice.</div>  <span class='imgPusher' style='float:left;height:0px'></span><span style='display: table;width:auto;position:relative;float:left;max-width:100%;;clear:left;margin-top:0px;*margin-top:0px'><a><img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/malleable-block-diagram_orig.png" style="margin-top: 0px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; border-width:0; max-width:100%" alt="Picture" class="galleryImageBorder wsite-image" /></a><span style="display: table-caption; caption-side: bottom; font-size: 90%; margin-top: -10px; margin-bottom: 10px; text-align: center;" class="wsite-caption"></span></span> <div class="paragraph" style="display:block;">I used variants for my malleable array type because they imply "wire anything!" It actually doesn't matter--I could have used input/output arrays of DBL, I32, String, etc.. Setting the VI as malleable tells the compiler to reconcile types at edit time--and it does!</div> <hr style="width:100%;clear:both;visibility:hidden;"></hr>  <h2 class="wsite-content-title">The Future, Service Pack 1</h2>  <div class="paragraph">At the CLA Summit, we got a quick preview of the malleable VI behavior coming in LV2017 Service Pack 1, and that's when I got <em>really</em> jazzed. SP1 malleable VIs will include a form of dynamic dispatch that allows classes to implement non-ancestor methods. GET OUT.<br /><br />For months, I have worked on a home-cooked solution to object-oriented interfaces (the <em>capital "I"</em> interfaces that exist in other languages). After lots of deep thinking, kludgy demo code, and wheel-spinning, I had no good solution that provided clean, composition-based, functionality (probably because it was impossible). No harm in thinking big.<br /><br />...But combine malleability with object-oriented dynamic dispatch (i.e. <em>run-time</em> polymorphism) and you suddenly have a powerful non-hierarchical way of designing classes. If I'm thrilled with the prospect of (almost) never again writing a polymorphic VI, I'm borderline giddy over this interface possibility. I can hardly wait to try some cleaner (and 100% kludge-free) design patterns with the release of LV2017 SP1. Stay tuned.</div>  <div><div style="height: 0px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 30px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong>Ethan Stern</strong><span>&nbsp;is a Managing Partner at Composed Systems</span><span>&nbsp;and is&nbsp;a Certified LabVIEW Architect, Certified LabVIEW Embedded Developer, Certified TestStand Developer, NI Certified Professional Instructor, and a certifiable LabVIEW geek.</span></div>]]></content:encoded></item><item><title><![CDATA[Pane Label Pain]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/pane-label-pain]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/pane-label-pain#comments]]></comments><pubDate>Thu, 16 Mar 2017 12:50:52 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/pane-label-pain</guid><description><![CDATA[Jon McBee  This will be a short post on a minor annoyance with putting together a dynamic UI in LabVIEW. &nbsp;I am currently building a multi-subpanel UI with Stream and my simple actor implementation and was annoyed with the difficulty of registering for events on the individual panes in my UI. &nbsp;This annoyance is rooted in the fact that I neglected to label my panes as they were created. &nbsp;So I wrote a very simple little tool for identifying and labeling populated panes.             F [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><a href="https://www.linkedin.com/in/jon-mcbee-b312b516/" target="_blank">Jon McBee</a></div>  <div class="paragraph">This will be a short post on a minor annoyance with putting together a dynamic UI in LabVIEW. &nbsp;I am currently building a multi-subpanel UI with Stream and my simple actor implementation and was annoyed with the difficulty of registering for events on the individual panes in my UI. &nbsp;This annoyance is rooted in the fact that I neglected to label my panes as they were created. &nbsp;So I wrote a very simple little tool for identifying and labeling populated panes.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/ui_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="paragraph">For context, I am putting together a resizable dynamic UI where I want to pop actors into and out of SubPanels based on user interaction. &nbsp;To accomplish this I put together a UI View Controller Actor whose only job is to handle top level UI scaling and SubPanel ownership, which necessitated the creation of multiple Panes through the use of splitters. &nbsp;Here is a little demo.</div>  <div class="wsite-video"><div class="wsite-video-wrapper wsite-video-height-480 wsite-video-align-center"> 					<div id="wsite-video-container-890841650364358015" class="wsite-video-container" style="margin: 10px 0 10px 0;"> 						<iframe allowtransparency="true" allowfullscreen="true" frameborder="0" scrolling="no" id="video-iframe-890841650364358015" 							src="about:blank"> 						</iframe> 						 						<style> 							#wsite-video-container-890841650364358015{ 								background: url(//www.weebly.comhttp://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/resizing_ui_demo_151.jpg); 							}  							#video-iframe-890841650364358015{ 								background: url(//cdn2.editmysite.com/images/util/videojs/play-icon.png?1489599220); 							}  							#wsite-video-container-890841650364358015, #video-iframe-890841650364358015{ 								background-repeat: no-repeat; 								background-position:center; 							}  							@media only screen and (-webkit-min-device-pixel-ratio: 2), 								only screen and (        min-device-pixel-ratio: 2), 								only screen and (                min-resolution: 192dpi), 								only screen and (                min-resolution: 2dppx) { 									#video-iframe-890841650364358015{ 										background: url(//cdn2.editmysite.com/images/util/videojs/@2x/play-icon.png?1489599220); 										background-repeat: no-repeat; 										background-position:center; 										background-size: 70px 70px; 									} 							} 						</style> 					</div> 				</div></div>  <div class="paragraph">In the demo the white areas are subpanels where actor UI's will be visible at run time. &nbsp;In the middle of the screen you can see the hamburger control that allows the user to slide the leftmost subpanels left or right. &nbsp;In order to make sure that the hamburger was always centered vertically in its pane I had to detect a pane resize, which required that I know the pane name. &nbsp;Since I neglected to name the panes as I created them, and was too lazy to delete the subpanels in each pane so that I could see it's label and change it I see this list when I try to add an event to the event structure.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/pane-names_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">My first thought was to drop some trash code on the block diagram to programmatically re-label the panes so that I could work with them in the event structure.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/pane-label_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">But this bit of code throws error 1073, "This property is writable only when the VI is in edit mode, or this method is available only when the VI is in edit mode."</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/panel-label-error_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">So like any other software developer with an idea they want to try out, instead of moving my subpanels and changing the pane labels manually by right clicking on the splitterbars, I wrote a simple little tool.</div>  <div class="wsite-video"><div class="wsite-video-wrapper wsite-video-height-480 wsite-video-align-center"> 					<div id="wsite-video-container-644883229996440903" class="wsite-video-container" style="margin: 10px 0 10px 0;"> 						<iframe allowtransparency="true" allowfullscreen="true" frameborder="0" scrolling="no" id="video-iframe-644883229996440903" 							src="about:blank"> 						</iframe> 						 						<style> 							#wsite-video-container-644883229996440903{ 								background: url(//www.weebly.comhttp://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/relabeling_panes_539.jpg); 							}  							#video-iframe-644883229996440903{ 								background: url(//cdn2.editmysite.com/images/util/videojs/play-icon.png?1489599220); 							}  							#wsite-video-container-644883229996440903, #video-iframe-644883229996440903{ 								background-repeat: no-repeat; 								background-position:center; 							}  							@media only screen and (-webkit-min-device-pixel-ratio: 2), 								only screen and (        min-device-pixel-ratio: 2), 								only screen and (                min-resolution: 192dpi), 								only screen and (                min-resolution: 2dppx) { 									#video-iframe-644883229996440903{ 										background: url(//cdn2.editmysite.com/images/util/videojs/@2x/play-icon.png?1489599220); 										background-repeat: no-repeat; 										background-position:center; 										background-size: 70px 70px; 									} 							} 						</style> 					</div> 				</div></div>  <div class="paragraph">There is nothing fancy about the pane re-labeling tool, it is so simple that I don't think it is worth my time to package it and give it away. &nbsp;Instead I will just show you screenshots of the block diagram so you can write it yourself in whatever version of LabVIEW you like.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/block-diagram-1_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Zooming in on the pane discovery bit before the while loop.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/pane-discovery_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">Counting the panel close event case, the event structure has three event cases. &nbsp;Here is a look at the handling of the doubleclick on the listbox.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/doubleclick_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">And here is a look at the right click on the listbox.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/right-click_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">In summary, this wouldn't have been a hard problem to solve manually but I figured I would write a short post on how I beat it to death with VI Server.</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong>Jon McBee</strong><span>&nbsp;is the Founder and Managing Partner at Composed Systems</span><span>&nbsp;and is&nbsp;a Certified LabVIEW Architect, Certified LabVIEW Embedded Developer, Certified TestStand Developer, an NI Certified Professional Instructor, a LabVIEW Champion, and a Certified ScrumMaster</span></div>]]></content:encoded></item><item><title><![CDATA[ØMQ Extension for Stream]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/mq-extension-for-stream]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/mq-extension-for-stream#comments]]></comments><pubDate>Mon, 06 Mar 2017 01:23:58 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/mq-extension-for-stream</guid><description><![CDATA[Jon McBee  I've been wanting to write a network extension for Stream for about a year now, adding the ability to extend the mediator to the network and allow pub/sub between actors on different machines. &nbsp;I finally got the motivation to do it after starting to collaborate with Jarobit Pe&ntilde;a&nbsp;Saez at Bits 2 Byte&nbsp;on the Stream project. &nbsp;This extension is a result of our collaboration efforts and the sharing of ideas.              					 						 						 						 						 							#w [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><a href="https://www.linkedin.com/in/jon-mcbee-b312b516/" target="_blank">Jon McBee</a></div>  <div class="paragraph">I've been wanting to write a network extension for Stream for about a year now, adding the ability to extend the mediator to the network and allow pub/sub between actors on different machines. &nbsp;I finally got the motivation to do it after starting to collaborate with <a href="https://www.linkedin.com/in/jarobit-pi%C3%B1a-saez-bb58922b/" target="_blank">Jarobit Pe&ntilde;a&nbsp;Saez</a> at <a href="http://bits2byte.net/" target="_blank">Bits 2 Byte</a>&nbsp;on the Stream project. &nbsp;This extension is a result of our collaboration efforts and the sharing of ideas.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/stream-logo-zmq_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="wsite-video"><div class="wsite-video-wrapper wsite-video-height-480 wsite-video-align-center"> 					<div id="wsite-video-container-602845682894325099" class="wsite-video-container" style="margin: 10px 0 10px 0;"> 						<iframe allowtransparency="true" allowfullscreen="true" frameborder="0" scrolling="no" id="video-iframe-602845682894325099" 							src="about:blank"> 						</iframe> 						 						<style> 							#wsite-video-container-602845682894325099{ 								background: url(//www.weebly.comhttp://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/stream_and_zmq_611.jpg); 							}  							#video-iframe-602845682894325099{ 								background: url(//cdn2.editmysite.com/images/util/videojs/play-icon.png?1488847911); 							}  							#wsite-video-container-602845682894325099, #video-iframe-602845682894325099{ 								background-repeat: no-repeat; 								background-position:center; 							}  							@media only screen and (-webkit-min-device-pixel-ratio: 2), 								only screen and (        min-device-pixel-ratio: 2), 								only screen and (                min-resolution: 192dpi), 								only screen and (                min-resolution: 2dppx) { 									#video-iframe-602845682894325099{ 										background: url(//cdn2.editmysite.com/images/util/videojs/@2x/play-icon.png?1488847911); 										background-repeat: no-repeat; 										background-position:center; 										background-size: 70px 70px; 									} 							} 						</style> 					</div> 				</div></div>  <div class="paragraph">&#8203;&#8203;I decided to use <a href="http://zeromq.org/" target="_blank">&Oslash;MQ</a> (pronounced zero-em-queue) as it is a free messaging library for use in distributed applications that handles the TCP socket layer for you. &nbsp;The base implementation is done in C++ but there are bindings for most popular languages including this <a href="http://labview-zmq.sourceforge.net/" target="_blank">binding for LabVIEW</a>, which I used. &nbsp;A cool aspect of the many bindings available is that &Oslash;MQ makes it easy to setup messaging not only between machines on network but between machines running different operating systems and using different programming languages. &nbsp;As you saw in the demo above it was pretty trivial to connect Stream in LabVIEW to a simple Python script using &Oslash;MQ. &nbsp;&Oslash;MQ has great documentation, I recommend that you read more <a href="http://zeromq.org/intro:read-the-manual" target="_blank">here</a>.</div>  <div class="paragraph">&#8203;Let's establish a little vocabulary so we can discuss the design. &nbsp;The &Oslash;MQ Network Extension for Stream is meant to allow Stream actors to communicate across a network without the need to write any TCP/IP level code. &nbsp;Let's refer to a system of actors on a machine as a microsystem, and the system comprised of many machines as a system. &nbsp;We can now say that our system is comprised of many microsystems where each microsystem is comprised of many actors. &nbsp;In the current implementation of the &Oslash;MQ Network Extension for Stream there must only be one server per system, and it is up to the developer to make this so. &nbsp;I don't love the fact that we need a server and think that the design can be improved, but as it stands today there must be one server to rule them all, one server to find them, one server to bring them all and in the darkness bind them (as the saying goes).</div>  <div class="paragraph">&#8203;Within each microsystem there can be one or more mediators, this is really a design decision left to the architect. &nbsp;I typically only have one mediator per microsystem but I know others like to spin up one global mediator per microsystem and one private mediator for each actor in the microsystem. &nbsp;One thing to keep in mind with this implementation is that every mediator creates its own &Oslash;MQ context, and then using the context to create sockets. &nbsp;The context is the container for all sockets in a single process and the &Oslash;MQ guide recommends "Do one create context at the start of your main line code, and one destroy context at the end."</div>  <div class="paragraph">&#8203;So how does the &Oslash;MQ Network Extension for Stream work? &nbsp;At a high level the extension is a message broker that uses the &Oslash;MQ Publish/Subscribe pattern as the transport, and serialized JSON data packets as the data message. &nbsp;The system level server maintains a list clients and spins up LabVIEW Topic Actor for each unique topic in the system. &nbsp;The Topic Actors are assigned an available port and the server handles distributing the updated ports to all known clients as they come in. &nbsp;The Topic Actors then each subscribe to the appropriate &Oslash;MQ endpoint and register as publishers on the appropriate local Stream topics. &nbsp;For this to work each message object must override the Pack.vi and Unpack.vi methods, these methods handle serialization and deserialization of the message objects.</div>  <div class="paragraph">One nice thing about using &Oslash;MQ is that it handles a lot of the hard stuff for you. &nbsp;&Oslash;MQ doesn't care if the server or the clients spin up first, it handles reconnecting after network dropouts, and makes it easy to bring the clients or the server down and back up again without the entire system going down. &nbsp;I did add a client heartbeat message to the server so that when clients go down the server recognizes it and broadcasts the change to the other clients. &nbsp;Likewise, if I bring the server down it will alert the clients, allowing each microsystem to run isolated until a new server spins up, at which point the mediator stitches the topics back together.</div>  <div class="paragraph">As it stands right now the &Oslash;MQ Network Extension for Stream works as designed, but there are a handful of design decisions that I would like to change. &nbsp;If you would like to contribute or collaborate on this project please let us know! &nbsp;The code for this project has been open sourced under an MIT license and can be found at this <a href="https://bitbucket.org/composedsystems/zeromq-extension-for-stream" target="_blank">Composed Systems Bitbucket page</a>.</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong>Jon McBee</strong><span>&nbsp;is the Founder and Managing Partner at Composed Systems</span><span>&nbsp;and is&nbsp;a Certified LabVIEW Architect, Certified LabVIEW Embedded Developer, Certified TestStand Developer, an NI Certified Professional Instructor, a LabVIEW Champion, and a Certified ScrumMaster</span></div>]]></content:encoded></item><item><title><![CDATA[Data Visualization with XControls & JavaScript]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/data-visualization-with-xcontrols-javascript]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/data-visualization-with-xcontrols-javascript#comments]]></comments><pubDate>Thu, 23 Feb 2017 01:57:23 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/data-visualization-with-xcontrols-javascript</guid><description><![CDATA[Jon McBee  I recently needed to create a small LabVIEW application that would allow my customers to view and interact with data they had acquired. &nbsp;As much as I love LabVIEW I really don't love trying to make sleek UI's for data visualization using LabVIEW. &nbsp;So I decided to tinker with embedding JavaScript UI elements in LabVIEW front panels using XControls. &nbsp;It ended up being more fun than it sounds.                    I knew that I wanted a JavaScript charting package and so I d [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><a href="https://www.linkedin.com/in/jon-mcbee-b312b516/" target="_blank">Jon McBee</a></div>  <div class="paragraph">I recently needed to create a small LabVIEW application that would allow my customers to view and interact with data they had acquired. &nbsp;As much as I love LabVIEW I really don't love trying to make sleek UI's for data visualization using LabVIEW. &nbsp;So I decided to tinker with embedding JavaScript UI elements in LabVIEW front panels using XControls. &nbsp;It ended up being more fun than it sounds.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/line-chart_1_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/chartli_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">I knew that I wanted a JavaScript charting package and so I did a little Googling and I found too many to count. &nbsp;I decided to buy a canned package that had examples that fit what I wanted to do because there is no way that I could build what I wanted myself for $20 worth of effort. &nbsp;I came across a package called <a href="https://codecanyon.net/item/chartli-interactive-chart/14957273" target="_blank">Chartli</a> on codecanyon for $20, it seemed to fit my use case so I purchased a license.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/html-javascript_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">The tangible artifacts that I purchased were HTML files with JavaScript code, JavaScript files, and CSS files. &nbsp;We don't typically deal with these types of artifacts as LabVIEW developers but there is no reason we can't. &nbsp;In fact there is a nice example that ships with LabVIEW called "ActiveX Event Callback.vi", this example uses the Microsoft WebBrowser ActiveX control to load a webpage in the ActiveX control so that it can be embedded in a LabVIEW VI's front panel. &nbsp;As luck would have it, the Chartli package I purchased was just a bunch of webpages that I could tweak and embed in an ActiveX Control.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/activex-event-callback_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph">So I now had a way to take the webpage component and view it on a LabVIEW VI's front panel using the ActiveX control. &nbsp;Notice that the Web Page URL is actually pointing to a local file on my hard drive. &nbsp;I don't even need to host the html file for the ActiveX control to be able to run it; and run it is the correct way to talk about it because when the HTML page is loaded it actually executes the JavaScript code embedded inside it. &nbsp;This is cool because it gives me a way to use JavaScript to handle UI elements, which, let's be honest, look and act nicer than anything I want to build with LabVIEW.</div>  <div class="wsite-video"><div class="wsite-video-wrapper wsite-video-height-480 wsite-video-align-center"> 					<div id="wsite-video-container-264329540844686649" class="wsite-video-container" style="margin: 10px 0 10px 0;"> 						<iframe allowtransparency="true" allowfullscreen="true" frameborder="0" scrolling="no" id="video-iframe-264329540844686649" 							src="about:blank"> 						</iframe> 						 						<style> 							#wsite-video-container-264329540844686649{ 								background: url(//www.weebly.comhttp://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/video_104.jpg); 							}  							#video-iframe-264329540844686649{ 								background: url(//cdn2.editmysite.com/images/util/videojs/play-icon.png?1487806352); 							}  							#wsite-video-container-264329540844686649, #video-iframe-264329540844686649{ 								background-repeat: no-repeat; 								background-position:center; 							}  							@media only screen and (-webkit-min-device-pixel-ratio: 2), 								only screen and (        min-device-pixel-ratio: 2), 								only screen and (                min-resolution: 192dpi), 								only screen and (                min-resolution: 2dppx) { 									#video-iframe-264329540844686649{ 										background: url(//cdn2.editmysite.com/images/util/videojs/@2x/play-icon.png?1487806352); 										background-repeat: no-repeat; 										background-position:center; 										background-size: 70px 70px; 									} 							} 						</style> 					</div> 				</div></div>  <div class="paragraph">So this is where the XControls come in. &nbsp;If you aren't familiar with XControls in LabVIEW then take a look <a href="http://www.ni.com/tutorial/3198/en/" target="_blank">here</a>. &nbsp;I didn't need to build much functionality into my XControls because I was only using them to encapsulate my hackery of programmatically updating HTML files and refreshing the webpage in the ActiveX control.</div>  <div class="paragraph">To finish I will mention a few caveats. &nbsp;These aren't speedy and I wouldn't use them for display of live data. &nbsp;Their responsiveness suffers with large amounts of data, for this reason I ended up creating a hybrid LabVIEW chart HTML+JavaScript chart that allowed me to do visualization for decimation of the data in LabVIEW and then push a decimated set of data up to HTML+JavaScript for fancy viewing. &nbsp;Another caveat is licensing, if you go the route I went and purchase code from someone else be sure that their license fits your use case. &nbsp;In my case <a href="https://codecanyon.net/licenses/terms/regular" target="_blank">the license I purchased</a> allows me to use this package once and distribute it to customers without selling it to them. &nbsp;If you download the code I post then you inherit that <a href="https://codecanyon.net/licenses/terms/regular" target="_blank">license</a> along with this text here:</div>  <div class="paragraph"><em><span style="color:rgb(68, 68, 68)"><font size="1">THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</font></span></em></div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong>Jon McBee</strong><span>&nbsp;is the Founder and Managing Partner at Composed Systems</span><span>&nbsp;and is&nbsp;a Certified LabVIEW Architect, Certified LabVIEW Embedded Developer, Certified TestStand Developer, an NI Certified Professional Instructor, a LabVIEW Champion, and a Certified ScrumMaster</span></div>  <div><div style="margin: 10px 0 0 -10px"> <a href="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/data_vis.zip"><img src="//www.weebly.com/weebly/images/file_icons/gz.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> data_vis_LV2016.zip</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>3404 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> zip</td></tr></table><a href="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/data_vis.zip" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>]]></content:encoded></item><item><title><![CDATA[Semantic Versioning]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/semantic-versioning]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/semantic-versioning#comments]]></comments><pubDate>Tue, 14 Feb 2017 12:57:15 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/semantic-versioning</guid><description><![CDATA[Jon McBee  &#8203;One of the many things I can stand to improve upon is how I version my software. &nbsp;I say this because throughout my career I have never adhered to a strict versioning scheme for the software I write. &nbsp;This has been tolerable because my decisions typically only impacted me or at worst my team, but now that I am diving into the world of open-sourced software I think it is time to embrace a standard for software versioning.             In my research to understand what ot [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><a href="https://www.linkedin.com/in/jon-mcbee-b312b516/" target="_blank">Jon McBee</a></div>  <div class="paragraph">&#8203;One of the many things I can stand to improve upon is how I version my software. &nbsp;I say this because throughout my career I have never adhered to a strict versioning scheme for the software I write. &nbsp;This has been tolerable because my decisions typically only impacted me or at worst my team, but now that I am diving into the world of open-sourced software I think it is time to embrace a standard for software versioning.</div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/published/software-version-nightmare.png?1487081418" alt="Picture" style="width:318;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="paragraph">In my research to understand what other people are doing with regard to versioning their software I came across the <a href="http://semver.org/#semantic-versioning-specification-semver" target="_blank">Semantic Versioning specification (SemVer)</a>. &nbsp;I'll be honest there is nothing earth shattering here, SemVer follows the standard X.Y.Z (Major.Minor.Patch) semantics for versioning that we probably all already use. &nbsp;What SemVer adds to the discussion is a very well defined standard for how/when/why the X.Y.Z versioning numbers are changed. &nbsp;This is important with open source projects like Stream because if we all agree to follow this standard then we now have a common language we can use to discuss changes to the software and what impacts those changes have on our respective code bases.</div>  <div class="paragraph">SemVer is made up of a list of 11 rules that dictate how software versions are updated. &nbsp;At a high level the software version number is structured as Major.Minor.Patch where the components are incremented as follows:<ul><li>Major version is incremented when you make incompatible API changes</li><li>Minor version is incremented when you add functionality in a backwards-compatible manner<br /></li><li>Patch version is incremented when you make backwards-compatible bug fixes<br><br /></li></ul>&#8203;We can see that the Patch version number identifies the number of backwards-compatible bug fixes that have been implemented under the current Minor version. &nbsp;SemVer defines a bug as an "internal change that fixes incorrect behaviour". &nbsp;The Minor version number identifies the number of backwards-compatible features that are added to the current Major version. &nbsp;This number is also incremented when existing features have been deprecated but not yet removed from the codebase. &nbsp;The Major version number identifies backwards-incompatible changes to the codebase. &nbsp;This a subtely powerful feature of SemVer because it allows me to guarantee that a consumer of my open-source code can update my published package without breaking their code that depends on my package as long as the Major version does not change.<br /></div>  <div class="paragraph">In the context of <a href="https://bitbucket.org/composedsystems/stream" target="_blank">Stream</a> I like the idea of using SemVer to explicitly define how releases are versioned. &nbsp;When you decide to use a package that I publish you and I have entered into an agreement that allows you to make a few assumptions. &nbsp;These assumptions include that I will maintain the code base behind the package, I will notify you when I make changes to the code base, and that I will give you the information that you need to decide if you want to adopt the new version or not. &nbsp;SemVer helps to remove the risk from the assumptions by explicitly defining how my changes impact your code base.</div>  <div class="paragraph">I encourage you to take a look at the <a href="http://semver.org/#semantic-versioning-specification-semver" target="_blank">SemVer specification</a> and would be interested to hear your thoughts on it. &nbsp;I am also curious how you handle versioning your software and if you have adopted a formal defintion for your versioning semantics. &nbsp;I will be using SemVer for all open-source projects that I publish on the Composed System Bitbucket page moving forward. &nbsp;Hopefully this decision will make it easier for you to use and participate in our open-sourced projects.</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong>Jon McBee</strong><span>&nbsp;is the Founder and Managing Partner at Composed Systems</span><span>&nbsp;and is&nbsp;a Certified LabVIEW Architect, Certified LabVIEW Embedded Developer, Certified TestStand Developer, an NI Certified Professional Instructor, a LabVIEW Champion, and a Certified ScrumMaster</span></div>]]></content:encoded></item><item><title><![CDATA[The God of Software]]></title><link><![CDATA[http://www.labviewcraftsmen.com/blog/the-god-of-software]]></link><comments><![CDATA[http://www.labviewcraftsmen.com/blog/the-god-of-software#comments]]></comments><pubDate>Wed, 01 Feb 2017 05:00:00 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.labviewcraftsmen.com/blog/the-god-of-software</guid><description><![CDATA[Jon McBee  I love reading about ancient Roman history and I also love reading about software design. &nbsp;Occasionally those two areas of interest smash together in my brain and weird ideas come out. &nbsp;This post is one of those weird ideas, I'd like to introduce you to Janus, the god of software.             Janus is the ancient Roman god of&nbsp;beginnings, gates, transitions, time, doorways, passages, and endings. &nbsp;As the god of transition&nbsp;Janus presided over the beginning and e [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><a href="https://www.linkedin.com/in/jon-mcbee-b312b516" target="_blank">Jon McBee</a></div>  <div class="paragraph"><span>I love reading about ancient Roman history and I also love reading about software design. &nbsp;Occasionally those two areas of interest smash together in my brain and weird ideas come out. &nbsp;This post is one of those weird ideas, I'd like to introduce you to Janus, the god of software.</span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="http://www.labviewcraftsmen.com/uploads/9/9/6/4/9964672/f091ee44659a1b75cd15d82ad2c2e87f_orig.jpg" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div>  <!--BLOG_SUMMARY_END--></div>  <div class="paragraph">Janus is the ancient Roman god of&nbsp;beginnings, gates, transitions, time, doorways, passages, and endings. &nbsp;As the god of transition&nbsp;Janus presided over the beginning and ending of conflict, and hence the doors of his temple were open in time of war, and closed to mark the peace throughout the ancient Roman republic.</div>  <div class="paragraph"><font color="#2a2a2a">In Latin Janus is spelled <em>Ianus&nbsp;</em>and Cicero explains the etymology of the name as being derived from the verb <em>ire</em>, meaning <em>to go</em>. &nbsp;From <em>Ianus </em>we get the words <em>ianua</em>, which is <em>door</em>, and <em>ianitor</em>, which is <em>janitor</em>. &nbsp;Saving the topic of janitor being derived from Janus for later, we can begin to see that&nbsp;Janus embodies the idea of&nbsp;&nbsp;transitional movement, which we will call&nbsp;<em>change</em>. &nbsp;Extrapolating&nbsp;one step further we can say that Janus is the god of change.</font></div>  <div class="paragraph">In his Clean Code series, Robert Martin (a.k.a. Uncle Bob) talks about the primary and secondary values of software. &nbsp;Uncle Bob states that software's secondary value, which is the type of value we are most familiar with, is that our software does what our customer wants it to do today. &nbsp;Our customers typically have this secondary value in mind when they evaluate what we deliver to them.</div>  <div class="paragraph">However, Uncle Bob claims that our software's primary value is that it is soft, i.e. it is able to meet the changing needs of the changing customers. &nbsp;This statement has a profound impact on how we both interact with our customers and write our software. &nbsp;It is this idea of change that is core to the principles of agile software development.</div>  <div class="paragraph"><span>Janus is typically depicted as having two faces, one looking into the past and one looking into the future. &nbsp;</span><span>&#8203;As software developers we don't have the luxury of being able to look into the future and so we have to move forward knowing that change is inevitable. &nbsp;We account for this inevitable change by cleaning our code as we write it, so that our code is able to embrace the changes as they come.</span></div>  <div class="paragraph">So let's embrace Janus as the ancient Roman god of software development. &nbsp;Janus embodies change and as software developers we need to embrace change. &nbsp;Closing the etymology loop, we saw before that the word janitor comes from combining Janus with the suffix <em>-tor</em>, meaning&nbsp;"caretaker of a building, person employed to see that rooms are kept clean and in order". &nbsp;As software developers we act as janitors of our code, caretakers focused on keeping it clean and in order. &nbsp;It is by being janitors of our code that we are able to deliver on our software's primary value.</div>  <div><div style="height: 20px; overflow: hidden; width: 100%;"></div> <hr class="styled-hr" style="width:100%;"></hr> <div style="height: 20px; overflow: hidden; width: 100%;"></div></div>  <div class="paragraph"><strong>Jon McBee</strong><span>&nbsp;is the Founder and Managing Partner at Composed Systems</span><span>&nbsp;and is&nbsp;a Certified LabVIEW Architect, Certified LabVIEW Embedded Developer, Certified TestStand Developer, an NI Certified Professional Instructor, a LabVIEW Champion, and a Certified ScrumMaster</span></div>]]></content:encoded></item></channel></rss>