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-1DigiLinX 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
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-2Connecting 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
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
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:
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.
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-1StreamNet 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.
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 bestpractices 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-2Command 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
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.
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:
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
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.
-- 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)
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).