Files
JIMRI/help/en/html/apps/DecoderPro/CreateDecoderAdvanced.shtml
T
2026-06-17 14:00:51 +02:00

1200 lines
57 KiB
Plaintext

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="generator" content="HTML Tidy for HTML5 for Apple macOS version 5.8.0">
<!-- Copyright Bob Jacobsen 2008 -->
<title>JMRI: DecoderPro User Guide - Advanced Decoder Definitions</title>
<!--#include virtual="/help/en/parts/Style.shtml" -->
</head>
<body>
<!--#include virtual="/help/en/parts/Header.shtml" -->
<div id="mBody">
<!--#include virtual="Sidebar.shtml" -->
<div id="mainContent">
<h1>JMRI: DecoderPro User Guide</h1>
<h2>Advanced Decoder Definitions</h2>
<p>This page provides information on advanced features in the decoder definition files for
the DecoderPro Symbolic Programmer.</p>
<h3 id="html_formatting">Formatting on the page</h3>
You can do limited formatting on the display using HTML formatting tags.
<p>You can embed HTML in pane text, but it must be enclosed in &lt;html&gt;...&lt;/html&gt;
tags.</p>
<p>This is made a bit tricky because of overlap between "tags as part of XML structure of
decoder file" and "HTML tags included in the decoder file". All HTML tags need to be
quoted, with their &lt; and &gt; characters replaced by the &amp;lt; and &amp;gt; strings and
any embedded double quotes being replaced by &amp;quot;.</p>
<p>For example:</p>
<pre style="font-family: monospace;">
&lt;label label="&amp;lt;html&amp;gt;&amp;lt;strong&amp;gt;JMRI 3.7.2 or later is required to use this definition.&amp;lt;/strong&amp;gt;&amp;lt;/html&amp;gt;"/&gt;
</pre>After the XML is read, the contents of that label will be displayed from the text in the
"label" attribute, which is:
<pre style="font-family: monospace;">
&lt;html&gt;&lt;strong&gt;JMRI 3.7.2 or later is required to use this definition.&lt;/strong&gt;&lt;/html&gt;
</pre>and will appear on the screen as
<p><strong>JMRI 3.7.2 or later is required to use this definition.</strong>
</p>
<p>For more examples see <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/esu/v4readMePane.xml" target=
"_blank">xml/decoders/esu/v4readMePane.xml</a>.</p>
<p>This provides only HTML5 support, so if something isn't displaying as you expect, see if
an approach using simpler HTML will work.</p>
<h3 id="id">Identification</h3>
When "Read Type from Decoder" is used to determine the correct decoder definition file,
several pieces of information are read from the decoder and used to attempt a match to a
family and model:
<dl>
<dt>Manufacturer:</dt>
<dd>Numerical value from CV8, which is then matched to a name using the entries in the
xml/decoderIndex.xml file.</dd>
<dt>Version code:</dt>
<dd>Numerical value from CV7, which is then matched to model name(s) using the lowVersionID
and highVersionID values on model elements within all decoder definitions for the specific
manufacturer. This is a complex process that doesn't always go well due to duplicate
values, etc.</dd>
<dt>Product ID code:</dt>
<dd>
Originally a numerical value read from a manufacturer-specific CV or CVs; this only works
for certain manufacturers. The read process is handled in the code (the <a href=
"/JavaDoc/doc/jmri/jmrit/decoderdefn/IdentifyDecoder.html" target=
"_blank">jmri.jmrit.decoderdefn.IdentifyDecoder</a> class) and has to be updated each
time a manufacturer starts providing values in one or more new CVs. When the product code
is present, it should break any degeneracy between overlapping CV7 values within a
decoder family. For example:
<pre style="font-family: monospace;">
&lt;decoder&gt;
&lt;family name="My Decoder Family" mfg="NMRA"&gt;
&lt;model model="Model A" lowVersionID="16" highVersionID="23" productID="400" /&gt;
&lt;/model&gt;
&lt;model model="Model B" lowVersionID="21" highVersionID="27" productID="401" /&gt;
&lt;/model&gt;
&lt;/family&gt;
&hellip;
&lt;/decoder&gt;</pre>
<p>Some decoders can have multiple possible stored Product IDs for otherwise-identical
decoders. In this case multiple comma-separated values can be specified in the Product ID
field and a match to any value in the list will identify the decoder uniquely. For
example, the ESU series usesthe RailCom&reg; Product ID CVs, but the Product ID is updated
for various production batches of the same model:</p>
<pre style="font-family: monospace;">
&lt;decoder&gt;
&lt;family name="ESU LokSound V4.0" mfg="Electronic Solutions Ulm GmbH" lowVersionID="255" highVersionID="255"&gt;
&lt;model model="LokSound V4.0" numOuts="92" numFns="40" extFnsESU="yes" productID="33554493,33554503,33554538"&gt;
&lt;/model&gt;
&lt;model model="LokSound V4.0 M4" numOuts="92" numFns="40" extFnsESU="yes" productID="33554500,33554536"&gt;
&lt;/model&gt;
&lt;/family&gt;
&hellip;
&lt;/decoder&gt;</pre>
<p id="idwarn"><strong>Warning:</strong> Do not use multiple possible stored Product IDs
for similar decoders that need different <a href="#conditional">conditional
expansion</a>. It will not work, for reasons explained <a href="#prodidwarn">in a section
below</a>. In this case, each Product ID must be assigned a different model name, as in
the first example above.</p>
<p>Support is also being added to find this value using the <a href=
"../../hardware/loconet/Addressing.shtml#SVs" target="_blank">LocoNet SV2 protocol</a>
some time during the JMRI 4.1 release series. See the release notes for more info on the
progress.</p>
<p>Since the product code works with the include/exclude operations described below, you
can also use it in cases where there's no CV or CVs that contain it. In that case, no
automated ID is done, but the value from the productID attribute of the user-selected
model is used during later processing and expansion of the decoder definition.
Alphanumeric productID values are sometimes used for this to avoid conflicts with the
numeric ones found in CVs.</p>
</dd>
</dl>
<p>When a decoder model is selected, either manually or as the result of the identification
process, the family and model names are stored in the roster entry being created and are used
for future linkage of a roster entry to a decoder definition.</p>
<p>It is important to note that the Manufacturer, Version Code or Product ID are not stored
in the roster entry, as the values are not reliably determined in some instances (e.g. manual
selection, firmware update by manufacturer-supplied software, updated ID information from
vendor). This has implications for when the decoder definition is expanded for programming
(<a href="#conditional">Conditional Decoder Definitions</a>) or updated (<a href=
"#update">Updates and Migration</a>).</p>
<h4>Public-domain and DIY decoders</h4>
<span class="since">Since <a href="/releasenotes/jmri4.11.5.shtml" target="_blank">JMRI
4.11.5</a></span>
<p>The "Read Type from Decoder" feature is available for Public-domain and DIY decoders.</p>
<p>Three identifiers are used to identify the decoder:</p>
<dl>
<dt>Manufacturer:</dt>
<dd>Numeric value <strong>CV8 = 13</strong> according to the NMRA standard S-9.2.2.
file.</dd>
<dt>Version code:</dt>
<dd>The numeric value from <strong>CV7</strong> where the software version is stored.</dd>
<dt>Product ID code:</dt>
<dd>
Numeric value stored in <strong>CV47</strong>, <strong>CV48</strong>,
<strong>CV49</strong> and <strong>CV50</strong> according to NMRA standard S-9.2.2 file
and reserved for use by the manufacturer.
<p>Product ID is calculated using the following formula:</p>
<ul>
<li>Product ID = (((CV47 * 256) + CV48) * 256 + CV49) * 256 + CV50</li>
</ul>
<p>Individual CVs have the following meaning:</p>
<ul>
<li>CV47 - country code, for example CV47 = 1 for the Czech Republic</li>
<li>CV48 - developer or group of developers code, such as CV48 = 1 for dccdoma.cz</li>
<li>CV49 - third ProductID for further identification</li>
<li>CV50 - fourth ProductID for further identification</li>
</ul>
</dd>
</dl>
<p>The corresponding decoder definition xml file has a filled &lt;family&gt; element.
Example:</p>
<pre style="font-family: monospace;">
&lt;decoder&gt;
&lt;family name="dccdoma.cz" mfg="Public-domain and DIY" &gt;
&lt;model model="UNI16ARD-NAV" lowVersionID="41" productID="16843010" &hellip; /&gt;
&lt;/family&gt;
&hellip;
&lt;/decoder&gt;</pre>
<p>The individual attributes of this element must be filled in as follows:</p>
<ul>
<li><strong>mfg="Public-domain and DIY"</strong> that matches CV8</li>
<li><strong>lowVersionID="nn" highVersionID="mm"</strong> that matches CV7</li>
<li><strong>productID="nnnnnn"</strong> that matches CV47, CV48, CV49 and CV50</li>
</ul>
<p>The name of the xml file with the definition of the decoder should have the following
structure:</p>
<pre style="font-family: monospace;"><strong>Public_Domain</strong>_<strong>family-name</strong>_<strong>model-model</strong>.xml</pre>
<p>Where each part of a file name has the following meaning:</p>
<ul>
<li><strong>Public_Domain</strong> that matches attribute &lt;family mfg="Public-domain and
DIY" &gt;</li>
<li><strong>family-name</strong> that matches attribute &lt;family name="developer"
&gt;</li>
<li><strong>model-model</strong> that matches attribute &lt;model model="decoder name"
&gt;</li>
</ul>
<p>Example of a definition decoder file for signal decoder <em>UNI16ARD-NAV.xml</em> from the
developers group <em>dccdoma.cz</em> who are from <em>the Czech Republic</em> <a href=
"../../../../../xml/decoders/Public_Domain_dccdoma_UNI16ARD_NAV.xml">Public_Domain_dccdoma_UNI16ARD_NAV.xml</a>.</p>
<p>For the new <em>country code</em> and new <em>developer code</em>, please contact
Groups.io jmriusers <a href=
"https://groups.io/g/jmriusers">https://groups.io/g/jmriusers</a>.</p>
<h3 id="pane_considerations">Pane Considerations</h3>
Programmer panes are used to split and organise decoder variables into convenient named
categories.
<ul>
<li>JMRI provides a standard set of panes, defined by &lt;pane&gt; elements included in the
&lt;programmer&gt; element of each of the standard Programmer files (Basic, Comprehensive,
Advanced, etc.) in the xml/programmers/ folder.</li>
<li>Decoder definition files can contain custom panes for particular decoders or families
of decoders, defined by &lt;pane&gt; elements included in the &lt;decoder-config&gt;
(top-level) element of the decoder file.</li>
<li>Pane names are specified by a &lt;name&gt; element at the top of each &lt;pane&gt;
element.</li>
</ul>
<h4 id="pane_replacement">Pane Replacement</h4>
Custom panes are usually added to definition files for one of the following reasons:
<ol style="list-style: upper-alpha;">
<li>The items to be shown do not fall into any of the categories defined by the standard
pane names.
<ul>
<li>In this case the pane &lt;name&gt; element should be different from any existing
standard names.</li>
<li>The new custom pane will be added at the end of the pane list.</li>
</ul>
</li>
<li>The applicable standard pane category does not have the correct layout or number of
variables.
<ul>
<li>In this case the pane &lt;name&gt; element should exactly match the existing
standard pane &lt;name&gt; element.</li>
<li>The new custom pane will <strong><em>replace</em></strong> the existing same-named
standard pane.</li>
</ul>
</li>
</ol>
<h4>Empty Panes</h4>
Empty panes are defined as those with no active variable elements to display for the selected
decoder. They may still contain text content.
<a id="pane_visibility"></a>
<h4 id="visibility">Pane Visibility</h4>
Pane visibility is governed by a complex set of rules:
<ul>
<li>Irrespective of all other rules, a pane will not show if it fails any <a href=
"#pane_include">"include" or "exclude" attributes</a> in its &lt;pane&gt; element.
</li>
<li>Empty pane visibilty is controlled by the following, in increasing order of priority:
<ul>
<li>The Preferences-&gt;Roster-&gt;Programmer-&gt;Show Empty Tabs setting.</li>
<li>If present, a showEmptyPanes attribute in the current programmer XML file.</li>
<li>If present, a showEmptyPanes attribute in the specific decoder defintiion XML
file.</li>
</ul>
</li>
As a special case, the suppressFunctionLabels and suppressRosterMedia
attributes on the decoder-config element can be used to suppress the
Function Labels and Roster Media panes respectively whether or not they are empty.
<li>Whether a specific empty pane (as defined in Empty Panes above) shows also depends on
the pane type:
<ul>
<li>If the empty pane is a standard pane (as defined in <a href="#pane_considerations">
Pane Considerations</a> above), it will only show if showEmptyPanes is in force.
<em>However, its usual contents will be replaced by a generic message explaining that
the pane is unused since the contents are inapplicable or appear on another
pane.</em>
</li>
<li>If the empty pane is a replacement pane (as defined in item B of <a href=
"#pane_replacement">Pane Replacement</a> above), it will only show if showEmptyPanes is
in force.
</li>
<li>If the empty pane is a custom pane (as defined in item A of <a href=
"#pane_replacement">Pane Replacement</a> above), it will always show, irrespective of
whether showEmptyPanes is in force.
</li>
</ul>
</li>
</ul>
<h4 id="pane_best_practice">Best Practice</h4>
Advanced users may choose to hide empty panes, but Show Empty Tabs is enabled by default so
beginner users need to see why panes are empty or where to find items not on the expected
panes.
<p>The recommended best practice is:</p>
<ul>
<li>Where possible, items should use the existing standard panes.</li>
<li>Where a particular existing standard pane does not suit in terms of number of items or
layout:
<ul>
<li>Create a <a href="#pane_replacement">replacement pane</a> with the same name as the
existing standard pane.
</li>
<li>For examples, see the Advanced and Sound panes of the <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/ESU_LokSoundV4_0.xml" target=
"_blank">ESU_LokSoundV4_0</a> decoder definition.
</li>
</ul>
</li>
<li>Where an existing standard pane does not suit in terms of concept:
<ul>
<li>Create one or more new <a href="#pane_replacement">custom panes</a> with unique
descriptive names.
</li>
<li>Create information-only (no variable display elements, just text) <a href=
"#pane_replacement">replacement panes</a> with the same names as any existing unused
standard panes. Use these panes to explain why each pane is unused and/or where to find
the information a user may reasonably expect to find on this pane. Use <a href=
"#html_formatting">HTML formatting</a> to enhance the display of these explanatory
panes.
</li>
<li>For examples, see the Lights and Sound Levels panes of the <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/ESU_LokSoundV4_0.xml" target=
"_blank">ESU_LokSoundV4_0</a> decoder definition.
</li>
</ul>
</li>
<li>Information-only <a href="#pane_replacement">custom panes</a> will <em>always</em> be
displayed.
</li>
</ul>
<p>In some cases, e.g. a non-locomotive decoder for servos where none of the
locomotive-decoder panes make sense so the decoder definition contains lots of custom panes,
it's a simplification to put a showEmptyPanes="no" attribute in the &lt;decoder-config&gt;
element of the definition XML and just hide all those empty panes by default.</p>
<h3 id="frag_include">Including Fragment Files</h3>
Common parts of decoder definitions can be placed into "fragment files", which can then be
included into multiple decoder definition files. This makes it easier to maintain and update
those common definitions, e.g. to translate them into other languages.
<p>By convention, we these fragment files in subdirectories:</p>
<dl>
<dt>xml/decoders/nmra</dt>
<dd>The NMRA definitions for CVs, used by many decoder types</dd>
<dt>xml/decoders/(mfg)</dt>
<dd>Manufacturer-specific variables, for example xml/decoders/esu</dd>
</dl>
The format for an include is:
<pre style="font-family: monospace;">
&lt;xi:include href="http://jmri.org/xml/decoders/nmra/shortAndLongAddress.xml"/&gt;
</pre>The program searches for those fragment files first in the preferences directory, then in the
program directory. The full path must be present, e.g. you need an xml directory that contains a
decoders directory in your preferences directory for the fragment file to be found.
<p>Use an existing file as an example for the top elements & format needed.</p>
<h3 id="update">Updates and Migration</h3>
Sometimes, we replace a decoder definition with a better one. The old one is in use, but we'd
like to move those users to the new one eventually. There are model-level attributes that can
be added to the old (not the new) definition to facilitate that:
<pre style="font-family: monospace;">
&lt;model show="no" model="A4X" replacementModel="A4X" replacementFamily="Jan 2012"&gt;
</pre>
When the user selects "Update Decoder Definitions" from the Debug menu on PanelPro
window or the Action menu in DecoderPro, all their existing roster entries that use a decoder
definition with replacementModel and/or replacementFamily defined will be updated to the specified
replacement decoder definition instead. This lets people keep using their old, comfortable decoder
definition (the old file remains in JMRI) until they decide to move forward to a new one.
<p>Note that an update defined this way is unconditional; if the family and model attributes
match a roster entry, it will be updated to the new family/model. Automated conditional
updates based on versionID or productID are not possible as these values are <a href=
"#id">not stored</a> in the roster entry. An interactive update process is now available in
these cases and uses a special syntax: <span class="since">Since <a href=
"/releasenotes/jmri4.9.5.shtml" >JMRI 4.9.5</a></span></p>
<pre style="font-family: monospace;">
&lt;model show="no" model="DP2X" numOuts="2" numFns="2" replacementFamily="query:Jan 2000|June 2007|Jan 2012"&gt;
</pre>
<p>A replacement field begining with the string "query:", optionally (preferably) followed by
a vertical bar "|" separated list of possible replacements, triggers interactive user
dialogs, containing further explanations and guidance for the user. Click <a href=
"images/UpdDecDef1.png" >here</a> and <a href=
"images/UpdDecDef2.png" >here</a> for typical
samples of these dialogs. Missing decoder definitions will also be detected. Click <a href=
"images/UpdDecDef3.png" >here</a> and <a href=
"images/UpdDecDef4.png" >here</a> for more
samples.</p>
<p>The model element "show" attribute helps ensure that new users starts with the new
definition. Its possible values are:</p>
<ul>
<li>"yes" (default) - the traditional behavior, always show this model and the family it
contains</li>
<li>"no" - never show this model, even if it matches a possible selection. Used for legacy
(old) definitions that have been replaced with newer ones.</li>
<li>"maybe" - only show if it matches a (possible) automatic identification.</li>
</ul>
To create a completely new definition for an existing model:
<ol>
<li>Decide where you want the new model defined. It has to have either a new model name, a
new family name (new file) or both.</li>
<li>Create your definition.</li>
<li>Add "replacementModel" and "replacementFamily" attributes to the old definition.</li>
<li>Generally, set the "show" attribute in the old definition to "no". The only exception
to this is when some users will want to select the old definition still for a new decoder,
perhaps because automatic identification can tell the uses of the old definition from the
new one. (E.g. you're splitting the old definition into two parts because a new locomotive
version exists)</li>
</ol>
<h3 id="capability">Programming Capabilities</h3>
Some decoders can do extra programming operations, for example bypassing limitations on CV
programming in the command station. "Capability" elements are used to tell DecoderPro about
these.
<h4>Access to High CV addresses</h4>
Certain command stations can only access up to CV 256 or CV512. Some decoder manufacturers
have built in mechanisms to bypass this. For example, some ESU decoders can use writes to
various CVs to access high-address CVs. To tell DecoderPro that a decoder can do this, use an
element like:
<pre style="font-family: monospace;">
&lt;capability&gt;
&lt;name&gt;High Access via Double Index&lt;/name&gt;
&lt;parameter name="Max Regular CV address"&gt;256&lt;/parameter&gt;
&lt;parameter name="High Address CV"&gt;96&lt;/parameter&gt;
&lt;parameter name="Low Address CV"&gt;97&lt;/parameter&gt;
&lt;parameter name="Access Register CV"&gt;99&lt;/parameter&gt;
&lt;parameter name="Modulo"&gt;100&lt;/parameter&gt;
&lt;/capability&gt;
</pre>
<p>The parameters must appear in the order shown. They mean:</p>
<ul>
<li>"Max Regular CV address" - CV addresses equal or below this don't use this mechanism.
(The mechanism won't be used if the command station can directly read/write the CV being
requested, but even if it can't, this mechanism won't be used below this value)</li>
<li>"High Address CV" - The high part (see Modulo) of the CV address is written here at the
start of the operation</li>
<li>"Low Address CV" - The low part (see Modulo) of the CV address is written here as the
2nd part of the operation.</li>
<li>"Access Register CV" - after the address values are set, this is the CV that's read or
written to read or set the desired real CV.</li>
<li>"Modulo" - value used to split the real CV address between the high and low address
CVs.</li>
</ul>
<p>For example, to write 21 to CV 614 with the values shown, DecoderPro will:</p>
<ul>
<li>Write 6 =(614/100) to CV 96 for the high address part</li>
<li>Write 14 = (614 mod 100) to CV 97 for the low address part</li>
<li>Write 21 to CV 99 to do the actual CV write</li>
</ul>
<p>For an example of where to position this capability element in the file, etc., see the
<a href="https://github.com/JMRI/JMRI/blob/master/xml/decoders/ESU_LokSoundV4_0.xml" target=
"_blank">xml/decoders/ESU_LokSoundV4_0.xml</a> file.</p>
<p id="zimocapability">Another approach, used by e.g. Zimo, is to provide a way to page the
access. For example, to write 21 to CV614 with one of these, you need to:</p>
<ul>
<li>Write 60 =(614/100)*10 to CV 7 for the high address part</li>
<li>Write 21 to CV 14 (614 mod 100) to do the actual CV write</li>
</ul>
This capability element will do that:
<pre style="font-family: monospace;">
&lt;capability&gt;
&lt;name&gt;High Access via Partial Index&lt;/name&gt;
&lt;parameter name="Max Regular CV address"&gt;100&lt;/parameter&gt;
&lt;parameter name="High Address CV"&gt;7&lt;/parameter&gt;
&lt;parameter name="High Address Multiplier"&gt;10&lt;/parameter&gt;
&lt;parameter name="Modulo"&gt;100&lt;/parameter&gt;
&lt;/capability&gt;
</pre>Note that it has a different "name" value. That's what selects the different algorithm needed
here.
<p>The parameters must appear in the order shown. They mean:</p>
<ul>
<li>"Max Regular CV address" - CV addresses equal or below this don't use this mechanism.
(The mechanism won't be used if the command station can directly read/write the CV being
requested, but even if it can't, this mechanism won't be used below this value)</li>
<li>"High Address CV" - The high part (see Modulo) of the CV address is written here at the
start of the operation</li>
<li>"High Address Multiplier" - This multiplies the high part of the CV address before it's
stored to the High Address CV. For example, putting a 10 here will store the high address
part in the "10's digit" of the High Address CV.</li>
<li>"Modulo" - value used to split the real CV address between the high and low address
CVs.</li>
</ul>
<p id="zimobis">Another approach used by e.g. Zimo uses a page register that has to be reset
afterwards. For example, to write 21 to CV614 with one of these, you need to:</p>
<ul>
<li>Write 260 =(614/100)*10+200 to CV 7 for the high address part. The "200" is an
indicator to use this mode.</li>
<li>Write 21 to CV 14 (614 mod 100) to do the actual CV write</li>
<li>Write 0 back to CV7 to reset the indexing.</li>
</ul>
This capability element will do that:
<pre style="font-family: monospace;">
&lt;capability&gt;
&lt;name&gt;High Access via Partial Index with Reset&lt;/name&gt;
&lt;parameter name="Max Regular CV address"&gt;100&lt;/parameter&gt;
&lt;parameter name="High Address CV"&gt;7&lt;/parameter&gt;
&lt;parameter name="High Address Multiplier"&gt;10&lt;/parameter&gt;
&lt;parameter name="Modulo"&gt;100&lt;/parameter&gt;
&lt;parameter name="Indicator"&gt;200&lt;/parameter&gt;
&lt;/capability&gt;
</pre>
<p>The parameters must appear in the order shown. They mean:</p>
<ul>
<li>"Max Regular CV address" - CV addresses equal or below this don't use this mechanism.
(The mechanism won't be used if the command station can directly read/write the CV being
requested, but even if it can't, this mechanism won't be used below this value)</li>
<li>"High Address CV" - The high part (see Modulo) of the CV address is written here at the
start of the operation</li>
<li>"High Address Multiplier" - This multiplies the high part of the CV address before it's
stored to the High Address CV. For example, putting a 10 here will store the high address
part in the "10's digit" of the High Address CV.</li>
<li>"Modulo" - value used to split the real CV address between the high and low address
CVs.</li>
<li>"Indicator" - value added to the value being stored to High Address CV to tell the
decoder to use this mode.</li>
</ul>
<h4 id="accessoryops">Accessory Decoder Ops Mode</h4>
Certain accessory decoders require special programming packets to configure their CVs from
the DCC track signal. The capability to do that is written:
<pre style="font-family: monospace;">
&lt;capability&gt;
&lt;name&gt;Ops Mode Accessory Programming&lt;/name&gt;
&lt;parameter name="Address Type"&gt;decoder&lt;/parameter&gt;
&lt;parameter name="Delay"&gt;200&lt;/parameter&gt;
&lt;/capability&gt;
</pre>The "Address Type" parameter is optional:
<ul>
<li>If it is "decoder" or omitted, the current address is interpreted as a 9-bit accessory
decoder address.</li>
<li>If it is "accessory" or "output", the current address is interpreted as an 11-bit
accessory output address.</li>
<li>If it is "signal", the current address is interpreted as an 11-bit signal decoder
address.</li>
<li>If it is "altsignal", the current address is interpreted as an 11-bit signal decoder
address, using an alternative interpretation of <a href=
"https://www.nmra.org/sites/default/files/s-9.2.1_2012_07.pdf" target="_blank">NMRA
standard 9.2.1</a>).
</li>
<li>If it is "legacy", the current address is interpreted as a 9-bit address (as for
"decoder") but a "legacy" programming packet (as per Appendix A of <a href=
"https://www.nmra.org/sites/default/files/s-9.2.1_2012_07.pdf" target="_blank">NMRA
standard 9.2.1</a>) is sent.
</li>
</ul>
The "Delay" parameter is optional and specifies a minimum delay (in milliseconds) between
successive writes. Some decoders will miss commands if the delay is too short. If this is
parameter is omitted, the default delay is 500 milliseconds.
<p>Note that this only works for ops-mode writes; these particular NMRA DCC packets do not
perform read operations, nor do they work in the service mode (programming track).</p>
Note an element:
<pre style="font-family: monospace;">
&lt;variable &hellip; item="Short Address" &hellip;&gt;
&hellip;
&lt;/variable&gt;</pre>
or:
<pre style="font-family: monospace;">
&lt;variable &hellip; item="Long Address" &hellip;&gt;
&hellip;
&lt;/variable&gt;</pre>
is required so the Ops Mode programmer has an address to use. Either form functions identically.
The "Address Type" parameter is the only way to specify whether the address is 9-bit or 11-bit.
<p>For a working example, see the <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/ESU_SwitchPilot.xml" target=
"_blank">xml/decoders/ESU_SwitchPilot.xml</a> file. In the case of this example decoder, the
address is stored in CVs 1 and 9 as per <a href=
"https://www.nmra.org/sites/default/files/standards/sandrp/pdf/s-9.2.2_decoder_cvs_2012.07.pdf"
target="_blank">NMRA standard 9.2.2</a>.</p>
<h4 id="opsdelayed">Ops Mode Delayed Programming</h4>
<p>Most locomotive decoders accept special programming packets to configure their CVs from
the DCC track signal (Programming on Main).</p>
However these packets take time to process and if subsequent packets are sent too soon they
can be missed. The capability to do add a delay after programming each CV is written:
<pre style="font-family: monospace;">
&lt;capability&gt;
&lt;name&gt;Ops Mode Delayed Programming&lt;/name&gt;
&lt;parameter name="Delay"&gt;500&lt;/parameter&gt;
&lt;/capability&gt;
</pre>The "Delay" parameter specifies a minimum delay (in milliseconds) between successive writes.
Some decoders miss commands if the delay is too short. If this is parameter is omitted, the default
delay is 500 milliseconds.
<p>Note that this only works for ops-mode writes; these particular NMRA DCC packets do not
perform read operations, nor do they work in the service mode (programming track).</p>
<p>Note also that this particular capability only works for multi-function decoders.
Accessory decoders need to use the <a href="#accessoryops">Accessory Decoder Ops Mode</a>
capability, which has its own "Delay" parameter.</p>
<h4 id="indexedcap">Indexed CV Access</h4>
To access indexed CVs, include this capability element:
<pre style="font-family: monospace;">
&lt;capability&gt;
&lt;name&gt;Indexed CV access&lt;/name&gt;
&lt;parameter name="PI"&gt;31&lt;/parameter&gt;
&lt;parameter name="SI"&gt;32&lt;/parameter&gt;
&lt;parameter name="cvFirst"&gt;false&lt;/parameter&gt;
&lt;parameter name="skipDupIndexWrite"&gt;true&lt;/parameter&gt;
&lt;/capability&gt;
</pre>
<p>If cvFirst is true, the format is CV.PI or CV.PI.SI as used by QSI. If it's false, the
format is PI.CV or PI.SI.CV as used by ESU.</p>
<p>Alternately the PI and/or SI CV numbers can be set by using a "nn=nn" syntax when
specifying PI and/or SI. For example, using a cvFirst false syntax, "101=12.80" sets CV101 to
12 before accessing CV 80, regardless of the PI value configured into the capability.</p>
<p>If skipDupIndexWrite is true, certain writes to the PI and SI CVs can be skipped if the
user selects skipping them. This speeds up access. Some decoders require that the CVs be
written for each operation, in which case this should be set to false. The default is
true.</p>
<p>In some cases, you want to reset the PI and SI values after the indexed CV
is read or written. To do that, put the new values after a semicolon:
11.12.123;0.1 for example. Note that this only works when both PI and
SI are being written; the case where just PI is used has not been
programmed yet.
<p>If both this and the "access to high CV" capabilities are present, this one should be
listed second.</p>
<p>For an example of where to position it etc., see the <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/ESU_LokSoundV4_0.xml" target=
"_blank">xml/decoders/ESU_LokSoundV4_0.xml</a> file.</p>
<h4 id="tcsaccess">TCS WOW decoder access</h4>
The TCS WOW decoders use several unique (to say the least) CV access methods. JMRI
accommodates them via a special capability element:
<pre style="font-family: monospace;">
&lt;capability&gt;
&lt;name&gt;TCS 4 CV access&lt;/name&gt;
&lt;/capability&gt;
</pre>This provides two custom CV formats:
<dl>
<dt>T2CV.11.12</dt>
<dd>Writes 11 to the first index CV (201), 12 to the 2nd index CV (202), then
does write/read/confirm operations on CV 203 and 204</dd>
<dt>T3CV.11.12.13</dt>
<dd>Writes 11 to the first index CV (201), the data to the 2nd index CV
(202), then writes 12 to CV203 and 13 to CV204.</dd>
</dl>
For examples of how to use these, see the TCS WOW decoder definition.
<h3 id="masks">Masks - inserting variables into part of a CV</h3>
A mask attribute declared in a variable definition is a pattern to control which part in a CV
contains our variable. Masks can be applied to a single CV, i.e. a decVal or enumVal type, or to
multiple CV's like <a href="#splitval">splitVal</a>.<br>
JMRI supports 2 mask types:
<p>A string like <code>XXXVVVXX</code> where each "V" is a bit that's included, and "X"
is a bit that's not to be included. It's best to have eight characters, as that makes it clearer
what's going on. If the variable is a full byte, this attribute can be omitted.<br>
Generally, the V characters should be a contiguous block of bits as specified in
the manufacturer's documentation for the decoder.<br>
In certain rare cases, the layout of the decoder might require a different pattern like
<code>XXVVXXVV</code>, but in those cases please check the operation of the resulting decoder
definition carefully to make sure it does what you want.</p>
<span class="since">Since <a href="/releasenotes/jmri4.15.2.shtml">JMRI 4.15.2</a></span><p>A second mask
pattern, Radix, is useful in cases where instead of bits, digits, triplets or some other unit
make up a pattern such as 1234C where "1234" is a turnout address and "C" is some other variable.
To define the address part, you would use:<br>
<code>mask="10"</code> as an attribute in the variable element (that is the base where our part starts, at
the 'tens') and<br>
<code>max="10000"</code> in the value element (to reserve 10^4 values for 4 digits).<br>
For example:
<pre>
&lt;variable CV="11" item="Address" mask="10">
&lt;decVal min="0" max="10000"/>
&lt;label>Address:&lt;/label>
&lt;/variable&gt;</pre>
A Radix mask can handle CVs that are coded in bases other than binary: Ones that store their parts
as decimal digits (as our example), or even base 3 or 5. That's a bit more technical, it's rarely
needed, but if you do need it, refer to the <a
href="https://www.jmri.org/JavaDoc/doc/jmri/jmrit/symbolicprog/VariableValue.html">javadoc</a> for
more details. The <a href="https://github.com/JMRI/JMRI/blob/master/xml/decoders/Uhlenbrock_63410.xml">Uhlenbrock_63410</a> definition
provides an example on CV1. The decoder definition using a Radix mask should point to /schema/decoder-4-15-2.xsd.
<h3 id="splitval">Split Variables - spread over multiple CVs</h3>
<span class="since">Since <a href="/releasenotes/jmri4.15.5.shtml">JMRI 4.15.5</a></span>
<p>Some decoders use variables that are spread over multiple CVs, contiguous or not.</p>
<p>A number of types are provided to handle this situation:</p>
<ul>
<li>A <a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitVariableValue.html" target=
"_blank">splitVal</a> type. This handles a numeric value stored across multiple CV's
(tested for up to 8 CVs).
<ul>
<li>For examples, see <a href="#splitvalExample">splitVal example</a> below and this
<a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/esu/v4decoderInfoCVs.xml"
target="_blank">decoder fragment file</a>.
</li>
<li>For details of required/optional attributes and advanced features, see this
<a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitVariableValue.html" target=
"_blank">JavaDoc page</a>.
</li>
</ul>
</li>
<li>A <a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitHexVariableValue.html" target=
"_blank">splitHexVal</a> type. This is like <a href=
"/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitVariableValue.html" target="_blank">splitVal</a>
but with the number entered and displayed in hexadecimal. An optional "case=" attribute can
be used to force the number to be displayed in "upper" or "lower" case.
<ul>
<li>For examples, see this <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/esu/v4decoderInfoCVs.xml"
target="_blank">decoder fragment file</a>.
</li>
<li>For details, see this <a href=
"/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitHexVariableValue.html" target=
"_blank">JavaDoc page</a>.
</li>
</ul>
</li>
<li>A <a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitDateTimeVariableValue.html"
target="_blank">splitDateTimeVal</a> type. This is like <a href=
"/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitVariableValue.html" target=
"_blank">splitVal</a> but the number displayed represents a Date and/or Time value.
<ul>
<li>For examples, see this <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/esu/v4decoderInfoCVs.xml"
target="_blank">decoder fragment file</a>.
</li>
<li>For details of required/optional attributes and advanced features, see this
<a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitDateTimeVariableValue.html"
target="_blank">JavaDoc page</a>.
</li>
</ul>
</li>
<li>A <a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitTextVariableValue.html" target=
"_blank">splitTextVal</a> type. This is like <a href=
"/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitVariableValue.html" target="_blank">splitVal</a>
but allows the entry, storage (in CVs) and display of text strings. The number of CVs
allocated by the user in the definition governs the maximum string length.
<ul>
<li>For examples, see this <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/esu/v4projectInfoCVs.xml"
target="_blank">decoder fragment file</a>.
</li>
<li>For details of required/optional attributes and advanced features, see this
<a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitTextVariableValue.html" target=
"_blank">JavaDoc page</a>.
</li>
</ul>
</li>
<li>A <a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitEnumVariableValue.html" target=
"_blank">splitEnumVal</a> type. This is like <a href=
"/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitVariableValue.html" target="_blank">splitVal</a>
but uses the selection of one object from a specified list.
<ul>
<li>For examples, see this <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/TCS_BachmannFT.xml"
target="_blank">decoder file</a>.
</li>
<li>For details of required/optional attributes and advanced features, see this
<a href="/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitEnumVariableValue.html" target=
"_blank">JavaDoc page</a>.
</li>
</ul>
</li>
</ul>
<p>The CVs to be used are specified in the <code>CV</code> attribute and masks (if required)
in the <code>mask</code> attribute.
Both CVs and masks are specified lowest-value first order:
The least
significant bit of the value will be in the first CV and mask specified, and the most
significant bit of the value will be in the last CV and mask specified.
For example:</p>
<pre style="font-family: monospace;">
&lt;variable CV="1,27,13" mask="XXVVVVVV XXXXXVVV XXXXXVVV" item="Sample Item"&gt;
&lt;splitVal/&gt;
&lt;/variable&gt;
</pre>
puts the least significant 6 bits of the value in CV1, and the most significant
three bits in CV 13.
<p>In cases where a number of complex or contiguous CVs are used, there are a number of
alternative more concise methods of specifying in the <code>CV</code> variable parameter:</p>
<ul>
<li>The available methods (with example strings) are detailed under <a href=
"https://www.jmri.org/JavaDoc/doc/jmri/util/CvUtil.html#expandCvList(java.lang.String)"
target="_blank">expandCvList</a> on this <a href=
"https://www.jmri.org/JavaDoc/doc/jmri/util/CvUtil.html#expandCvList(java.lang.String)"
target="_blank">JavaDoc page</a>.
</li>
<li>For example, this <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/esu/v4projectInfoCVs.xml" target=
"_blank">decoder fragment file</a> has a <a href=
"/JavaDoc/doc/jmri/jmrit/symbolicprog/SplitTextVariableValue.html" target=
"_blank">splitTextVal</a> requiring 28 CVs.
</li>
<li>Other examples are found in this <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/esu/v4decoderInfoCVs.xml" target=
"_blank">decoder fragment file</a>.
</li>
<li>The following example reads the RailCom&reg; Production Date as per <a href=
"https://www.nmra.org/sites/default/files/s-9.3.2_2012_12_10.pdf">NMRA standard 9.3.2</a>
from 4 contiguous indexed CVs.
</li>
</ul>
<pre style="font-family: monospace;">
&lt;variable CV="0.255.269:4" readOnly="yes" item="PDate"&gt;
&lt;splitDateTimeVal display="dateOnly" base="2000-01-01T00:00:00"/&gt;
&lt;label&gt;Production Date&lt;/label&gt;
&lt;/variable&gt;
</pre>Note that if only one mask is specified, it will apply to all CVs. If fewer masks than
CVs are specified, the last mask will apply to the remaining CVs.
<h4 id="splitvalExample">splitVal example - "long" addresses over 2 CVs</h4>
<p>Some decoders, mostly accessory decoders, are using "long" addresses that are split over 2
CVs, contiguous or not.</p>
<p>CV1 and CV9 are standardized by NMRA for accessory decoders primary address, see <a href=
"https://www.nmra.org/sites/default/files/standards/sandrp/pdf/s-9.2.2_decoder_cvs_2012.07.pdf">
NMRA standard 9.2.2</a>.</p>
<p>Long addresses can be accessed via "splitVal" type, as in the following example:</p>
<pre style="font-family: monospace;">
&lt;variable CV="1,9" mask="XXVVVVVV XXXXXVVV" item="Short Address" default="1" minOut="1"&gt;
&lt;splitVal/&gt;
&lt;label&gt;Accessory Address&lt;/label&gt;
&lt;/variable&gt;
</pre>
<ul>
<li>CV1 is the Least Significant Byte (LSB) of the address and contains the six least
significant bits of the accessory decoder's address in bits 0-5.</li>
<li>CV9 is the (Most Significant Byte) MSB of the address and contains the three most
significant bits of the accessory decoder's address in bits 0-3.</li>
</ul>
<h4>decVal/splitVal/splitHexVal - optional "factor" and "offset" attributes</h4>
<p>For special purposes, decVal, splitVal and splitHexVal have two optional parameters, a "factor"
and an "offset":</p>
<ul>
<li>Value to put in CVs = ((value in text field) - Offset)/Factor</li>
<li>Value to put in text field = ((value in CVs) * Factor) + Offset</li>
</ul>
<pre style="font-family: monospace;">
&lt;splitVal factor="4" offset="-3"/&gt;
</pre>
<p>For usage examples, see the <a href=
"https://github.com/JMRI/JMRI/blob/master/xml/decoders/ESU_SwitchPilot.xml" target=
"_blank">xml/decoders/ESU_SwitchPilot.xml</a> file.</p>
<h3 id="conditional">Conditional Decoder Definitions</h3>
To reduce the number of decoder definition files needed, each file can contain definitions
for multiple decoder models. JMRI provides ways of adapting the definition to specific models
both when the file is being initially expanded for use, and later while the program is
working on the definition. These are particularly useful when using a common fragment file
that might be included by multiple decoder definition files (defining different-but-similar
families)
<h4 id="var_include">Include/Exclude During Variable Expansion</h4>
Whether a variable element is expanded and used can be made conditional on the decoder type
using "include" and "exclude" attributes on &lt;variables&gt;, &lt;variable&gt;,
&lt;enumChoice&gt; and &lt;enumChoiceGroup&gt; elements.
<p>A variable definition will not be expanded and used:</p>
<ul>
<li>If an exclude attribute is present, neither the decoder's product ID, model name, nor
family name is found in the exclude list.</li>
<li>If an include attribute is present, at least one of the decoder's product ID, model
name, or family name is found in the include list.</li>
</ul>
Both of these conditions must be true, and it's possible to use both include and exclude on
the same element, but it's more usual to just use one.
<p>Example:</p>
<pre style="font-family: monospace;">
&lt;variable label="My Variable" CV="72" include="ModelA,400"&gt;
&lt;decVal/&gt;
&lt;/variable&gt;
</pre>
<p>The variable above will only appear when expanding the decoder definition for ModelA or
product ID 400.<br>
Note there should be no spaces around the comma.</p>
<p>You can also put include and exclude attributes on individual choices in an
enumeration-type variable. This can be used to e.g. only include specific lighting options in
certain decoder families.</p>
<p>Attributes on a &lt;variables&gt; element act on all the &lt;variable&gt; elements within
it, along with any include or exclude attributes on those individual variables.</p>
<p>You can also use the include mechanism to specify the default value of a variable.</p>
<p>Note: &lt;defaultItem&gt; must be the first element inside the &lt;variable&gt; element body.</p>
<p>Example:</p>
<pre style="font-family: monospace;">
&lt;variable label="My Variable" CV="72" default="3"&gt;
&lt;defaultItem default="12" include="815"/&gt;
&lt;decVal/&gt;
&lt;/variable&gt;
</pre>
<p>This will set the default (initial) value of the CV to 12 if the "815" matches, and
otherwise use the default-default of 3. You can have as many &lt;defaultItem&gt; elements as needed;
the first one that matches is used.</p>
<p>Note: any &lt;defaultItem&gt; elements must come before other elements inside the &lt;variable&gt; element.</p>
<h4 id="pane_include">Include/Exclude During Pane Creation</h4>
Whether a pane (or part of a pane) is created can be made conditional on the decoder type
using "include" and "exclude" attributes on &lt;pane&gt; and &lt;group&gt; elements.
<p>A pane will not be created:</p>
<ul>
<li>If an exclude attribute is present, neither the decoders product ID, model name, nor
family name is found in the exclude list.</li>
<li>If an include attribute is present, at least one of the decoders product ID, model
name, nor family name is found in the include list.</li>
</ul>
Both of these conditions must be true, and it's possible to use both include and exclude on
the same element, but it's more usual to just use one.
<p>Example:</p>
<pre style="font-family: monospace;">
&lt;pane include="ModelA,400"&gt;
...
&lt;/pane&gt;
</pre>
<p>"My Pane" will be created only when expanding the decoder definition for ModelA or product
ID 400.</p>
<p>You can also create a &lt;group&gt; element with include and exclude attributes. Elements
within the &lt;group&gt; will be created only if the &lt;group&gt; conditions are met. This
can be used to e.g. display specific text labels only for certain decoder models.</p>
<p>Example:</p>
<pre style="font-family: monospace;">
&lt;group include="ModelA,400"&gt;
&lt;label&gt;
&lt;text&gt;These decoders are very old.&lt;/text&gt;
&lt;/label&gt;
&lt;label&gt;
&lt;text&gt;Some features are unavailable.&lt;/text&gt;
&lt;/label&gt;
&lt;/group&gt;
</pre>
<p>The text will be created only when expanding the decoder definition for ModelA or product
ID 400.</p>
<h4 id="prodidwarn">Warning Regarding Use of Product ID in Include/Exclude</h4>
Care must be exercised when attempting to match against product ID in include or exclude
attributes. The product ID is not matched against any value read from the decoder during
<a href="#id">identification</a> but against the productID attribute specified in the decoder
definition. This can particularly be a problem if the productID attribute has multiple
values. For example:
<pre style="font-family: monospace;">
&lt;decoder&gt;
&lt;family name="My Big Family" mfg="NMRA"&gt;
&lt;model model="My Model" productID="400,401" /&gt;
&lt;/model&gt;
&lt;/family&gt;
&hellip;
&lt;/decoder&gt;
&lt;pane label="My 400 Pane" include="400"&gt;
&hellip;
&lt;/pane&gt;
&lt;pane label="My 401 Pane" include="401"&gt;
&hellip;
&lt;/pane&gt;</pre>Both panes will always be created. If the definitions need to differ between
product IDs, you will need to create two models, as per <a href="#id">the first example under
Identification</a>.
<h4 id="qualify">Run-time Qualification of Variables</h4>
<h5>Qualifying Variables</h5>
A "qualifier" element on a variable element allows you to enable or disable the variable
depending on the current value of another variable. This can be useful if, for example, the
decoder has a "mode" CV that determines the meaning of other CVs.
<p>If a variable is qualified as inactive, it doesn't appear in any panes and is neither read
nor written to the decoder when you do "All" or "Changes only" read or write operations. The
value is saved to the roster and will be reloaded when the roster entry is reopened
later.</p>
<p>In the following example, a CV is interpreted as two different variables depending on
whether the decoder is set for short or long addressing.</p>
<pre style="font-family: monospace;">
&lt;variable label="Variable for Short Address" CV="11"&gt;
&lt;qualifier&gt;
&lt;variableref&gt;Address Format&lt;/variableref&gt;
&lt;relation&gt;eq&lt;/relation&gt;
&lt;value&gt;0&lt;/value&gt;
&lt;/qualifier&gt;
&lt;decVal/&gt;
&lt;/variable&gt;
&lt;variable label="Variable for Long Address" CV="11"&gt;
&lt;qualifier&gt;
&lt;variableref&gt;Address Format&lt;/variableref&gt;
&lt;relation&gt;eq&lt;/relation&gt;
&lt;value&gt;1&lt;/value&gt;
&lt;/qualifier&gt;
&lt;decVal/&gt;
&lt;/variable&gt;
</pre>Other available operators include "gt", "ge", "ne", "lt", "le" and "exists". The "exists"
operator checks for whether a variable is defined or not; a "1" value means that it is, and a "0"
means that it doesn't.
<p>If multiple qualifier elements are present, all must be true for the variable to be active
and displayed.</p>
<h5 id="panes">Qualifying Panes</h5>
A "qualifier" element on a pane element allows you to enable or disable the pane depending on
the current value of a variable.
<p>If a pane is qualified as inactive, its contents are no longer shown. This includes any
labels or other decorations on the pane, in addition to the variables it contains. Depending
on other options, the pane may either show as empty, or not show at all. The variables within
it are still active, though, and a "Read all sheets" or "Write all sheets" will still write
them. If you have overlapping variable definitions, consider carefully whether this is what
you want. You might need to qualify the individual overlapping variables.</p>
<p>The following example enables one of two panes depending on whether the decoder is
currently set for short or long addressing.</p>
<pre style="font-family: monospace;">
&lt;pane name="Short Only"&gt;
&lt;qualifier&gt;
&lt;variableref&gt;Address Format&lt;/variableref&gt;
&lt;relation&gt;eq&lt;/relation&gt;
&lt;value&gt;0&lt;/value&gt;
&lt;/qualifier&gt;
&lt;column&gt;&lt;row&gt;
&lt;label label="Short Only Pane"/&gt;
&lt;/row&gt;&lt;/column&gt;
&lt;/pane&gt;
&lt;pane name="Long Only"&gt;
&lt;qualifier&gt;
&lt;variableref&gt;Address Format&lt;/variableref&gt;
&lt;relation&gt;eq&lt;/relation&gt;
&lt;value&gt;1&lt;/value&gt;
&lt;/qualifier&gt;
&lt;column&gt;&lt;row&gt;
&lt;label label="Long Only Pane"/&gt;
&lt;/row&gt;&lt;/column&gt;
&lt;/pane&gt;
</pre>Other available operators include "gt", "ge", "ne", "lt" and "le".
<p>If multiple qualifier elements are present, all must be true for the pane to be active and
displayed.</p>
<h5 id="labels">Qualifying Elements on Panes</h5>
A "qualifier" element on a "label", "soundlabel", "row", "column", "grid" or "griditem"
element allows you to enable or disable the display of that element on a specific pane.
<p>The following example displays a warning label if a version-number variable has a too-low
value:</p>
<pre style="font-family: monospace;">
&lt;label label="Version number too low!"&gt;
&lt;qualifier&gt;
&lt;variableref&gt;Version Number&lt;/variableref&gt;
&lt;relation&gt;lt&lt;/relation&gt;
&lt;value&gt;3&lt;/value&gt;
&lt;/qualifier&gt;
&lt;/label&gt;
</pre>
<p>You can use the same qualifier for multiple elements by enclosing the elements in a
"group" element and adding the qualifier to the "group" element:</p>
<pre style="font-family: monospace;">
&lt;group&gt;
&lt;qualifier&gt;
&lt;variableref&gt;Version Number&lt;/variableref&gt;
&lt;relation&gt;lt&lt;/relation&gt;
&lt;value&gt;3&lt;/value&gt;
&lt;/qualifier&gt;
&lt;label label="Version number too low!"/&gt;
&lt;label label=" "/&gt;
&lt;label label="Please update."/&gt;
&lt;/group&gt;
</pre>
<p>Once you've read the Version Number (variable or CV) from the decoder, the label(s) will
display iff that version number is too low. Note that initially, before the values are read
from the decoder, this display will depend on the default value from the file, which might be
misleading to the user.</p>
<h3>Using XSL transformations</h3>
<p>It is possible to generate complex, repeated decoder XML parts using XSL stylesheets. For
more information, please see <a href="TransformDecoder.shtml">Use XSLT Transformation for
complex decoders</a>.</p>
<!--#include virtual="/help/en/parts/Footer.shtml" -->
</div>
<!-- closes #mainContent-->
</div>
<!-- closes #mBody-->
<script src="/js/help.js"></script>
</body>
</html>