725 lines
41 KiB
Plaintext
725 lines
41 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta name="generator" content="HTML Tidy for HTML5 for Apple macOS version 5.8.0">
|
|
<title>JMRI Hardware Support - MQTT</title>
|
|
<meta name="author" content="Bob Jacobsen">
|
|
<meta name="author" content="Jerry Grochow">
|
|
<meta name="keywords" content="JMRI MQTT">
|
|
<!--#include virtual="/help/en/parts/Style.shtml" -->
|
|
|
|
</head>
|
|
<body>
|
|
<!--#include virtual="/help/en/parts/Header.shtml" -->
|
|
|
|
<div id="mBody">
|
|
<!--#include virtual="../SidebarUp.shtml" -->
|
|
|
|
<div id="mainContent">
|
|
<h1>Hardware Support: MQTT</h1>
|
|
<img src="images/mqtt-logo.png" alt="MQTT logo" class="floatRight">
|
|
<p><a href="https://mqtt.org" target="_blank">MQTT</a> is a "client-server publish-subscribe"
|
|
protocol, meaning that JMRI connects to an MQTT server (called a "message broker") and subscribes
|
|
to receive messages on certain "topics." JMRI also publishes messages to the MQTT message broker
|
|
and any device (on or off the layout) subscribed to the published topic will receive a copy. This
|
|
approach allows JMRI users to use MQTT communication in developing any number of layout control and
|
|
automation scenarios. For example, you can use JMRI's MQTT capability to communicate with <a href=
|
|
"https://en.wikipedia.org/wiki/Internet_of_things" target="_blank">IOT devices</a> as well as
|
|
<a href="../arduino/index.shtml">arduinos</a> and other microcontrollers.</p>
|
|
|
|
<p>MQTT messages consist of two parts: <em>topic</em> and <em>contents</em>. JMRI provides three mechanisms for
|
|
creating and processing MQTT messages, the specifics of each are provided in sections below:
|
|
|
|
<ul>
|
|
<li><a href="#objects">MQTT-connected objects</a>: Certain JMRI objects can be defined as being
|
|
connected via MQTT. As of release 4.26, JMRI implements MQTT-connected turnouts, sensors, lights,
|
|
and signal masts. Reporters were added in release 5.3.2. Power and throttle control functions were
|
|
added in release 5.5.4. Other object types and functions may be added in the future based on user requests.</li>
|
|
|
|
<li><a href="#LNG">LogxiNG</a>: As of release 4.99.7, <a href="../../tools/logixng/LogixNG.shtml">LogixNG</a> has
|
|
the capability to publish and subscribe MQTT messages on any topic of your choosing.</li>
|
|
|
|
<li><a href="#scripts">Scripting</a>: <em>Advanced Usage</em>: For other objects and devices, you can
|
|
use a provided <a href="#scripts">script</a> or write your own using JMRI's MQTT Adapter
|
|
object and methods.</li>
|
|
</ul>
|
|
|
|
<p><a href=
|
|
"images/MQTTSchematic.jpg"><img src="images/MQTTSchematic.jpg" alt="MQTT schematic"></a></p>
|
|
|
|
<p id="top"><strong>Help Page Contents:</strong></p>
|
|
<div class="toc">
|
|
|
|
<ul>
|
|
<li><a href="#connecting">Getting Started with MQTT</a>
|
|
<ul><li><a href="#prefs">Additional MQTT Connection Preferences</a></li></ul>
|
|
</li>
|
|
|
|
<li><a href="#topics">MQTT Topics</a>
|
|
</li>
|
|
|
|
<li><a href="#contents">Message Contents</a>
|
|
</li>
|
|
|
|
<li><a href="#QoSRet">MQTT Parameters for Quality of Service and Retained Messages</a>
|
|
</li>
|
|
|
|
<li>
|
|
Using MQTT with...
|
|
<ul>
|
|
<li><a href="#objects">MQTT-connected Objects</a>
|
|
<ul>
|
|
<li>Available Objects</li>
|
|
<li><a href="#objnames">MQTT-connected Object Names</a></li>
|
|
<li>Topics for MQTT-connected Objects</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#powerandthrottle">Power and Throttle Control</a>
|
|
</li>
|
|
<li><a href="#LNG">LogixNG</a>
|
|
<ul>
|
|
<li>LogixNG Topics for MQTT</li>
|
|
<li>LogixNG MQTT Publish</li>
|
|
<li>LogixNG MQTT Subscribe</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#scripts">Scripts</a>
|
|
<ul>
|
|
<li>Publishing Messages</li>
|
|
<li>Example: Publishing Object Status</li>
|
|
<li>Subscribing to (Receiving) Messages</li>
|
|
<li>Changing Default Message Parsing</li>
|
|
<li>Changing Message Topics at Startup</li>
|
|
<li>Changing MQTT QoS and Retain</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="#testing">Testing</a>
|
|
</li>
|
|
</ul>
|
|
<p class="important">This document is up-to-date as of JMRI Release 5.5.7.</p>
|
|
</div>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h2 id="connecting">Getting Started with MQTT</h2>
|
|
|
|
<p>The first step in using MQTT communication with JMRI is to create a connection to an MQTT
|
|
message broker. This is done via the Connections pane in the <a href=
|
|
"../../../package/apps/TabbedPreferences.shtml">Preferences window.</a>
|
|
(<strong>Edit⇒ Preferences⇒Connections</strong>)</p>
|
|
|
|
<ul>
|
|
<li>Select "MQTT" as the <strong>System manufacturer</strong></li>
|
|
|
|
<li>Select "MQTT Connection" as the <strong>System Connection</strong>. [While there is no "MQTT
|
|
Simulator" as there are for other connection types in JMRI, this may be added in the future to allow
|
|
testing without direct attachment to an MQTT message broker; see <a href="#testing">Testing</a> for
|
|
simple ways to connect to a message broker.]</li>
|
|
|
|
<li>The <strong>IP Address/Host Name</strong> should be either the IP address or host name of an external
|
|
server, or "localhost" if you are running an MQTT message broker on the same machine as JMRI.<br>
|
|
<span class="since">Since 5.5.7</span>JMRI will use the Preferences <strong>Railroad Name</strong>
|
|
when connecting to the broker (<strong>Edit⇒Preferences⇒Railroad Name</strong>).
|
|
This is known as the "MQTT Client ID" and will make it easier to identify the JMRI connection in
|
|
the MQTT broker logs.</li>
|
|
|
|
<li>The default <strong>Connection Prefix</strong> for MQTT is "M". [<em>Advanced Usage</em>: this can
|
|
be changed when setting up the connection.]</li>
|
|
|
|
<li>The default <strong>Connection Name</strong> is "MQTT." Currently, JMRI can handle only one MQTT
|
|
connection at a time. [<em>Advanced Usage</em>: The ability to change the connection name will be
|
|
required at some point in the future when more than one MQTT Connection is allowed.]</li>
|
|
</ul>
|
|
|
|
<p>You can establish an MQTT Connection in JMRI in addition to having other connection types.</p>
|
|
|
|
<p><a href="#top"><em><small>[Go to top of page]</small></em></a>
|
|
</p>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h3 id="prefs">Additional MQTT Connection Preferences</h3>
|
|
|
|
<p>Many parameters related to MQTT communication can be seen and changed
|
|
by selecting "Additional Connection Settings" on the MQTT Connection page under
|
|
Preferences, as shown in the picture below.</p>
|
|
|
|
<p><a href="images/MQTTPrefs_default_rel5_5_6.jpg"><img
|
|
src="images/MQTTPrefs_default_rel5_5_6.jpg" alt="MQTT preferences rel 5.5.6" ></a></p>
|
|
|
|
<ul>
|
|
<li><strong>TCP/UDP Port</strong>: The MQTT Message Broker listens for traffic on a
|
|
particular port. The default is 1883. <em>Advanced Usage</em>: This can be changed to suit the
|
|
message broker instance you are using.</li>
|
|
|
|
<li><span class="since">Since 4.23.6</span><strong>MQTT User Name and Password</strong>: MQTT Message Brokers
|
|
can be initialized to require a user name and password. You can specify those here. See also below under
|
|
<a href="#testing">Testing</a> for further information about using a broker without a user name
|
|
and password.</li>
|
|
|
|
<li><strong>MQTT Channel</strong>: MQTT Channel is prefixed to the topic of any MQTT messages published or subscribed
|
|
by JMRI. Prior to JMRI release 5.1.2, MQTT Channel contained "/trains/" as a default.
|
|
<br><span class="since">Since 5.1.2</span> MQTT Channel now deaults to blank but you can change it to
|
|
anything you want.<br>
|
|
|
|
Note that current guidance from the MQTT community is not to have a leading slash in the MQTT Channel. A trailing
|
|
slash should be provided for non-blank strings for convenience in organizing topics.
|
|
<br>[Prior to JMRI Rel. 5.1.2, since the default of "/trains/" was for all users of JMRI, anyone keeping the default and using a public MQTT message
|
|
broker (such as htttp://test.mosquitto.org, <a href="#testing">see below</a>) will show their messages (and see messages
|
|
from) every other JMRI user anywhere in the world who is doing the same thing!] </li>
|
|
|
|
<li><strong>MQTT-connected object topics</strong>: MQTT-connected objects such as sensors, lights,
|
|
turnouts, and signal masts use a unique three-part topic (<a href="#topics">see below</a>). The fields
|
|
listed here comprise the middle part (MQTT Channel is the first part and the hardware name portion of the object's
|
|
system name is generally the third part).
|
|
|
|
<br><em>Advanced Usage</em>: While there are fields for specifying separate topics for publishing (the "send" field) and
|
|
subscribing (receiving back from the layout) for some objects, it is recommended that send and receive topics be set the
|
|
same except for advanced usage (typically involving custom programmed microcontrollers used on the layout).
|
|
|
|
<br><em>Advanced Usage</em>: If you want the object's system name suffix to be in the topic string at some place other
|
|
than at the end, you can use a placeholder of "{0}" within the string to put the object's
|
|
system name suffix at that place. This allows you to set up topics like
|
|
"track/turnout/{0}/state" so JMRI will generate "/trains/track/turnout/abc123/state" for
|
|
turnout "MTabc123".
|
|
|
|
<br><em>Advanced Usage</em>: You can also change these fields as part of JMRI start-up using a script as
|
|
described <a href="#scripts">below.</a>
|
|
</li>
|
|
|
|
<li><span class="since">Since 4.25.3</span><strong>Last Will</strong>: JMRI can specify its "last will" topic and
|
|
message when it connects to a broker. The broker stores the message and topic and sends it as a normal MQTT message
|
|
to clients who have subscribed to that topic if and when it finds that JMRI has disconnected in an abnormal manner.
|
|
Find more information
|
|
<a href="https://www.hivemq.com/blog/mqtt-essentials-part-9-last-will-and-testament/" target="_blank">
|
|
here</a> about Last Will and Testament.</li>
|
|
|
|
</ul>
|
|
|
|
<p>Two other parameters that control the way the MQTT Message Broker interacts with JMRI can be changed via script.
|
|
See <a href="#QoSRet">Changing Default MQTT Parameters: QoS and Retained Messages</a>.</p>
|
|
|
|
|
|
<p class="noted">Be sure to save the JMRI Preferences if you have changed anything (hit the
|
|
"Save" button on the Preferences pane) and restart JMRI to put the changes into
|
|
effect.</p>
|
|
|
|
<p><a href="#top"><em><small>[Go to top of page]</small></em></a>
|
|
</p>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h2 id="topics">MQTT Topics</h2>
|
|
|
|
<p>JMRI publishes and receives MQTT messages on specific "topics." An MQTT topic is the label
|
|
or headline for published messages. It is the label that other processes subscribe to to receive messages.
|
|
MQTT treats a topic as
|
|
a single string, although topics are typically organized with slashes to create multiple levels. JMRI, however,
|
|
forms an MQTT topic by concatenating two or three strings, each with or without slashes as desired, as is described
|
|
under the sections for each type of use (<a href="#objects">MQTT-connected objects</a>, <a href="#LNG">LogixNG</a>,
|
|
<a href="#scripts">scripts</a>). MQTT Channel (see above in <a href="#prefs">Preferences</a>) is always the
|
|
first (prefix) part of the topic sent to the MQTT Broker (but may be blank, as of JMRI relesae 5.1.2).</p>
|
|
|
|
<p>Topics used in Subscribe messages can optionally have a wild card character. The plus sign ("+") mateches any string
|
|
only in the level (between slashes) where it appears. The hash sign ("#") must appear at the end of a topic string
|
|
and will match to any string and any number of levels. See <a href="https://mosquitto.org/man/mqtt-7.html" target="_blank">
|
|
this mosquitto.org page</a> for more information.</p>
|
|
|
|
<p><span class="since">Since 5.1.2</span>Setting the MQTT Channel to blank means that the user has complete control over topic strings both for publish and
|
|
subscribe. This provides great flexibility, especially in communicating with devices that do not have much
|
|
flexibility to set their topic strings, such as some home automation devices.</p>
|
|
|
|
<p><a href=
|
|
"images/MQTTSchematic2.jpg"><img src="images/MQTTSchematic2.jpg" alt="MQTT schematic specific"></a></p>
|
|
|
|
<p>Any message topic, defined or custom, can be subscribed to and processed by a <a href="#LNG">LogixNG</a>
|
|
or a custom <a href="#scripts">script</a>. These messages
|
|
can further be used to trigger <a href="../../tools/Logix.shtml">Logix,</a> populate <a href=
|
|
"../../tools/Memories.shtml">Memories</a> and then display them on panels, or for whatever purposes
|
|
you find useful.</p>
|
|
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h2 id="contents">MQTT Message Contents</h2>
|
|
|
|
<p>For MQTT-connected objects, MQTT message contents to be published are prescribed and automatically created (see
|
|
following). For both LogixNG and scripts, MQTT message contents can be any arbitrary string you create. How that message
|
|
contents is interpreted is up to the processes that subscribe to the topic of the message. See the following sections for more details.</p>
|
|
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h2 id="QoSRet">MQTT Parameters for Quality of Service and Retained Messages</h2>
|
|
|
|
<p><a href="https://mosquitto.org/man/mqtt-7.html" target="_blank">MQTT Quality of Service</a> indicates
|
|
to the MQTT message broker how to handle message delivery and receipt. Allowable values are 0, 1, and 2.
|
|
JMRI publishes messages using QOS level 2, the most stringent level, to ensure that messages are received by
|
|
the broker (this can be changed by <a href="#scripts">script</a>). QoS is between the publisher and
|
|
the broker. While JMRI sets a QoS level 2, whoever is publishing messages you want JMRI to receive (via
|
|
subscription) needs to set its own level (which can be the same or different than the level JMRI sets).
|
|
</p>
|
|
|
|
<p>The <a href="https://www.hivemq.com/blog/mqtt-essentials-part-8-retained-messages/" target=
|
|
"_blank">Retained Messages</a> parameter indicates to the MQTT message broker whether to retain the current
|
|
message to be automatically published whenever a new subscriber to that topic appears. JMRI publishes messages
|
|
with the retain option on (this can be changed by <a href="#scripts">script</a>). Since JMRI subscribes to
|
|
the receive topics for the individual objects you have set up in JMRI, subscriptions are made when you load a
|
|
panel. Any retained messages will be received at that time. For example, JMRI subscribes to messages
|
|
from MQTT sensors (that is, devices managing sensors and publishing MQTT messages). The publisher of those messages
|
|
decides whether values are retained by the broker so JMRI will receive them when a panel is loaded or a new sensor
|
|
created. Turnouts and lights commands are generally published by JMRI so JMRI will not receive anything on
|
|
startup as it would not be subscribing to its own messages.
|
|
</p>
|
|
|
|
<p><a href="#top"><em><small>[Go to top of page]</small></em></a>
|
|
</p>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h2 id="objects">Using MQTT-connected Layout Objects</h2>
|
|
|
|
<h3>Available Objects</h3>
|
|
|
|
<p>JMRI's MQTT capabilities continue to evolve. Older versions of JMRI (4.12 and earlier) directly
|
|
support Turnouts only. Other objects have been added in later releases as indicated below.
|
|
Direct support for Signal Heads is not yet available. Any JMRI object can be updated via an MQTT
|
|
messages using <a href="#scripts">scripts.</a></p>
|
|
|
|
<p>Message "contents" for JMRI standard objects are typically single words that represent the state of
|
|
the object. Specifics are discussed following.
|
|
|
|
<em>Advanced Usage</em>: It is also possible to replace the standard message contents by using a <a href=
|
|
"#scripts">custom version of the message parser</a> (including using <a href=
|
|
"https://www.json.org/json-en.html" target="_blank">JSON messages</a>).</p>
|
|
|
|
|
|
<ul>
|
|
<li>
|
|
<strong>Turnouts</strong>: JMRI sends on the "Turnout send topic" if a user commands a
|
|
turnout change e.g. by clicking on a panel or table. Additionally, if a Turnout has been
|
|
created in either the Direct mode or Monitoring mode (see <a href=
|
|
"../../../package/jmri/jmrit/beantable/TurnoutTable.shtml#Turnout_Feedback">turnout
|
|
documentation</a>), JMRI expects to receive turnout state on the "Turnout receive
|
|
topic."
|
|
The message content to be published by turnouts is "CLOSED" and "THROWN". Turnouts in Direct or Monitoring
|
|
mode can also receive these as well as the messages "INCONSISTENT" and "UNKNOWN" (sets the Known State).
|
|
Receiving any other message will generate a Warning in the <a href="../../../package/apps/SystemConsole.shtml">
|
|
JMRI System Console</a> and will set the turnout Known state to "UNKNOWN."
|
|
</li>
|
|
|
|
<li>
|
|
<strong>Lights</strong><span class="since">Since JMRI 4.21.1</span>:
|
|
JMRI sends on the "Light send topic" if a user commands a
|
|
Light change e.g. by clicking on a panel or table. JMRI also acts on Light state messages sent
|
|
from the layout on the "Light receive topic."
|
|
The expected message content for lights is "OFF", "ON"
|
|
and "INTENSITY dddd" where ddd is a number between 0.00 and 1.00.
|
|
Receiving any other messages will result in a Warning in the <a href=
|
|
"../../../package/apps/SystemConsole.shtml">JMRI System Console.</a> and cause the Light
|
|
state to be set to "UNKNOWN."
|
|
</li>
|
|
|
|
<li>
|
|
<strong>Sensors</strong><span class="since">Since JMRI 4.21.1</span>:
|
|
JMRI expects to receive sensor state on the "Sensor receive
|
|
topic" (as specified on the Preferences page). JMRI sends state on the "Sensor send topic"
|
|
if a user changes sensor state e.g. by clicking on a panel or table.
|
|
The expected message content for sensors is
|
|
"ACTIVE" and "INACTIVE". Any other message will generate a Warning in the <a href=
|
|
"../../../package/apps/SystemConsole.shtml">JMRI System Console</a> but will not change the
|
|
Sensor state.
|
|
</li>
|
|
|
|
<li>
|
|
<strong>Reporters</strong><span class="since">Since JMRI 5.3.2</span>:
|
|
MQTT-connected Reporters expect to receive a message like "nnnn text",
|
|
where nnnn is the locomotive ID and the rest of the message is free form text.
|
|
The Reporter creates/updates an <a href="../../tools/IdTags.shtml">IdTag</a> with the locomotive ID as the tag ID
|
|
(e.g. ID1234) and puts the rest of the message in the "content" parameter. Reporters
|
|
do not publish any MQTT messages.
|
|
A Reporter can also receive an empty message which clears the current report but
|
|
doesn't update any IdTags.
|
|
<br>
|
|
<em>Advanced Usage</em>: <a href="#scripts">Scripts</a> can read from a JMRI reporter
|
|
and send the content asa MQTT message as needed.
|
|
</li>
|
|
|
|
<li>
|
|
<strong>Signal Heads</strong>: MQTT-connected Signal Heads are not yet implemented.
|
|
You can use e.g. the Three Turnout Signal Head style with MQTT turnouts as a
|
|
work around. <em>Advanced Usage</em>: You can also write a <a href="#scripts">script</a>
|
|
that sends the content of a virtual or other Signal Head to the layout.
|
|
</li>
|
|
|
|
<li>
|
|
<strong>Signal Masts</strong><span class="since">Since JMRI 4.26</span>:
|
|
You can define MQTT-connected Signal Masts which will send
|
|
their aspect when changed.
|
|
A JMRI MQTT Signal Mast will send the
|
|
aspect name, followed by the held status and the lit status. Examples are
|
|
"Approach Medium; Lit; Unheld" and "Clear; Unlit; Held". The available
|
|
aspect names are defined in the signal system definition being used.
|
|
If the mast receives information in the same format, it will update
|
|
the mast's state.
|
|
</li>
|
|
<li>
|
|
<strong>Throttles and Power Control</strong><span class="since">Since JMRI 5.5.4</span>:
|
|
While not "layout objects," JMRI can also generate and receive MQTT messages for these functions, as
|
|
described <a href="#powerandthrottle">below</a>.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>All other messages on these defined topics are ignored by the standard JMRI processing.</p>
|
|
|
|
|
|
<h3 id="objnames">MQTT-connected Object Names</h3>
|
|
|
|
<p>As with all objects within JMRI, MQTT-connected layout objects (turnouts, sensors,
|
|
lights, and signal masts) have a <a href="../../doc/Technical/Names.shtml">"system name"</a>
|
|
and may optionally have a "user name."
|
|
|
|
<p>If you create objects by "adding" them to their respective tables, first select "MQTT" from the pulldown.
|
|
Enter a string in the "Hardware address" field. As opposed to certain other JMRI connection types,
|
|
this string does not have to follow any particular model and can be any alphanumeric characters.
|
|
For example, MQTT-connected Turnouts can be specified with JMRI hardware addresses such as "abcd" or
|
|
"123" or ".X$42". JMRI will prefix that string with the MQTT Connection Prefix and Object Type,
|
|
creating System Names in this example of "MTabcd", "MT123", or "MT.X$42".</p>
|
|
|
|
<em>Advanced Usage</em>: System Names may also include one or more "/" (slash) characters, causing MQTT to
|
|
see this as defining another level in the full topic. For example, if sensor "abc" is attached to
|
|
microcontroller "Ard01", you could name it "Ard01/abc". This allows easy identification of which hardware
|
|
controls which sensors, turnouts, or other devices.
|
|
|
|
<h3>Topics for MQTT-connected objects</h3>
|
|
|
|
<p>For MQTT-connected objects, JMRI creates a topic string composed of three parts for communicating with
|
|
those objects:
|
|
|
|
<ol>
|
|
<li>MQTT Channel (may be blank as of JMRI Release 5.1.2) is prefixed to the...</li>
|
|
<li>MQTT topic for that object type as defined in the Connection Preferences
|
|
(<em>Advanced Usage</em>: may be different for publishing and subscribing),</li>
|
|
<li>followed by the hardware name portion of the object's system name (system name stripped of the connection
|
|
and object type characters).
|
|
<!-- Following line removed as confusing 2025-07-04 jerryg2003:
|
|
[<em>Advanced Usage</em>: the object's hardware name may be inserted in the middle of the object type topic if
|
|
so defined in Preferences, <a href="#prefs">as discussed above.</a>
|
|
-->
|
|
</li>
|
|
</ol>
|
|
|
|
<p>An example of MQTT-connected objects: Using the example entries in the JMRI Preferences Connection pane
|
|
shown in the picture below, JMRI would construct the MQTT topic to publish the status of a Turnout with
|
|
system name "MTabcd1" by concatenating:</p>
|
|
|
|
<ol>
|
|
<li>the MQTT channel: "trains/"</li>
|
|
|
|
<li>the object-type-specific "send" topic: "jSend/to/"</li>
|
|
|
|
<li>the object's system name suffix: "abcd1"</li>
|
|
</ol>
|
|
|
|
<p>yielding the complete MQTT message topic: "<em>trains/jSend/to/abcd1</em>".</p>
|
|
|
|
<p><em>Advanced Usage</em>: If the object's system name include a "/" (perhaps to separate a hardware designator),
|
|
say "MTArd01/abcd1", the topic would include that slash and become "<em>trains/jSend/to/Ard01/abcd1</em>"</p>
|
|
|
|
<p><em>Advanced Usage</em>: If you want the object's system name suffix to be placed in the topic string other
|
|
than at the end, you can use a placeholder of "{0}" within the preference string to put the object's
|
|
system name suffix at that place (see Preference pane diagram <a href="#prefs">above</a>). This allows you to set up topics like
|
|
"jSend/to/{0}/state" so JMRI will generate "<em>trains/jSend/to/abcd1/state</em>" for
|
|
turnout "MTabcd1" or "<em>trains/jSend/to/Ard01/abcd1/state</em>" for
|
|
turnout "MTArd01/abcd1".</p>
|
|
|
|
<p><a href="images/MQTTPrefs_example_rel5_5_6.jpg"><img src="images/MQTTPrefs_example_rel5_5_6.jpg" alt=
|
|
"MQTT preferences example"></a></p>
|
|
|
|
<p><a href="#top"><em><small>[Go to top of page]</small></em></a>
|
|
</p>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
<h2 id="powerandthrottle">Power and Throttle Control</h2>
|
|
|
|
<p>It is now possible to subscribe to and receive MQTT messages to turn track power on or off and to control engine throttles.
|
|
</p>
|
|
|
|
<h3>MQTT Power Control</h3>
|
|
<p><span class="since">Since JMRI 5.5.4</span>
|
|
JMRI publishes Track Power ON/OFF commands on the "Power send topic" and receives the track power status on the "Power receive
|
|
topic". These messages will always be sent if you set power via the
|
|
<a href="../../../package/jmri/jmrit/powerpanel/PowerPanelFrame.shtml">JMRI Power Control Window</a>.
|
|
</p>
|
|
<p>
|
|
If you select an MQTT connection as the default for Power Control, MQTT messages will be published when selecting Power
|
|
ON or OFF from the Power Control Window, the <a href="../../../package/jmri/jmrit/withrottle/UserInterface.shtml">
|
|
WiThrottle Server window</a>, or any throttle connected via the
|
|
WiThrottle Server, or any scripts that use "powermanager.setPower(jmri.PpwerManager)". [If multiple command stations types
|
|
are connecte to JMRI, it is always possible to turn their track power on or off via the Power Control Window.]
|
|
</p>
|
|
<p><a href="images/MQTT_Power_Control_rel554.png"><img src="images/MQTT_Power_Control_rel554.png" alt=
|
|
"MQTT Power Control Window"></a></p>
|
|
|
|
<h3>MQTT Throttle Control</h3>
|
|
<p><span class="since">Since 5.5.4</span>
|
|
JMRI supports controlling locomotives over MQTT. Throttles attached to the specified MQTT connection (either by
|
|
default or by using <strong>Tools⇒Throttles⇒Throttles for connections⇒[select from pulldown]</strong>)
|
|
will publish MQTT messages on the indicated topics. The protocol is controller agnostic, however the internal design
|
|
of JMRI imposes some compliance with DCC standards.
|
|
</p>
|
|
|
|
<p>Throttles will generate and process MQTT messages as follows:</p>
|
|
<ul>
|
|
<li><strong>Throttle</strong>: The speed setting as a 0-100 percentage value is sent on the
|
|
"Throttle send topic" and received on the "Throttle receive topic".</li>
|
|
<li><strong>Direction</strong>: The throttle direction is sent on the "Direction send topic" and
|
|
received on the "Direction receive topic". Direction values are "FORWARD" and "REVERSE", and "STOP"
|
|
for an emergency stop.</li>
|
|
<li><strong>Function</strong>: Function states are sent on the "Function send topic" and received
|
|
on the "Function receive topic". The placeholder "{1}" within each topic is substituted with
|
|
the number of the function.Function state values are "ON" and "OFF".</li>
|
|
<li><strong>Consist</strong>: MQTT supports Command Station Consists in JMRI using the standard
|
|
Consist Tool. All of the loco addresses that make up a consist are listed in the
|
|
"Consist send topic" when a throttle is controlling that consist address. It is up to the controller
|
|
to determine how it controls the individual locos in the consist.</li>
|
|
</ul>
|
|
|
|
<p>
|
|
In the topics listed above, the placeholder "{0}" in the topic name is replaced with the loco or consist address
|
|
that the throttle is controlling. When the throttle is Released, all of the above topics are removed from MQTT.
|
|
If a throttle is Dispatched, the topics are retained on MQTT - this allows for locos to be controlled from a script
|
|
but be able to be taken over and manually controlled as required (ie for shunting operations).
|
|
</p>
|
|
|
|
<p>
|
|
If you select an MQTT connection as the default for Throttle Control (by selecting the "Throttle" button on
|
|
<strong>Edit⇒ Preferences⇒Defaults</strong>), any Throttle opened with
|
|
<strong>Tools⇒Throttle⇒New Throttle</strong> from the main Panel window or using smartphone applications
|
|
such as <a href="../../../package/jmri/jmrit/withrottle/UserInterface.shtml">WiThrottle and EngineDriver</a>
|
|
will generate MQTT messages. You can always select a throttle for any installed connection using
|
|
<strong>Tools⇒Throttles⇒Throttles for connections⇒[select from pulldown]</strong>.
|
|
</p>
|
|
|
|
<p><a href="#top"><em><small>[Go to top of page]</small></em></a>
|
|
</p>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h2 id="LNG">Using MQTT via LogixNG</h2>
|
|
|
|
<p> <span class="since">Since 4.99.7</span> <a href="../../tools/logixng/LogixNG.shtml">LogixNG</a> provides a
|
|
significant upgrade to creating <a href="../../tools/Logix.shtml">Logix</a> procedures to perform a wide variety of
|
|
functions with JMRI. One of its features is to publish and subscribe to arbitrary MQTT topics and then perform
|
|
any of the other functions allowed in a LogixNG Conditional.</p>
|
|
|
|
<p><a href="../../tools/logixng/reference/chapter5.shtml#digital_action_mqtt">See Chapter 5 of the LogixNG Reference</a> for information on entering Publish and Subscribe expressions into LogixNG Conditionals.</p>
|
|
|
|
<h3>LogixNG MQTT Topics</h3>
|
|
|
|
<p>In a LogixNG conditional, any string defined by you as the "topic" is concatenated to the MQTT Channel to
|
|
form the MQTT topic that will be published or subscribed. If you specify "mytrains/someobject" as the topic,
|
|
JMRI will publish and subscribe on "<em>[MQTT Channel]mytrains/someobject</em>" using the MQTT Channel specified in
|
|
the MQTT Connection Preferences. Slashes can be inserted for convenience. JMRI does not automatically insert any slashes.</p>
|
|
|
|
|
|
<h3>LogixNG MQTT Publish</h3>
|
|
|
|
<p>An example of a simple LogixNG conditional that will publish an MQTT message whenever a sensor (Trigger2) is
|
|
changed is shown in <a href="images/MQTTLogixNGPublish.jpg"><img src="images/MQTTLogixNGPublish.jpg"
|
|
alt="LogixNG condition for publishing MQTT messages" class="floatRight">the picture to the right.</a>.
|
|
Using this LogixNG you can publish the sensor state
|
|
change using any text message of your choosing (in this example, the contents of JMRI memories MemoryData and
|
|
MemoryData2), for example, to a display or a sub-panel controlled via MQTT messages.
|
|
Furthermore, you could do that with any type of sensor, including internal and those that are connected to the
|
|
layout via other communication methods. [If the sensor Trigger2 is an MQTT-connected sensor, JMRI will have
|
|
already subscribed to state change messages from the layout. In that case, this LogixNG would additionally
|
|
publish whatever message you choose on the topic you specify.]</p>
|
|
|
|
<h3>LogixNG MQTT Subscribe</h3>
|
|
|
|
<p>In the picture below,
|
|
you can set up LogixNG conditionals to subscribe to any messages coming from any devices on the layout
|
|
(in this case with topic "test/" followed by anything else; "#" is the wild card character). Note that for Subscribe,
|
|
LogixNG requires you to specify the topic directly in the conditional expression (it cannot be, for example, in
|
|
a memory as in the case of Publish). JMRI will put the
|
|
topic and contents of the message into LogixNG local variables (Topic and Contents) and you can then use them
|
|
or, as in this example, move them into JMRI memories (TestDataRcvd and TextTopicRcvd) for further use.</p>
|
|
|
|
<a href="images/MQTTLogixNGSubscribe.jpg"><img src="images/MQTTLogixNGSubscribe.jpg"
|
|
alt="LogixNG condition for subscribing to MQTT messages"></a>
|
|
|
|
<p><a href="#top"><em><small>[Go to top of page]</small></em></a>
|
|
</p>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h2 id="scripts">Using MQTT via Scripting</h2>
|
|
|
|
<p>The JMRI MQTT capability is very general and scripts can be used to send and receive arbitrary
|
|
messages from any MQTT-aware device on or off the layout. In addition, scripts can be used to
|
|
change standard message processing and default parameters.</p>
|
|
|
|
<p>In a script, any string defined by you as the "topic" in a reference to an MQTT
|
|
Adapter object is concatenated to the MQTT Channel to form the MQTT topic that will be published or subscribed.
|
|
If you define "mytrains/someobject" as the topic, JMRI will publish and subscribe on
|
|
"<em>[MQTT Channel]mytrains/someobject</em>" using the MQTT Channel specified in
|
|
the MQTT Connection Preferences. Slashes can be inserted for convenience. JMRI does not automatically insert any slashes.</p>
|
|
|
|
<p>All the scripts discussed here can be found in <a href="../../../../../jython/MQTT/">the
|
|
JMRI distribution jython directory under "MQTT."</a> More information about scripting with
|
|
JMRI is provided under <a href="../../tools/scripting/index.shtml">Scripting</a> in the JMRI
|
|
Help and website. Custom scripts for MQTT will typically use the <a href=
|
|
"https://www.jmri.org/JavaDoc/doc/jmri/jmrix/mqtt/MqttAdapter.html">MQTT Adapter object and
|
|
methods.</a></p>
|
|
|
|
<h4>Publishing Messages</h4>
|
|
|
|
<p>The <a href="../../../../../jython/MQTT/SendMqttMessage.py">SendMqttMessage.py</a> is an
|
|
example of how to send any message on any topic (automatically prefixed with the JMRI MQTT
|
|
channel) for processing by other devices.</p>
|
|
|
|
<h4>Example: Publishing Object Status (Signal Head Appearance)</h4>
|
|
<span class="since">Since JMRI 4.99.9</span>
|
|
<p><a href="../../../../../jython/MQTT/MqttSignalHead.py">This script</a> provides an example of using
|
|
JMRI's MQTT "publish" method to publish signal head appearance changes </p>
|
|
|
|
<h4>Subscribing to (Receiving) Messages</h4>
|
|
|
|
<p>You can use the <a href=
|
|
"../../../../../jython/MQTT/ReceiveMqttMessage.py">ReceiveMqttMessage.py</a> script to
|
|
subscribe to any topic on the JMRI MQTT channel (both for JMRI objects and custom) to receive
|
|
message for further processing. Standard <a href=
|
|
"https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/" target=
|
|
"_blank">MQTT wildcards (# and +)</a> can be used (as of release 4.21.3).</p>
|
|
|
|
<h4 id="defaultParser">Changing the Default Message Parsing</h4>
|
|
|
|
<span class="since">Since JMRI 4.15.5</span>
|
|
<p><em>Advanced Usage</em>: You can use a script to install a new <a href=
|
|
"https://www.jmri.org/JavaDoc/doc/jmri/jmrix/mqtt/MqttContentParser.html">MqttContentParser</a>
|
|
object to code and decode the content of messages. You might want to use JSON format, or need
|
|
to adapt to specific messages from some already-existing device; you can create a custom
|
|
parser to do any of that. See the <a href=
|
|
"../../../../../jython/MQTT/SetMqttParser.py">SetMqttParser.py</a> sample script. For a Java
|
|
example, see the <a href=
|
|
"https://github.com/JMRI/JMRI/blob/master/java/src/jmri/jmrix/mqtt/MqttTurnout.java#L41"
|
|
target="_blank">inner class implementation in MqttTurnout</a>.</p>
|
|
|
|
<p>Note that you can call <code>setParser(...)</code> on the <a href=
|
|
"https://www.jmri.org/JavaDoc/doc/jmri/jmrix/mqtt/MqttTurnoutManager.html">jmri.jmrix.mqtt.MqttTurnoutManager</a>
|
|
or on an individual <a href=
|
|
"https://www.jmri.org/JavaDoc/doc/jmri/jmrix/mqtt/MqttTurnout.html">jmri.jmrix.mqtt.MqttTurnout</a>
|
|
object. If you call it on the MqttTurnoutManager, all <strong>later created</strong>
|
|
MqttTurnout objects will use the new parser; earlier-created ones will not be changed. This
|
|
means you should execute a script to change the parser before loading any panel files if you
|
|
want all MqttTurnouts to be modified.</p>
|
|
|
|
<h4>Changing the MQTT Message Topic at JMRI Startup</h4>
|
|
<span class="since">Since JMRI 4.15.5</span>
|
|
<p>The sample script <a href=
|
|
"../../../../../jython/MQTT/SetMqttPrefix.py">SetMqttPrefix.py</a> shows how to set MQTT-connected object
|
|
type specific topic components at JMRI startup. Note that any changes should be made at
|
|
startup time before creating any such objects, i.e. the script must be run before any
|
|
panel files are loaded. Changing the prefix only affects objects that are created after the
|
|
change.</p>
|
|
|
|
<h4>Changing MQTT QoS and Retain</h4>
|
|
<span class="since">Since JMRI 4.21.3</span>
|
|
<p>MQTT parameters <a href="#QoSRet">Quality of Service and Retained Message</a> used by JMRI can be reset
|
|
via scripting. Example script <a href="../../../../../jython/MQTT/SetMqttOptions.py">SetMqttOptions.py</a>
|
|
shows how both of these parameters can be changed .</p>
|
|
|
|
<p><a href="#top"><em><small>[Go to top of page]</small></em></a>
|
|
</p>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<h2 id="testing">Testing</h2>
|
|
<a href="http://test.mosquitto.org" target="_blank"><img src=
|
|
"https://mosquitto.org/stickers/mosquitto-mono.png" alt="Mosquitto logo" height="80" width=
|
|
"80" class="floatRight"></a>
|
|
<p>If you want to test using JMRI with the MQTT connection
|
|
type, you can use a publicly available (non-JMRI) test server or install and run a copy of an MQTT
|
|
Message Broker locally.</p>
|
|
|
|
<p>A popular message broker is provided by the
|
|
mosquito.org foundation. Enter "test.mosquitto.org" as the Host Name on the Preferences Connections
|
|
page to connect to this message broker (for more information, type
|
|
<a href="https://test.mosquitto.org" target="_blank">test.mosquitto.org</a> into a browser).</p>
|
|
|
|
|
|
<p>You can also install the <a href="https://mosquitto.org/download/" target=
|
|
"_blank">mosquitto broker and tools</a> on your own machine. After downloading the tools, enter one of
|
|
the following command lines from the directory where they now reside:</p>
|
|
|
|
<pre>
|
|
mosquitto -v
|
|
</pre>
|
|
If you are using version 2.0 of mosquitto or later, you will need to provide a "configuration file":
|
|
|
|
<pre>
|
|
mosquitto -c "[location of your config file]/mosquitto.conf"
|
|
</pre>
|
|
|
|
Include at least the following lines in mosquitto.conf:
|
|
|
|
<pre>
|
|
log_type all #Equivalent to setting -v (verbose mode)
|
|
listener 1883 #To ensure listening on the appropriate port
|
|
allow_anonymous true #Allows JMRI to subscribe without an ID or password
|
|
</pre>
|
|
|
|
Now enter "localhost" as the Host Name on the MQTT JMRI Connection Preferences page. You are now connected!
|
|
|
|
<p>To <em>subscribe and print</em> all JMRI messages as they are published to JMRI's MQTT Channel "trains/", enter
|
|
this from the directory where you have the mosquitto tools:
|
|
|
|
<pre>
|
|
mosquitto_sub -h test.mosquitto.org -v -t 'trains/#'
|
|
</pre>
|
|
|
|
<p>To <em>remove all retained messages</em>, add the parameter "--remove-retained".
|
|
|
|
<p>To <em>get a nicely formatted output</em>, add a format string like this following the "-F" parameter:
|
|
|
|
<pre>
|
|
mosquitto_sub" -i LocalMonitor -t "trains/# -F "%I %-38.38t %q %r %l %-25.25p"
|
|
</pre>
|
|
|
|
To <em>publish messages</em> for JMRI to subscribe to:
|
|
|
|
<pre>
|
|
mosquitto_pub -h test.mosquitto.org -t trains/track/turnout/123 -r -m "CLOSED"
|
|
mosquitto_pub -h test.mosquitto.org -t trains/track/turnout/123 -r -m "THROWN"
|
|
</pre>
|
|
These commands can be run on the same machine as JMRI, or from a separate machine.
|
|
|
|
|
|
<p>See the <a href="https://mosquitto.org/man/mosquitto-conf-5.html" target="_blank">mosquitto
|
|
documentation</a> for more information.</p>
|
|
|
|
<p>There are also MQTT tools available for <a href=
|
|
"https://www.google.com/search?q=apple+app+store+mqtt&oq=apple+app+store+mqtt" target=
|
|
"_blank">iOS devices</a> and <a href=
|
|
"https://play.google.com/store/search?q=mqtt&c=apps&authuser" target="_blank">Android
|
|
devices</a> that can be useful for monitoring, testing and operating your layout.</p>
|
|
|
|
<p><a href="#top"><em><small>[Go to top of page]</small></em></a>
|
|
</p>
|
|
|
|
<!-- *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= -->
|
|
|
|
<!--#include virtual="/help/en/parts/Footer.shtml" -->
|
|
</div>
|
|
<!-- closes #mainContent-->
|
|
</div>
|
|
<!-- closes #mBody-->
|
|
<script src="/js/help.js"></script>
|
|
</body>
|
|
</html>
|