Overview
The Feedback Evaporative Cooler sample project implements an evaporative cooler with hot-swappable hardware, controllers, and user interfaces. The sample project is made up of multiple independently-running VIs, called actors, that represent the user interface, the cooler, its fans, and its water level. Each actor has the ability to pass command-like messages to, and receive such messages from, related actors. The architecture supports expansion for statically or dynamically including more actors.
Table of Contents
- Developer Walkthrough
- System Requirements
- Running this Sample Project
- Overview
- Design Notes
- Important Information
![]() |
Note This template makes extensive use of LabVIEW classes. Designing an application with the Actor Framework requires familiarity with principles of object-oriented programming in LabVIEW. This document provides the information necessary to understand and modify the Feedback Evaporative Cooler sample project. For more information about designing applications with the Actor Framework, refer to the Actor Framework Whitepaper in the Project Documentation folder of the Project Explorer window. |
This sample project is based on the Actor Framework template. Refer to the Actor Framework template and its documentation, available from the Create Project dialog box, for information about how this template works.
Developer Walkthrough
See a Developer Walkthrough of the Actor framework here. More Documentation on Actor Framework here.
System Requirements
LabVIEW Base, Full, or Professional Development System
Running this Sample Project
- In the Project Explorer window, open and run Application»Application Launcher.lvlib»Splash Screen.vi.
- Change the Desired Temperature and watch the fans and water pump activate to control the Actual Temperature. The controller has a deadband zone of five degrees, which means that if you set the Desired Temperature to 75 degrees, the Actual Temperature will rise to 80 degrees before the cooling process begins.
- Control the simulation:
- In the Project Explorer window, open Model»Simulated Hardware»Simulated Evaporative Cooler.lvclass»Simulated Data_Global.vi.
- Adjust the Simulation Inputs and watch the application respond.
- Switch to the programmatic interface by clicking UI Option 2 in the user interface. The application loads the programmatic controller and user interface into memory. This controller executes a Program Sequence of desired temperatures that you cannot modify. You can retake control of the desired temperature by clicking UI Option 1.
- Click Stop All to shut down the application.
Overview
The top-level actor loads either a simulated evaporative cooler or a real one and starts the cooler running. The sample project has two controller interfaces, one you can control and one that is pre-programmed, that you can dynamically swap between. Because each evaporative cooler and controller is an actor, you can add coolers and controllers without modifying the majority of the sample project.
The following list shows the inheritance tree of this sample project and explains the capabilities of each actor:
- Actor (Actor.lvclass)—The ancestor of all actors in LabVIEW.
- Application actor (Air Cooler Application.lvclass)—The actor that represents the application itself. This actor launches the Live User Controller actor and an Evaporative Cooler actor. The specific Evaporative Cooler actor that is launched depends on what is contained in the Air Cooler App.ini configuration file.
- Timed Loop actor (Timed Loop Actor.lvclass)—Repeats a process every n milliseconds.
- Level Controller actor (Level Controller.lvclass)—Monitors a variable. This actor takes one action if that variable goes above a threshold and takes a different action if that variable goes below a threshold.
- Cooler actor (Cooler.lvclass)—Monitors the indoor air temperature and starts a cooling process to keep the temperature within a range.
- Evaporative Cooler actor (Evaporative Cooler.lvclass)—Defines an evaporative cooling process, which is a cooling process that can report information about controlling a water pump/dual fan system.
- Simulated Evaporative Cooler actor (Simulated Evaporative Cooler.lvclass)—Defines a simulated evaporative cooler, which is an evaporative cooler that communicates with a simulated fan and a simulated water pump.
- Hardware Evaporative Cooler actor (HW Evaporative Cooler.lvclass)—Defines a real evaporative cooler, which is an evaporative cooler that communicates with a real fan and a real water pump.
- Evaporative Cooler actor (Evaporative Cooler.lvclass)—Defines an evaporative cooling process, which is a cooling process that can report information about controlling a water pump/dual fan system.
- Water Level actor (Water Level.lvclass)—Represents a water pump.
- Simulated Water Level actor (Simulated Water Level.lvclass)—Simulates a water pump.
- Hardware Water Level actor (HW Water Level.lvclass)—Communicates with a real water pump.
- Cooler actor (Cooler.lvclass)—Monitors the indoor air temperature and starts a cooling process to keep the temperature within a range.
- Dual Fan actor (Dual Fan.lvclass)—Represents a dual fan system.
- Simulated Dual Fan actor (Simulated Dual Fan.lvclass)—Simulates a dual fan system.
- Hardware Dual Fan actor (HW Dual Fan.lvclass)—Communicates with a real dual fan system.
- Level Controller actor (Level Controller.lvclass)—Monitors a variable. This actor takes one action if that variable goes above a threshold and takes a different action if that variable goes below a threshold.
- Cooler Controller actor (Cooler Controller.lvclass)—Controls a Cooler actor.
- Evaporative Cooler Controller actor (Evaporative Cooler Controller.lvclass)—Controls an Evaporative Cooler actor.
- Live User Controller actor (Live User Controller.lvclass)—Displays a user interface for controlling an Evaporative Cooler actor.
- Programmatic Controller actor (Programmatic Controller.lvclass)—Controls a actor by executing a pre-programmed sequence of desired temperatures.
- Evaporative Cooler Controller actor (Evaporative Cooler Controller.lvclass)—Controls an Evaporative Cooler actor.
This sample project uses the actors listed above to implement the following features:
- Hardware abstraction layer (HAL)—A HAL is a layer of software that enables you to write general instructions that can execute on a variety of specific targets. You send general commands to the HAL, which is programmed to interpret these general commands into specific ones that a target needs. To add a target, just provide the necessary interpretation of the general commands.
For example, GPIB and DAQ devices perform the same general operations (open task, write data, and so on); however, they each use a different API. You can design an application to send a general command to the HAL, which then sends the device-specific command to the target you select.
To demonstrate a HAL, this sample project includes actors that represent two evaporative coolers. Each actor performs the same task but in a different way. The simulated evaporative cooler reads a simulated fan status from a VI, whereas the hardware evaporative cooler reads a real fan status from an actual hardware device. The HAL is the software layer between these two actors and the programmatic interface. To add an evaporative cooler, define an actor that overrides the methods defined in the HAL and supplies the commands necessary for the evaporative cooler you want to add. - Hot-swappable user interfaces—This sample project features two user interfaces — a live user interface that you can control and a pre-programmed controller you cannot. Each user interface is defined as an actor. Each actor receives the same messages but displays them differently. Because LabVIEW can dynamically start and stop actors, this sample project can stop one user interface and start the other, each time changing the way the messages are displayed.
Design Notes
Hot-Swapping User Interfaces
The Swap Controllers method of the Air Cooler Application class swaps controllers without shutting the application down. Each controller has a different user interface. This method executes the following steps:
- Breaks communication between the current controller and the cooler by giving invalid message enqueuer to the controller and the cooler. The cooler continues running because it is designed to continue running without a controller.
- Launches the new controller.
- Tells the cooler what the new controller is by giving the new controller's self-enqueuer to the cooler.
- Tells the new controller what the cooler is by giving the cooler's self-enqueuer to the new controller.
- Stops the old controller.
While the application is running, you send the Swap Controllers message to the Air Cooler Application actor by clicking UI Option 1 or UI Option 2.
Bypassing the Task Tree
This sample project intentionally breaks the task tree in one location. The Cooler and the Cooler Controller actors are on different branches of the task tree, but this sample project enables them to communicate directly with one another by sending each actor the self enqueuer of the other actor. This code is contained in the Actor Core method of the Air Cooler Application class.
The reason for this direct line of communication is that, the way this sample project is designed, the controller and cooler actors are highly coupled to one another. A cooler needs a controller, and a controller needs a cooler. Sending messages through the Application actor is an unnecessary step.
Localizing User-Visible Strings
Centralizing user-facing strings into one VI minimizes the number of VIs whose user-visible strings must be translated or edited. Many actors in this application define a Localization VI, which acts as a look-up table to facilitate translating strings from one human language to another.
Loading Configuration Information into the Application
This sample project is designed to read configuration data from a file but, since the file will not always be necessary, to provide default values if the file is not present. The Read Config File method of the Air Cooler Application class reads Air Cooler App.ini to determine which evaporative cooler, simulated or real, to use. If this file does not exist, the default cooler is defined in the private data of the Air Cooler Application class.
Launching the Top-Level Actor but Releasing the Message Queue
The way this sample project is designed, the Application actor attempts to send only the standard Last Ack message to its caller, the Load App VI. In this situation, the sample project does not need to act on this message from the Application actor. Therefore, after obtaining the message queue and using it to launch the Application actor, the Load App VI immediately releases the message queue. This action prevents the Application actor from communicating with its caller.
Ignoring Recipient Type When Sending a Message
This sample project contains a few messages that do not check whether the recipient is of the proper type. For example, the Do VI of the Update Pump State Message class instructs an Evaporative Cooler actor to invoke its Update Fan Status method. If the recipient of the message is not an Evaporative Cooler, the message is sent, but the receiving actor does not report an error. This design is acceptable because the message being sent is a status message and therefore is not important.
Because most messages are designed to be received by a specific type of actor, this design contrasts from the typical design of a Do VI, which first checks to see whether the recipient is of the proper type. If this check fails, the Do method returns the error from the To More Specific Class function, reporting it to the Handle Error method of the actor. Most message classes are designed this way to prevent, for example, a DAQ command from being sent to an actor that can understand only GPIB commands.
Obtaining Resources for an Actor Before the Actor Launches
This sample project assigns a unique numeric ID to every Timed Loop actor in a way that meets the following conditions:
- The assignment is guaranteed to be executed by all Timed Loop actors as they start
- The assignment is guaranteed to happen before any of the actor's methods can execute, so the methods can all assume this assignment happened
- If the assignment is not possible for some reason, the actor shuts down
The Pre Launch Init method of the Actor class meets all of these conditions; therefore, the unique assignment happens in this method.
Designing Actors for Reuse
The Dual Fan actor is designed to be reused with any kind of caller, not just the one defined in this sample project. For example, the Dual Fan class in this sample project is used by an evaporative cooler but could be called by a car motor, a hard drive, or a similar device that requires cooling.
To achieve this level of reuse, the Dual Fan actor is designed to send messages to its caller without knowing the type of the caller. In the Actor Framework, this relationship is called the Zero-Coupling Pattern. This pattern is achieved by using what is known as an abstract message instead of a typical message. An abstract message is a message that has the basic setup of a message but lacks the instructions for what the caller does when it receives the message. Instead, each type of caller provides the actor with a set of instructions for that caller.
The following procedure uses the Dual Fan actor, its abstract message, and its caller as an example of the Zero-Coupling Pattern:
| Step | In this Sample Project | ||
|---|---|---|---|
| 1. An abstract message is created. This is the message type that the actor will send to its caller. | The abstract message is the Update Fan Status Msg class. Its Send Update Fan Status method contains an Update Msg Object input.
|
||
| 2. An actor is designed with a placeholder that will contain instructions for its caller. | The actor is the Dual Fan class. The placeholder is the Update Msg element, which is defined in the cluster of private data available to the Dual Fan class. | ||
| 3. An actor is designed with a method that, when invoked, fills in this placeholder. | The Dual Fan actor has a Write Update Fan Status Message method. | ||
| 4. A child of the abstract message is created. The child contains a Do method that is specific to the caller. | The descendant is the Cooler Update Fan Status Msg class. It contains the Do method that is executed when the message is received. The caller is the Evaporative Cooler class; therefore, this Do method is specific to an actor of the Evaporative Cooler type. | ||
| 5. The caller invokes the method that fills in the placeholder of the actor. | The caller is the Evaporative Cooler class. Its Actor Core method invokes the Write Update Fan Status Message method. This invocation fills Update Msg with an object of the Cooler Update Fan Status Msg class. | ||
| 6. The caller launches the actor. | The caller is the Evaporative Cooler class. Its Actor Core method launches the Dual Fan actor. | ||
| 7. The actor sends the abstract message to the caller. When the caller receives the message, it executes the Do method of the message. The Do method was created in step 4 and given to the actor in step 5. | The Update Caller method of the Dual Fan class sends the Update Fan Status Msg class to the Evaporative Cooler actor. This message carries with it the Cooler Update Fan Status Msg class, which contains instructions for the Evaporative Cooler actor on how to process the message. |
Designing an actor for reuse introduces some programming complexity. However, the benefit of this design is that you can reuse the actor with any type of caller. Because the actor has a placeholder designed to be filled in by a caller, you create one descendant of the abstract message class for each type of caller. Each type of caller fills in the placeholder with a message the caller can understand.
Important Information
Copyright
© 2012 National Instruments. All rights reserved.
Under the copyright laws, this publication may not be reproduced or transmitted in any form, electronic or mechanical, including photocopying, recording, storing in an information retrieval system, or translating, in whole or in part, without the prior written consent of National Instruments Corporation.
National Instruments respects the intellectual property of others, and we ask our users to do the same. NI software is protected by copyright and other intellectual property laws. Where NI software may be used to reproduce software or other materials belonging to others, you may use NI software only to reproduce materials that you may reproduce in accordance with the terms of any applicable license or other legal restriction.
End-User License Agreements and Third-Party Legal Notices
You can find end-user license agreements (EULAs) and third-party legal notices in the following locations:
- Notices are located in the <National Instruments>\_Legal Information and <National Instruments> directories.
- EULAs are located in the <National Instruments>\Shared\MDF\Legal\license directory.
- Review <National Instruments>\_Legal Information.txt for information on including legal information in installers built with NI products.
Trademarks
LabVIEW, National Instruments, NI, ni.com, the National Instruments corporate logo, and the Eagle logo are trademarks of National Instruments Corporation. Refer to the Trademark Information at ni.com/trademarks for other National Instruments trademarks.
Other product and company names mentioned herein are trademarks or trade names of their respective companies.
Patents
For patents covering the National Instruments products/technology, refer to the appropriate location: Help»Patents in your software, the patents.txt file on your media, or the National Instruments Patent Notice at ni.com/patents.
Reader Comments | Submit a comment »
Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).

