ClearOne Writing StreamNet User Manual

NetStreams DigiLinX
Writing StreamNet Device Drivers
Title: Writing StreamNet Device Drivers Document Number: 020014A Original Publication Date: August 14, 2006 Revision Date: February 27, 2007
All rights reserved.
Copyright © 2007 by NetStreams.
All brand names, product names, and trademarks are properties of their
respective owners.
Copyright
3600 W. Parmer Lane, Suite 100
Austin, TX 78727
USA
Phone: +1 512.977.9393
Fax: +1 512.977.9398
Toll Free Technical Support 1-866-353-3496
Contents
Chapter 1: Introduction ................................................................................................................1-1
Introduction to Lua .................................................................................................................. 1-2
Chapter 2: Activating Drivers within DigiLinX Dealer Setup ....................................................2-1
Chapter 3: Handling Commands .................................................................................................3-1
Handling Commands ................................................................................................................ 3-2
Example: Handle_Set ........................................................................................................... 3-2
Chapter 4: Handling Communications ........................................................................................4-1
Chapter 5: Configuration ..............................................................................................................5-1
Chapter 6: Installing the Driver ....................................................................................................6-1
Useful Development Tips .......................................................................................................... 6-7
Chapter 7: Generating Status Reports ........................................................................................7-1
Chapter 8: Diagnostic Messages .................................................................................................8-1
Chapter 9: Reference ....................................................................................................................9-1
Syntax ......................................................................................................................................... 9-1
Control ....................................................................................................................................... 9-1
default_handle_command (command) ................................................................................. 9-1
handle_command(command) ................................................................................................ 9-2
aNode = getSubNode(strNodeName) ................................................................................... 9-2
setStatus(strField, value) ....................................................................................................... 9-3
aString = getStatus(strField, value) ...................................................................................... 9-3
SubNode ..................................................................................................................................... 9-3
aSubNode = createSubNode(strName) ................................................................................. 9-3
aTable = subNodes ................................................................................................................ 9-3
aString = aSubNode.name .................................................................................................... 9-3
aStatus = aSubNode.status .................................................................................................... 9-3
aSubNode:setStatus(strField, value) ..................................................................................... 9-3
aString = aSubNode:getStatus(strField, value) ..................................................................... 9-4
aSubNode:default_handle_command(command) ................................................................. 9-4
aSubNode:handle_command(command) .............................................................................. 9-4
AsciiCommand .......................................................................................................................... 9-4
aString = command.command .............................................................................................. 9-4
aTable = command.params ................................................................................................... 9-4
aString = command.to ...........................................................................................................9-5
iii
Writing Streamnet Device Drivers
aString = command.toNode .................................................................................................. 9-5
aString = command.toSubNode ............................................................................................ 9-5
aString = command.from ...................................................................................................... 9-5
aString = command.fromNode ............................................................................................. 9-5
aString = command.fromSubNode ....................................................................................... 9-5
Stream ........................................................................................................................................ 9-5
aStream = createStream(strPort) ........................................................................................... 9-6
aString = stream:read(max) .................................................................................................. 9-7
stream:write(aString) ............................................................................................................ 9-7
anInteger = stream:available() .............................................................................................. 9-7
stream:startAsyncInput(aFunction, options) ......................................................................... 9-8
stream:stopAsyncInput() ....................................................................................................... 9-8
Status ..........................................................................................................................................9-9
aStatus = createStatus() ......................................................................................................... 9-9
aStatus = status ...................................................................................................................... 9-9
status:setField(field, value) ................................................................................................... 9-9
aString = aStatus:getField(field) ........................................................................................... 9-9
Timer ........................................................................................................................................9-10
aTimer = createTimer(nMS, aFunction) ............................................................................. 9-10
anInteger = aTimer.duration ............................................................................................... 9-10
aTimer:cancel() ................................................................................................................... 9-10
aTimer:queue(nMS) ............................................................................................................ 9-11
Debug ....................................................................................................................................... 9-11
debug(category, …) ............................................................................................................ 9-11
setDebug(category, <”on”|”off”|”toggle”>) ........................................................................ 9-11
Appendix A:Lua 5.0 License ......................................................................................................... A-1
Appendix B:Editing Environments ............................................................................................... B-1
Appendix C:Control Driver Example ............................................................................................ C-1
Appendix D:Audio Driver Example ............................................................................................... D-1
iv
Chapter
1
Introduction
NetStreams® ships drivers for a variety of third party systems with the DigiLinX™ system. These drivers include Lutron® for lighting, Aprilaire® for HVAC, and GE Concord® for security. Custom installers can use these included drivers with a ControLinX™ to enable DigiLinX control of external systems. Sometimes, the
specific needs of a job require DigiLinX to control different third party systems. The
NetStreams StreamNet™ device driver Application Programming Interface (API) is
designed to enable programmers to interface RS-232 and network devices with the NetStreams DigiLinX system. This gives custom installers the flexibility they need for their jobs.
The DigiLinX system is a combination of hardware, software, and firmware. To understand how to interface third party systems with DigiLinX, programmers must understand the architecture of the system (see Figure 1-1).
User Interface
API
Configuration
Driver
Software
Firmware
Hardwar e
Figure 1-1 DigiLinX Hardware/Software model
In the DigiLinX system, the hardware layer is controlled by firmware. Firmware is controlled and updated by software, which in turn is controlled by configuration files, and drives the User Interface. NetStreams’ engineering team has created an API that
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
1-1
Writing StreamNet Device Drivers
enables DigiLinX to control and be controlled by third party systems using a driver (seeFigure 1-2 ).
Figure 1-2 Connecting 3rd Party Systems to DigiLinX
Device drivers allow two-way interaction with third party hardware devices over a communications subsystem, such as RS-232. The ControLinX device includes the hardware needed to control external systems.
The DigiLinX API is written in a programming language called Lua. Lua is a free, lightweight, procedural language that is designed to be fast and easy to learn for most programmers. Third party drivers must be written in Lua to work with the DigiLinX API.
Third party drivers are composed of objects called Controls. These Controls are represented by all of the functions and variables in the driver’s code. Drivers may also contain code to control subcomponents, called subNodes. DigiLinX treats subNodes as logical entities for both accepting commands and producing status messages. For example, in a lighting system, a subNode might represent a specific lighting load. Commands addressed to this subNode would then only affect that lighting load and all status messages related to the load would be addressed from the subNode.
Introduction to Lua
Lua is a byte-code interpreted language, similar to Java. It provides a small scripting and user-customizable interface to a subset of an application written in C or C++.
Where Java is primarily focused on providing all of the tools necessary to write a complete application, Lua is focused on providing minimal system interfaces and a tightly coupled interface to an underlying application.
The benefits of Lua include:
1-2
Extension Language – Lua is designed from the ground up to be an extension
language. This is a language solely used to extend the functionality of a larger application. This means there is a two-way interface that easily allows Lua code to invoke native subroutines and vice-versa. The vast majority of the functional
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Introduction
portion of the control system can be written in C/C++ while a minimum of device specific code is written in interpreted Lua.
Minimal System Interface and Dependence – The Lua virtual machine and its
associated parser/compiler are written in ANSI-standard C with a minimum system interface. There is no operating system (OS) interface defined at the script level.
Native String Manipulation – The bulk of the necessary string operations
(concatenation, searching, formatting, regular expressions, etc.) are implemented in ANSI C, rather than being implemented in the script language. This provides for substantially improved performance given that the majority of control applications are string parsing and generation.
Virtual Machine (VM) implementation – The Lua scripting language is compiled
(either at runtime or in advance) into a VM-interpreted language that is subsequently run on a virtual machine designed with the language constraints in mind. This substantially improves performance over similar languages that are fully interpreted.
Object-oriented – While Lua is not an object-oriented language, there are sufficient
language features that it can be treated as such.
The Lua script engine and its associated tools are licensed under a MIT-style license, which states that it is copyrighted material but free license is granted for commercial and non-commercial usage.
For the full Lua license see Appendix A, Lua 5.0 License on page A-1. Further information on Lua is available either from the web site http://www.lua.org or
Programming in Lua by Roberto Lerusalimschy.
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
1-3
Writing StreamNet Device Drivers
1-4
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Chapter
2
Activating Drivers within DigiLinX Dealer Setup
Starting with version 1.70, DigiLinX Dealer Setup uses an intelligent lookup to determine if there are custom written drivers present in the system.
In order to load custom written drivers through DigiLinX Dealer Setup, you must first create a new folder called “drivers” under your DigiLinX Dealer Setup install directory and copy the .lua driver file to this directory. In most cases, the directory will be:
C:\Program Files\DigiLinX Dealer Setup\drivers\yourdriverfile.lua
After you have created this folder and copied your driver file into the folder, build your project normally in DigiLinX Dealer Setup. Add a ControLinX or MediaLinX to your project, selecting the GUI type from the dropdown menu (for example, Tuner, Lutron, etc.). When you enter the details for your ControLinX or MediaLinX, Dealer Setup will detect the custom driver in the drivers folder and present the option to select a new .lua driver file.
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
2-1
Writing StreamNet Device Drivers
2-2
All specifications subject to change without notification. All rights reserved. Copyright © 2006 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Chapter
3
Handling Commands
The generation and processing of ASCII-formatted commands is central to the interaction between various StreamNet devices and hence, the heart of a device driver is how it receives and process ASCII commands. Figure 3-1 shows how the StreamNet commands flow.
User Presses GUI
Button
Figure 3-1 StreamNet command flow
GUI code generates a
StreamNet ASCII
command and sends it
to the StreamNet device
StreamNet device
receives and parses
command and sends it to
the Lua driver
StreamNet command is
routed to the appropriate
section of the Lua driver
code
As commands are received by the host StreamNet device, they are parsed to separate out the various addressing fields, ASCII command, and command parameters. Once the command is completely parsed, it is passed to the device driver for handling by the appropriate Lua code. Refer to Figure 3-2 to see how commands are routed within the driver.
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
3-1
Writing StreamNet Device Drivers
NOTE
Streamnet command is routed to the appropriate section of the Lua driver code
Start
Handling Commands
It is always possible to define an appropriate command-specific handler, so that the default_command_hand ler is not needed. Programming best­practices state that a fallback default_command_hand ler should be defined even if it is not intended for use.
Is the command
addressed to a
subnode?
YesYes
Is there a subnode specific command
handler?
Call subnode specific
command handler
No
No
Is there a Control specific command
handler?
Yes
Call Control specific
command handler
Is there a subnode
default command
handler?
Yes
Call subnode default
command handler
No
No
Call Control default
command handler
Is there a Control specific c o mmand
handler?
Yes
Call Control specific
command handler
N
o
Call Control def ault
command handler
Figure 3-2 Command routing within the driver
For a device driver to receive and handle commands, it is necessary to define Lua functions with predefined names based on the command to be handled. The routine that needs to be defined is “handle_<command>” (where <command> is replaced with the lower cased version of the ASCII command). For example, if a driver needs to handle #SET commands, it needs to define a function handle_set within the driver. As a fall-back mechanism, if no command-specific function is defined, the function “default_command_handler” will be invoked if defined.
If the command is generic to the entire device, the necessary function should be defined in the outermost control scope of the Lua file, and will be invoked with only the command as a parameter.
Example: Handle_Set
function handle_set(cmd) if(cmd.params[1] == “heat”) then
… handle the #set heat command
end end function default_command_handler(cmd)
3-2
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Handling Commands
NOTE
if(cmd.command == “debug”) then
… handle the #debug command
end end
If the command is specific to a particular subNode of the driver, it should be defined as an element in the subNode. It will be passed the subNode itself as its only argument.
subNode.handle_set = function(self, cmd)
if(cmd.params[1] == “heat”) then
… handle the #set heat… command
end end
subNode.default_command_handler = function(self, cmd)
if(cmd.command == “debug”) then
… handle the #debug command
end end
In the previous example, Lua provides a convenient short-cut notation with identical functionality:
function subNode:handle_set(cmd) if(cmd.params[1] == “heat”) then
end
end
3-3
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Writing StreamNet Device Drivers
3-4
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
NOTE
Chapter
4
Handling Communications
Most device drivers will need some mechanism for talking to a controlled device. In the StreamNet system, that capability is provided by a generalized I/O Stream mechanism.
A stream can be created using a string-based configuration string, the precise format of which depends on the details of the connection. Once the stream is created, the details of the underlying transport mechanism (such as RS-232, TCP/IP, or some other mechanism) is identical for all streams. This allows the same driver and code to be used to control a device regardless of the physical connection type.
Use the “:” syntax to pass the stream as an argument to the read and write functions.
A stream is created with the createStream function:
stream = createStream(“comm:// 0;baud=9600;parity=n”);
Once created, the stream can be read from and written to using the read and write functions:
input = stream:read() stream:write(input)
Many devices have asynchronous outputs, i.e., outputs that are not in direct response to some command being sent down. The preferred mechanism of dealing with such responses is to define and enable an asynchronous response handler:
function input(stream, line) … handle async response in “line” end
stream:startAsyncInput(input, {endString = “\n”})
4-1
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Writing StreamNet Device Drivers
4-2
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Chapter
5
Configuration
As for any other StreamNet service, a StreamNet service with a Lua driver is configured by including an appropriate service tag within the config_current.xml file. In the case of standard StreamNet device types, the clause will be automatically generated, but in the case of custom device types, the clause may need to be manually generated.
<service serviceNumber=”2” serviceName=”AprilAire”
serviceType=”gpio” enabled=”1”> <control controlType=”SCRIPT”>
<SCRIPT file=”AprilAire.lua”>
<SCRIPT_DATA>
-- lines here are passed to the lua interpreter before
-- the driver file is loaded config = {}; config.port = “comm://0;baud=9600”;
</SCRIPT_DATA>
</SCRIPT> </control> </service>
The SCRIPT_DATA block defines a section of Lua that will be passed to the interpreter before the driver is loaded, allowing for installation specific parameters, such as the port settings above, to be passed to the driver.
NOTE: The serviceType in this example is currently required to be “gpio,” and the
serviceNumber is a device specific constant (always 2 in the case of a CL100 or CL100A)
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
5-1
Writing StreamNet Device Drivers
5-2
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Chapter
6
Installing the Driver
After writing a driver, you must load it for use with the DigiLinX network. This chapter provides step by step procedures for installing and running an example driver
for a Panamax® power conditioner. If you have any questions concerning DigiLinX Dealer Setup, refer to the DigiLinX Dealer Setup Manual located on the Dealer Documents page of the NetStreams website.
WARNING! You can only load drivers with DigiLinX Dealer Setup versions 1.5 or
higher.
1. Add a ControLinX configured for General Purpose Driver, Serial (see Figure 6-1).
Figure 6-1 Add a ControLinX
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
6-1
Writing StreamNet Device Drivers
2. Using Windows Explorer, copy the driver you have written to C:\Program
NOTE: In this case you are copying to \07_17_2006\drivers.
Files\DigiLinX Dealer Setup\upgrades\<latest folder date>\drivers.
Figure 6-2 Copying the driver to the hard drive
From DigiLinX Dealer Setup, highlight the ControLinX and select the IR/RS-232
3.
tab.
4. Enter the filename of your driver file in the driver file text box of your ControLinX
configuration:
6-2
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Figure 6-3 Entering the driver file name
Installing the Driver
Select Labels and enter button presets.
5.
NOTE: This procedure creates the individual buttons that will control this device. The
ID field corresponds to the driver subNode, while the Button Label is the first label that appears on the GUI buttons.
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
6-3
Writing StreamNet Device Drivers
Figure 6-4 Entering Button Presets
Select the Menu tab and select Enable a Menu for this Room.
6.
NOTE: Ensure that rooms requiring control of this device have this menu enabled.
6-4
All specifications subject to change without notification. All rights reserved. Copyright © 2007 NetStreams
Main +1 512.977-9393 / fax +1 512.977.9398 / Toll Free Technical Support +1 866-353-3496
3600 W. Parmer Lane, Suite 100; Austin, TX 78727 / www.netstreams.com.
Loading...
+ 50 hidden pages