Design XPress Home Theater Version Advanced Programmers Guide 0332716
Design XPress Home Theater Version Advanced Programmers Guide 0332716
Design XPress -
Home Theater
version 1.2
So ftw are
Software Warranty Agreement
PRE-RELEASE CODE.
Portions of the AMX Software may, from time to time, as identified in the AMX Software, include PRE-RELEASE CODE
and such code may not be at the level of performance, compatibility and functionality of the final code. The PRE-
RELEASE CODE may not operate correctly and may be substantially modified prior to final release or certain features
may not be generally released. AMX is not obligated to make or support any PRE-RELEASE CODE. ALL PRE-
RELEASE CODE IS PROVIDED “AS IS” WITH NO WARRANTIES.
LIMITED WARRANTY.
AMX warrants that the AMX Software will perform substantially in accordance with the accompanying written materials
for a period of 30 days from the date of receipt. AMX DISCLAIMS ALL OTHER WARRANTIES, EITHER EXPRESS OR
IMPLIED, INCLUDING, BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE, WITH REGARD TO THE AMX SOFTWARE. THIS LIMITED WARRANTY GIVES YOU
SPECIFIC LEGAL RIGHTS.
LICENSEE REMEDIES.
AMX's entire liability and your exclusive remedy shall be repair or replacement of the AMX Software that does not meet
AMX's Limited Warranty and which is returned to AMX. This Limited Warranty is void if failure of the AMX Software has
resulted from accident, abuse, or misapplication. Any replacement AMX Software will be warranted for the remainder
of the original warranty period or 30 days, whichever is longer. Outside the United States, these remedies may not
available.
NO LIABILITY FOR CONSEQUENTIAL DAMAGES. IN NO EVENT SHALL AMX BE LIABLE FOR ANY DAMAGES
WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF
THE USE OF OR INABILITY TO USE THIS AMX PRODUCT, EVEN IF AMX HAS BEEN ADVISED OF THE POSSI-
BILITY OF SUCH DAMAGES. BECAUSE SOME STATES/COUNTRIES DO NOT ALLOW THE EXCLUSION OR LIMI-
TATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT
APPLY TO YOU.
If you acquired this product in the United States, this Agreement is governed by the laws of the State of Texas.
Should you have any questions concerning this Agreement, or if you desire to contact AMX for any reason, please
write: AMX Corporation, 3000 Research Drive, Richardson, TX 75082.
Table of Contents
Table of Contents
Architectural Overview ............................................................................................1
The GUI Tier...................................................................................................................... 1
BUTTON_EVENT - Cable.axi .................................................................................................. 1
BUTTON_EVENT - CD.axi ...................................................................................................... 1
BUTTON_EVENT - Display.axi................................................................................................ 1
BUTTON_EVENT - DSS.axi .................................................................................................... 1
BUTTON_EVENT - DVD.axi .................................................................................................... 1
BUTTON_EVENT - Environment.axi ....................................................................................... 1
BUTTON_EVENT - Global.axi ................................................................................................. 1
BUTTON_EVENT - Main Menu.axi.......................................................................................... 1
BUTTON_EVENT - MP3.axi .................................................................................................... 1
BUTTON_EVENT - PVR.axi .................................................................................................... 1
BUTTON_EVENT - Receiver.axi ............................................................................................. 2
BUTTON_EVENT - VCR.axi .................................................................................................... 2
Main Menu.axi.......................................................................................................................... 2
TP.axi ....................................................................................................................................... 2
The Application (Logic) Tier .............................................................................................. 3
Define Constant.axi.................................................................................................................. 3
Define Event.axi ....................................................................................................................... 3
Define Start.axi......................................................................................................................... 3
Define Structure.axi.................................................................................................................. 3
Define Variable.axi ................................................................................................................... 3
Control.axi ................................................................................................................................ 3
ControlLogics.axi...................................................................................................................... 3
Custom.axi ............................................................................................................................... 4
Custom Macro Functions.axi.................................................................................................... 4
Debug.axi ................................................................................................................................. 4
Globals.axi ............................................................................................................................... 4
Macro Engine.axi ..................................................................................................................... 4
Macro Engine Handlers.axi ...................................................................................................... 4
The Data Tier .................................................................................................................... 4
Config.axi ................................................................................................................................. 4
CD List Management.axi.......................................................................................................... 4
DB Access.axi .......................................................................................................................... 4
Anatomy Of a Handler ..............................................................................................5
Overview ........................................................................................................................... 5
DBInitHandler .................................................................................................................... 7
Architectural Overview
Design XPress Home Theater (DXP-HT) NetLinx code is best viewed as a traditional "3-Tier"
application - the Graphical User Interface (GUI) Tier, the Application (or Logic) Tier, and the Data
Tier.
BUTTON_EVENT - Cable.axi
Handles touch panel interface commands that apply to cable set-top units. While all handlers for the
entire cable receiver command-set are found within this file, the actual logic of what action(s) to
take as a result of each command is contained within Control.axi and ControlLogics.axi. The
handlers themselves are virtually identical except that each one passes the appropriate unique
command identifier into Control.axi. This is true for all BUTTON_EVENT - { Type } files, with the
exception of BUTTON_EVENT - Display.axi, which calls into ControlDisplayDevice instead
of ControlSourceDevice (both ControlSourceDevice and ControlDisplayDevice are
defined within Control.axi).
BUTTON_EVENT - CD.axi
Handles touch panel interface commands that apply to CD players.
BUTTON_EVENT - Display.axi
Handles touch panel interface commands that apply to display devices.
BUTTON_EVENT - DSS.axi
Handles touch panel interface commands that apply to Digital Satellite Systems.
BUTTON_EVENT - DVD.axi
Handles touch panel interface commands that apply to DVD players.
BUTTON_EVENT - Environment.axi
Handles touch panel interface commands that apply to environmental control.
BUTTON_EVENT - Global.axi
Handles global touch panel interface commands.
BUTTON_EVENT - MP3.axi
Handles touch panel interface commands that apply to MP3 players.
BUTTON_EVENT - PVR.axi
Handles touch panel interface commands that apply to personal video recorders (PVRs).
BUTTON_EVENT - Receiver.axi
Handles touch panel interface commands that apply to A/V receivers.
BUTTON_EVENT - VCR.axi
Handles touch panel interface commands that apply VCRs.
Main Menu.axi
Governs population and handling of the main menu. Two menu types are available in DXP-HT:
! Scrolling - The structure of the main menu is gleaned dynamically from the database
using the same set of buttons to select any device that is available to the user. The
categories (or families) of devices are defined by the v_rstDevType table and the
members of those categories are defined within the v_rstDisplay and v_rstSource
tables. Note that the prefix "rst" may be read, "Array of Structures". FIG. 1 shows an
example of the Scrolling main menu style:
! Static - Up to six parent categories are available at all times: Display, Sources, Lights,
Relays, Macros, About. With the exception of the Sources button, selecting any category
will send the user to the proper popup. If the user selects the Sources category then s/he
will be presented with a popup of static buttons with source names as their labels.
Pressing any of those buttons will send the user to the proper popup and activate the
selected device. Because these buttons are static, they may be copied and pasted
anywhere in the interface (TPD) file. This means that custom pages or popups may be
built with buttons used to activate sources. FIG. 2 shows an example of the Static main
menu style:
TP.axi
Functions related to interface feedback and behaviors.
Define Event.axi
Handles interface, I/O device, and MP3 Player events (ONLINE, STRING, etc).
Define Start.axi
Miscellaneous startup initializations. The most important steps that occur during startup are the
database queries that define all properties of the system (source count, source properties, number of
interfaces, display device properties, macros, etc).
Define Structure.axi
Defines all structures that are used in DXP-HT. Most of the structures pertain to the database,
which is really just several arrays of structures (all global structures are preceded with "v_rst," to
indicate that they are arrays of structures). The three main structures that constitute the bulk of the
database are v_rstSource, v_rstDisplay, and v_rstInterface. Note that the structures are
defined within this file but they are not actually declared here -- that is a function of _Define
Variable.axi. Refer to The Data Tier section on page 4 for more information regarding the database
structures.
Define Variable.axi
Defines all global variables, which are preceded with "v_," followed by appropriate Hungarian
Notation.
Control.axi
The central point from which all commands are interpreted and acted upon. Almost all handlers
will call into this include file (either ControlSourceDevice or ControlDisplayDevice,
depending on which handler has executed). This include file will determine whether or not a
Control Logic is defined for the device in question, then it will either call the appropriate Control
Logic or else it will determine which IR code to pulse in order to cause the desired behavior. When
determining the correct IR code the IR Map will be referenced, which is a structure containing
unique commands and their corresponding IR codes. All display devices and sources have an IR
map associated with them, although it may not be referenced if the device utilizes a Control Logic.
ControlLogics.axi
Contains all intrinsic DXP-HT Control Logics. A Control Logic is a block of code built to control a
specific device. For example, the behaviors, properties, and protocols of a specific device will be
known by the Control Logic. Control Logics may be modules, SYSTEM_CALLs, or simple NetLinx
code. See How to create a custom Control Logic. section on page 24 for detailed information
regarding Control Logics.
Custom.axi
This file contains no code. It is intended for use by the dealer when customizing the system.
Debug.axi
Strictly for debugging via Telnet or HyperTerminal. Prints debugging and diagnostics for use when
troubleshooting the system. Refer to the Debugging and Diagnostics section on page 29 for more
information.
Globals.axi
"Catch all" for all functions that are not easily categorized into one of the existing include files.
This include file handles those commands that apply to multiple categories (such as the discrete
channel list which may apply to both the display device and the VCR).
Macro Engine.axi
The core code that drives the Macro Engine. The Macro Engine allows sequences of unique
commands to execute on a timeline while retaining namespace for all required parameters.
CD List Management.axi
Reads the CD List from the D.O.C. and displays it for the user. Also handles many functions of the
CD List such as sorting, scrolling, Add, Edit, Delete, etc.
DB Access.axi
Functions regarding database access (i.e., the arrays of structures that are initialized in Config.axi).
This file serves as a level of abstraction between the "Application Tier" and the "Data Tier." For the
most part, a NetLinx programmer need understand only a few of the functions that are available
within this file in order to gain access to any part of the database.
Anatomy Of a Handler
Overview
The mechanism by which all interface button pushes are handled is the NetLinx BUTTON_EVENT
handler. No PUSHes or RELEASEs are handled via Mainline.
Each button will have a corresponding BUTTON_EVENT in a related file. The channel names will
typically be indicative of the button's nature. For example, the DVD Player "Play" button can be
found within the file BUTTON_EVENT - DVD.axi.
The handler is: BUTTON_EVENT[dvTP, c_btnDVDPlay].
Some handlers include stacked BUTTON_EVENTs of related functionality, such as transport
control. This is also evident with the DVD "Play" button handler, which looks like this:
BUTTON_EVENT[dvTP, c_btnDVDPlay]
BUTTON_EVENT[dvTP, c_btnDVDStop]
BUTTON_EVENT[dvTP, c_btnDVDPause]
BUTTON_EVENT[dvTP, c_btnDVDFF]
BUTTON_EVENT[dvTP, c_btnDVDRew]
BUTTON_EVENT[dvTP, c_btnDVDSkipRev]
BUTTON_EVENT[dvTP, c_btnDVDSkipFwd]
{
...body of handler...
}
The body of most handlers is almost identical, with the exception of some parameters that are
passed into the functions that query the database and act upon the devices. The exceptions are the
"Power" handlers, which are similar to all other handlers except that they call into a different
function in order to act upon the device. This is due to the special needs of the power management
capability.
Following is an example of a simple handler:
// Handle DVD ENTER command:
BUTTON_EVENT[dvTP, c_btnDVDEnter]
{
PUSH :
{
STACK_VAR INTEGER nSrcIdx // Index into source table
STACK_VAR INTEGER nTPDBIdx // Index into interface table
}
}
RELEASE :
{
STACK_VAR INTEGER nSrcIdx // Index into source table
STACK_VAR INTEGER nTPDBIdx // Index into interface table
! The first function call, DBInitHandler (found in DB Access.axi), queries the NetLinx
database (found in Config.axi) to determine which source is currently active to the
interface from which the event was received. This query also acquires the pertinent
properties of the device. The DBInitHandler function is described in greater detail in the
DBInitHandler section on page 7.
! In order to employ a consistent mechanism for control of all device types, DXP-HT does
not typically act directly upon a device from within the handler. This is because the goal
is to allow you leverage to choose your own devices, rather than dictating which devices
DXP-HT will support. If we were to build DXP-HT around specific make and models
then we could act directly upon them within the handlers. However, as we do not
necessarily know the control mechanism required to control your selected set of devices,
we instead save all necessary device properties within the NetLinx database (Config.axi)
and acquire those properties when the handlers are executed. This allows us to determine
how to control a device and potentially employs special logic that may be required to
control your devices.
! Another reason for the database-driven architecture is to allow you to use your IR files
without worrying about the channel locations for the various functions. Instead of forcing
you to place functions in particular slots within the IR files, we allow you to tell us how
your files are mapped. Support of this functionality requires that your IR mappings be
saved in a database and looked up by the handlers.
! While it would be possible to simplify the handlers by only looking up IR mappings and
then pulsing the proper IR code directly from within the handler, that would not suffice
for RS-232 controlled devices. So the argument could be made, why not simply pulse IR
or send strings directly from within the handlers? While this may seem simpler, it would
greatly complicate the handlers since we would have to embed all of the logic to
determine what strings to send, what special logic may be required, etc. Instead of
attempting to handle the endless permutations that inevitably surface in custom home
theaters, we have built a standard mechanism that is employed by almost all handlers. In
our model, the "nuts and bolts" of acting upon the devices are then driven by two
centralized functions: ControlSourceDevice and ControlDisplayDevice (found in
Control.axi).
! Building all handlers in a consistent manner allows us to determine which events apply to
which devices by altering the database instead of the source code. For example, if a user
presses a button with channel code 1 on touch panel device 128, it may cause two
handlers to execute. One may query the database and find that [128:1:0,1] does not apply
to it, since the "Device Used" level does not apply to it. However, another handler may
perform the same query and discover that the event does apply to it, and it can then
proceed with the handler. This allows consistency across handlers for all device types and
it allows us to simply reference the one master interface DevSet, dvTP, which is written
out by the Wizard in Main.axs, rather than attempting to maintain several different
DevSets for each device type.
DBInitHandler
Following is a list of the parameters received by DBInitHandler:
! Queries the database to determine whether the "Device Used" level for the device type in
question is equal to the "Device Used" level from which the event was received.
! Outputs debugging and diagnostics to the Telnet or Terminal client (see the Debugging
and Diagnostics section on page 29).
! Determines which device is currently "active". In other words, determines which device
the user previously selected from the main menu, so that we will be sure to control the
device that the user intends to control.
! Ensures that the interface is not locked. Some actions require a short time-out during
which interface events should be ignored. DBInitHandler provides this capability since
all standard handlers call into it.
! Determines whether the calling handler should fall through (i.e., do nothing) or rather
control the active device to which the handler applies. If the button channel code is found
to be on the same "Device Used" level as the device type parameter that was passed in
(parameter #3 - nType), and if nIdx and nTPDBIdx are properly initialized (see the
DBInitHandler section on page 7), DBInitHandler will return a non-zero value.
Otherwise, it will return zero and the handler will fall through. For example, if the button
"Device Used" level is 2, and if the third parameter passed into DBInitHandler is
c_nDVD, the handler will return a non-zero value, because c_nDVDSetIdx is 2 in
_Define Constant.axi. On the other hand, if the third parameter was c_nCD, which
utilizes buttons on "Device Used" level 3 of the touch panel, DBInitHandler would
return 0.
Additional notes
! The "Device Used" levels for all device types are stored in the Device Types table in
Config.axi (v_rstDevType). DBInitHandler calls into DBGetDeviceTypeIndex and
passes in the unique identifier from the handler (c_nDVD, c_nVCR, etc.).
DBGetDeviceTypeIndex returns the index into the v_rstDevType table that
corresponds to the device type. We are then able to determine what the "Device Used"
level is, and consequently we can know whether the event applies to the handler or not.
ControlSourceDevice / ControlDisplayDevice
ControlSourceDevice and ControlDisplayDevice are very similar in nature. The parameters that
they receive vary only slightly. The main difference between these two functions is that one queries
against the Source table and the other queries against the Display table in Config.axi.
The following table lists the parameters received by ControlSourceDevice:
INTEGER nSrcDBIdx Index into the Source table that applies to the device in ques-
tion.
INTEGER nTPDBIdx Index into the Interface table that applies to the interface that
sent the control event.
INTEGER nFunc A unique identifier corresponding to the selected function.
stRoute stXPoints An stRoute structure containing crosspoint information. For
any device other than receivers or routers this value will
always contain zeroes for all members (passed as
v_stBlankRoute). It may or may not contain non-zero values
for receivers. It must contain non-zero values for switchers.
See the Define Structure.axi section on page 3 for a list of the
members contained within it.
stPmtrs stParams A "generic" structure that can be used to pass parameters
into this function. See the Define Structure.axi section on
page 3 for a list of the members contained within it.
INTEGER bPush Indicates whether the function has been invoked as the result
of a PUSH or RELEASE. If true then it applies to a PUSH; if
false then it is a RELEASE.
INTEGER nTVDBIdx Index into the Display table that applies to the device in ques-
tion.
INTEGER nTPDBIdx Index into the Interface table that applies to the interface that
sent the control event.
INTEGER nFunc A unique identifier corresponding to the selected function.
INTEGER nTVDBIdx Index into the Display table that applies to the device in ques-
tion.
INTEGER nTPDBIdx Index into the Interface table that applies to the interface that
sent the control event.
INTEGER nFunc A unique identifier corresponding to the selected function.
stPmtrs stParams A "generic" structure that can be used to pass parameters
into this function. See the Define Structure.axi section on
page 3 for a list of the members contained within it.
INTEGER bPush Indicates whether the function has been invoked as the result
of a PUSH or RELEASE. If true then it applies to a PUSH; if
false then it is a RELEASE.
! Determines whether or not the device to be controlled has a Control Logic associated
with it (as determined by its nCtrlLogic member that is initialized within Config.axi). If
so, calls into the proper Control Logic. Otherwise, proceeds with the following...
Custom Programming
Guidelines
Modification of any file other than Custom.axi or Custom Macro Functions.axi is highly
discouraged because DXP-HT will overwrite all other files when the project is regenerated. For
advanced users that choose to modify the core NetLinx engine, the preferred method is to build the
project to the extent that it can be completed via the Wizard. Then, after generating code, copy the
interfaces and the source code from the project directory to another directory that is not utilized by
the DXP-HT Project Wizard. Thereafter, implement all modifications using the new working
directory.
If possible, all customization should be accomplished within the files Custom.axi or Custom Macro
Functions.axi. The DXP-HT Wizard will not overwrite these files during project generation. Any
site-specific customization that cannot be accomplished within Custom.axi should be developed
using the method described above.
The importance of careful attention to the location of your source code cannot be overstated. If you
generate a project and then use the DXP-HT working directory as the location for your custom
modifications (other than those implemented within Custom.axi or Custom Macro Functions.axi),
you run the risk of accidentally overwriting your hard work whenever the project is regenerated.
This principle also applies to the touch panel interface files (TPDs).
The easiest and most familiar way to add customization to a facility is via traditional NetLinx code,
or via the customization tools that DXP-HT provides.
Method 1
Manually create a button, preferably on Device #4 of the touch panel interface. Then create a
handler for that button in Custom.axi (the handler must be preceded with a DEFINE_EVENT section
identifier). For example, if you create a button on Device #4 having channel ID 100, and you want
that button to pulse IR slot 5 on NetLinx card 10 at port 2, the handler might look like this (the
following assumes the facility utilizes three interfaces starting at AMX Device ID 128):
BUTTON_EVENT [131:1:0, 100] // Button on "Device Used" 4
BUTTON_EVENT [135:1:0, 100] // Button on "Device Used" 4
BUTTON_EVENT [139:1:0, 100] // Button on "Device Used" 4
{
PUSH :
{
PULSE [10:2:0, 5]
}
}
Method 2
Create a PULSE macro via the Wizard and assign it to a button on the Macros page. Then, using
TPDesign3 or TPDesing4, copy that button from the macros page and paste it onto the appropriate
page. See the How to take advantage of the custom macro functions. section on page 17 for more
information regarding the Macro Engine.
Adding NetLinx handler functionality while maintaining the integrity of the architecture is
somewhat more complicated. However, in the example from Method 1, the difficulty is not extreme.
Following are the steps of how one would accomplish the same goal without abandoning the
database-driven architecture of DXP-HT:
! Open the file that controls the device for which you are adding a button. Let's assume
we're adding a button to the DVD control page. We would open the file BUTTON_EVENT
- DVD.axi.
! Find an existing handler. Note that some handlers include stacked events with
SELECT…CASE statements within them. Such handlers would not be desirable for this
example. The "Enter" command is a good example of a simple command handler.
Following is the code snippet for the "Enter" handler:
// Handle DVD ENTER command:
BUTTON_EVENT[dvTP, c_btnDVDEnter]
{
PUSH :
{
STACK_VAR INTEGER nSrcIdx
STACK_VAR INTEGER nTPDBIdx
! Copy the above handler and paste it into Custom.axi, immediately after the
DEFINE_EVENT section identifier (which must be added manually).
! Change the channel (c_btnDVDEnter) to the channel ID that you need to handle. You
may hard code it or you may create a constant in Main.AXS (or _Define Constants.axi).
! In the body of the handler, replace the unique command ID (c_nEnter) with your own
unique command ID. This must be done in both the PUSH and RELEASE sections of the
handler.
! If your command is not already defined in _Define Constants.axi then you will need to
create a new one. The value of the command ID is irrelevant except that it must be
unique. Therefore, if you create your own command ID, it is recommended that it be
initialized at 1000 or larger, to ensure that it is out of range of the unique command
identifiers that are used by DXP-HT.
! If your command is already defined, and if your DVD player is IR controlled, you are
done. The handler will call into ControlSourceDevice and pass the unique ID, which will
be referenced against the IR Map. Assuming the IR code has been properly mapped via
the Wizard, IR will be pulsed when the event is received.
If you created a new command ID (such as c_nAspect, for example), and if your device is
controlled via IR, then you will need to add that handler to the IR map. This may be accomplished
by adding a new member to the stIRMap structure within _Define Structure.axi, then initializing
that member within the DEFINE_START section of Custom.axi. If your device is controlled via
RS-232, Ethernet, or Relay, then you will need to add handling of your unique ID to the device's
Control Logic, or create a new Control Logic geared towards your device. See the How to create a
custom Control Logic. section on page 24 for instructions on creating new Control Logics.
Advanced Customization
NetLinx Database Manipulation
For advanced programmers, more complex customization may be accomplished while remaining
true to the architecture of DXP-HT NetLinx. Because all source code that is generated by the
Wizard is open for modifications, careful study of the overall architecture and a full understanding
of the database-driven model can unlock the true power of the DXP-HT application.
Properties for all interfaces are stored in the Interface table (v_rstInterface). Note that the
prefix "rst" should be read, "Array of Structures". Some members of the interface structure are
initialized in Config.axi by the Wizard. Others are internal to NetLinx. Custom members may be
added to the interface database by defining them within the stInterface structure within
_Define Structure.axi.
Properties for all sources are stored in the Source table (v_rstSource). Much like the Interface
table, some members of the source structure are initialized in Config.axi by the Wizard while others
are internal to NetLinx. Adding members to the Source database may be accomplished by defining
them within the stSource structure within _Define Structure.axi.
Properties for all display devices are stored in the Display table (v_rstDisplay). Just as with
interfaces and sources, some members of the display device structure are initialized in Config.axi
by the Wizard while others are internal to NetLinx. Adding members to the Display database may
be accomplished by defining them within the stDisplay structure within _Define Structure.axi.
The device categories (or families) are stored in the Device Types table (v_rstDevType). Most
members of this table are written by the Wizard but a few are defined during startup as the facility
configuration is gleaned from the Display and Source databases. New device categories may be
added to DXP-HT by adding them to this database. For example, if a facility called for the inclusion
of a Laser Disc Player, which is not supported by default, a new record could be added to this table
to define the category, then a Laser Disc Player could be added to the source table as a member of
the new category. See the How to manually add a source to the NetLinx database. section on
page 21 for step-by-step instructions on adding unsupported devices.
Macros are stored in the Macros database (v_rstMacroSeq). See the How to create a custom event
handler. section on page 15 for step-by-step instructions regarding manual macro creation.
If the Source database in Config.axi (v_rstSource) does not contain a source of type c_nMacro
then you must create one. If a source of type c_nMacro already exists, skip to step 4. Otherwise,
follow these steps to create a new Macro "source":
1. First, locate the About "source," which should be the last index of the Source database.
Immediately before the section pertaining to the About source, paste the following three lines
of source code:
// Macro "source"
v_rstSource[20].strName = "'Macros'"
v_rstSource[20].nSourceType = c_nMacro
Ensure that the subscript is the next in line. For instance, make the Macro "source" subscript
(20 in this example) the subscript of the About "source," then increment the About source's
subscript by one (since it should always be the last "source").
2. Next, increase the CfgDefineSources() return value by one. The RETURN statement
immediately follows the initialization of the About "source." The subscript on the About
"source" and the return value should be identical.
3. Finally, in Main.AXS, increase the value of c_nMaxSources by one. You have now created a
new "macro source" that will appear on the main menu of the touch panel.
4. Now you are ready to create your macro. In the function cfgDefineMacros(), increase the
return value by one. Then paste the following block into the function immediately above the
RETURN statement:
v_rstMacroSeq[x].stStep[1].dvID = y:y:y
v_rstMacroSeq[x].stStep[1].nActionID = c_qPulse
v_rstMacroSeq[x].stStep[1].stParam.nParam1 = z
…where…
! y:y:y = the D:P:S device ID of the card that should pulse, and
the range of those already defined within _Define Constant.axi. It is recommended that the
naming convention be followed where "c_" indicates that the value is a constant and "q"
indicates it is a "Queue Action ID." Be sure to define your custom constant outside the range of
those that exist in the core NetLinx code. After creating your custom Action ID, it must be
handled in Macro Engine Handlers.axi. Be careful to save any modifications to Macro Engine
Handlers.axi within a separate working directory, as DXP-HT will overwrite this file any time
you regenerate your project. See the NetLinx Database Manipulation section on page 15 for
more information regarding Action IDs.
The example macro shown in FIG. 3 will be assigned to one of the 32 custom macro buttons on the
interface. Upon project generation, the Wizard will name the button "Movie Mode". When the user
presses the "Movie Mode" button, the Macro Engine will immediately execute the first step, which
is to lower the screen. Immediately after lowering the screen, your custom code within
CustomMacroFunction01 (), which is in the file Custom Macro Handlers.axi, will execute.
Next, the display device will turn ON, then a 5-second wait will transpire. Then, your custom code
within CustomMacroFunction02 () will execute. The Macro Engine will proceed to complete
steps 6, 7, and 8.
It should be noted that each of the 32 custom macro functions can call other custom functions that
you develop. Also, if need be, nested macros may be included within the custom macro functions.
See the following section for more information regarding programmatic use of the Macro Engine.
! The Action ID is a unique identifier used by the Macro Engine to determine which block
of code to execute. The value of the Action ID is irrelevant, but it must be unique.
! By convention, Action IDs are prefixed with "c_q". The "c_" indicates that the value is a
constant and the "q" indicates that it is a Queue Action ID.
! Several Action IDs exist already within _Define Constants.axi. Be sure to define your
Action ID such that it does not conflict with any existing Action IDs. It is recommended
that your custom Action IDs start at 500+. To see those Action IDs that exist within the
core NetLinx code, open _Define Constants.axi and search on "c_q".
! Macro Engine Handlers.axi contains a SWITCH...CASE statement with handlers for all
Queue Action IDs. You will need to create your own branch of the SWITCH...CASE. Note
that Macro Engine Handlers.axi is another core DXP-HT file that will be overwritten any
time you regenerate your project. Therefore, any modifications to this file imply that your
code must be saved to a working directory that is untouched by the Wizard.
! The parameters for the Macro Engine include a "generic" structure that can be used to
pass in values to be retrieved when the Action ID is handled. Retrieval of any value from
the parameter list implies a contact between the caller and the handler. For example, if we
retrieve any value from the parameter list then we must also ensure that we have passed
that value in when we "instantiated" the macro. Passing parameters into the Macro
Engine is described further in the next section.
The following table lists the parameters that may be retrieved when the Action ID is handled within
Macro Engine Handlers.axi:
Additional parameters for general use may be added to the Macro Engine via
additions to the stMacroParam structure in _Define Structure.axi.
! Any macro sequence requires creation of an Instance with as many steps as necessary (up
to c_nMaxMacroSteps).
! Following is an example of creation of a 1-step macro that will simply pulse an IR code
(note that c_qPulse is predefined in the turnkey DXP-HT NetLinx code):
STACK_VAR stMacroParam stMP // Macro parameters
Additional device categories may be added by duplicating an existing type and incrementing the
index:
1. Copy an existing set from the Device Types table (v_rstDevType) and paste it to the end of
the CfgDefineDeviceTypes() function.
5. After following the steps above, you must create a source or display device that falls within the
new device type category. See the following section for instructions on manually adding
sources to the NetLinx database.
If your source does not fall within this category, refer to section 4.5 for instructions about creating
your own device category (or family).
Assuming the source that you are adding falls into an existing or newly created category, follow
these steps to add it to the NetLinx database:
1. In Config.axi, find the CfgDefineSources() function. Scroll down to the end of the function
until you reach the About "source." Increase the index of the About "source" by one (i.e., if it
exists at v_rstSource[15] then increment all indexes in that section such that they read
v_rstSource[16]).
2. Increase the return value of the CfgDefineSources() function by one.
3. In Main.AXS, increase the value of c_nMaxSources by one.
4. In Config.axi, copy an existing source initialization. Do not copy any irMap or rstPreset
blocks. Paste the block towards the end of the CfgDefineSources() function, immediately
before the About "source."
5. Increment all indexes on the copied block so that they immediately precede the indexes of the
About section. Note that all indexes within a section should be identical. For example, if your
new source falls at v_rstSource[15] then all indexes within the block should be 15.
6. Initialize the members according to the following member descriptions:
If you are creating a custom Control Logic for an IR controlled device, you may act directly upon
the device or you may simply set the values of nIR and nPulseType. If you initialize nIR and
nPulseType within your Control Logic, functions within the parent file (Control.axi) will send IR
automatically. This occurs because modifying the value of the two parameters will also modify the
value of the variables that were passed in by the calling function (either ControlSourceDevice
or ControlDisplayDevice).
! nIR should be set equal to the value of the IR channel that you need to actuate.
{
// Send the command to the device:
SEND_STRING dvID,'STOP'
Feedback
By default, almost all button pushes utilize momentary feedback. That is, for the duration that the
button is pushed, it will remain ON and it will turn OFF when the user releases the button.
Feedback may be overridden for any Control Logic by adding the unique identifier of the Control
Logic to the c_rFdbkOverride array. Controlling feedback for your custom Control Logic via the
Control Logic itself is a 3-step process:
1. In the DEFINE_CONSTANT section of Main.axs, add the following compiler directive:
#DEFINE FdbkOverride.
2. In the DEFINE_CONSTANT section of Main.axs, add the following declaration:
c_nMaxFdbkOverrides = [x], where [x] is the number of custom Control Logics that
you have created plus 3. We add three because DXP-HT already overrides feedback for the
three built in relay Control Logics (see next step).
3. In the DEFINE_CONSTANT section of Main.axs, add the following declaration, where
c_nMyCtrlLogic represents the unique identifier that you created for your Control Logic
(note that the pre-existing relay Control Logics must be included in this array):
INTEGER c_rFdbkOverride[c_nMaxFdbkOverrides] = {
c_nRelay01,
c_nRelay02,
c_nRelay03,
c_nMyCtrlLogic }
After completing the steps described above, no feedback will be intrinsically available for any
device that utilizes your custom Control Logic. It is now your responsibility to handle feedback
within the Control Logic itself.
Several functions are available to facilitate interface feedback:
? nBtnSet The "Device Used" value of the buttons that are utilizing your
Control Logic. This must be a value 1-4.
? nChan The channel that you need to turn ON.
? nBtnSet The "Device Used" value of the buttons that are utilizing your
Control Logic. This must be a value 1-4.
? nChan The channel that you need to turn OFF.
? nBtnSet The "Device Used" value of the buttons that are utilizing your
Control Logic. This must be a value 1-4.
? nChan The channel that you need to turn OFF.
? bState A "Boolean" value used to determine whether the button
should be turned ON or OFF. This may be passed as an eval-
uation. Following is an example of a call to TPFdbk:
TPFdbk (c_nDVDSetIdx,
c_btnDVDPlay,
v_rstSource[nSrcDBIdx].nCurrState =
c_nPlay))
You may also manually set feedback from within your custom Control Logic by simply turning
interface channels ON and OFF. However, use of the functions described above will automatically
account for the following:
! ? Feedback will automatically propagate across all interfaces that exist within the
system.
! ? Feedback flags will be set so that interfaces will be properly initialized when they
come online.
! General Messaging - miscellaneous debug messaging that is used throughout the code.
! Path of Execution - debug messaging that is displayed when functions are entered and
exited. This can be used to track the logical flow of the code.
! Macro Engine - technical debug messages related to the operation of the Macro Engine.
Typically, this level will be utilized only by AMX Technical Support.
! Errors & Exceptions - errors and warnings regarding database access, parameter
validation, and similar tasks.
Debug messages may be viewed via Terminal or Telnet connected to the NetLinx master. Be sure
NetLinx master messaging is enabled via the MSG ON command, which may be entered via
Terminal or Telnet.
You may add your own debugging and diagnostics statements via the Debug function. The
parameters of the Debug function are described as follows:
! INTEGER nLevel - The debugging level to which the statement applies. This must be
one of the following constants:
! c_nGeneral
! c_nPath
! c_nHandler
! c_nMacro
! c_nError
DbgSetFlag (c_nGeneral)
DbgSetFlag (c_nPath)
DbgSetFlag (c_nHandler)
DbgSetFlag (c_nMacro)
DbgSetFlag (c_nError)
Glossary
! Control Logic - A block of source code that is built around the behaviors and properties
of a specific device. Control Logics may drive any device type (RS-232, Ethernet, Relay,
or IR). Typically, Control Logics are geared towards RS-232 or Ethernet devices that
require specialized handling beyond simple "push & pulse". A Control Logic may call
directly into a module or it may act upon the device itself. For IR controlled devices, the
Control Logic may merely set a channel ID and pulse type for handling within it's parent
function, ControlSourceDevice or ControlDisplayDevice.
! D.O.C. - Disk On Chip. This is hardware that is built into the NetLinx controller for use
in storing and retrieving persistent data.
! Module - A compiled block of source code that is designed to control one specific device
or a set of devices that have identical or similar behavior. Modules are compiled code that
are instantiated as standalone binary entities, analogous to a COM Object in some
respects. Modules expose a standardized API which permits control of a host of devices
via the same NetLinx source code.
AMX reserves the right to alter specifications without notice at any time.
ARGENTINA • AUSTRALIA • BELGIUM • BRAZIL • CANADA • CHINA • ENGLAND • FRANCE • GERMANY • GREECE • HONG KONG • INDIA • INDONESIA • ITALY • JAPAN
LEBANON • MALAYSIA • MEXICO • NETHERLANDS • NEW ZEALAND • PHILIPPINES • PORTUGAL • RUSSIA • SINGAPORE • SPAIN • SWITZERLAND • THAILAND • TURKEY • USA
ATLANTA • BOSTON • CHICAGO • CLEVELAND • DALLAS • DENVER • INDIANAPOLIS • LOS ANGELES • MINNEAPOLIS • PHILADELPHIA • PHOENIX • PORTLAND • SPOKANE • TAMPA
3000 RESEARCH DRIVE, RICHARDSON, TX 75082 USA • 800.222.0193 • 469.624.8000 • 469-624-7153 fax • 800.932.6993 technical support • www.amx.com