An MQTT last will and testament can be configured:
-* __lwtMessage__: An optional last will and testament message. Defaults to empty.
-* __lwtTopic__: The last will topic. Defaults to empty and therefore disables the last will.
-* __lwtQos__: The optional qos of the last will. Defaults to 0.
-* __lwtRetain__: Retain last will message. Defaults to false.
+* __lwtMessage__: An optional last will and testament message. Defaults to empty.
+* __lwtTopic__: The last will topic. Defaults to empty and therefore disables the last will.
+* __lwtQos__: The optional qos of the last will. Defaults to 0.
+* __lwtRetain__: Retain last will message. Defaults to true.
+
+An MQTT message can be published upon a successful connection to the MQTT broker with these parameters:
+
+* __birthMessage__: An optional message to be published once the bridge established a connection to the MQTT broker. Defaults to empty.
+* __birthTopic__: The birth topic. Defaults to empty and therefore no birth message will be published.
+* __birthRetain__: Retain the birth message. Defaults to true.
+
+An MQTT message can be published just before disconnecting from the broker with these parameters:
+
+* __shutdownMessage__: An optional message to be published before the bridge disconnects from the MQTT broker. Defaults to empty.
+* __shutdownTopic__: The shutdown topic. Defaults to empty and therefore no shutdown message will be published.
+* __shutdownRetain__: Retain the shutdown message. Defaults to true.
For more security, the following optional parameters can be altered:
package org.openhab.binding.mqtt.handler;
import java.security.NoSuchAlgorithmException;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
* connection to the {@link MqttService}.
*
* @author David Graeff - Initial contribution
+ * @author Jimmy Tanagra - Add birth and shutdown message
*/
@NonNullByDefault
public class BrokerHandler extends AbstractBrokerHandler implements PinnedCallback {
// Store generated client ID if none was set by the user
final MqttBrokerConnection connection = this.connection;
String clientID = config.clientID;
- if (connection != null && state == MqttConnectionState.CONNECTED && (clientID == null || clientID.isBlank())) {
- clientID = connection.getClientId();
- config.clientID = clientID;
- Configuration editConfig = editConfiguration();
- editConfig.put("clientid", clientID);
- updateConfiguration(editConfig);
+ if (connection != null && state == MqttConnectionState.CONNECTED) {
+ if (clientID == null || clientID.isBlank()) {
+ clientID = connection.getClientId();
+ config.clientID = clientID;
+ Configuration editConfig = editConfiguration();
+ editConfig.put("clientid", clientID);
+ updateConfiguration(editConfig);
+ } else {
+ publish(config.birthTopic, config.birthMessage, config.birthRetain);
+ }
}
}
public void dispose() {
try {
if (connection != null) {
+ publish(config.shutdownTopic, config.shutdownMessage, config.shutdownRetain).get(1000,
+ TimeUnit.MILLISECONDS);
connection.stop().get(1000, TimeUnit.MILLISECONDS);
} else {
logger.warn("Trying to dispose handler {} but connection is already null. Most likely this is a bug.",
super.initialize();
}
+
+ /**
+ * Calls the @NonNull MqttBrokerConnection::publish() with @Nullable topic and message
+ */
+ private CompletableFuture<Boolean> publish(@Nullable String topic, @Nullable String message, boolean retain) {
+ if (topic == null || connection == null) {
+ return CompletableFuture.completedFuture(true);
+ }
+ String nonNullMessage = message != null ? message : "";
+ return connection.publish(topic, nonNullMessage.getBytes(), connection.getQos(), retain);
+ }
}
public String publickey = "";
public boolean enableDiscovery = true;
+
+ // Birth message parameters
+ public @Nullable String birthTopic;
+ public @Nullable String birthMessage;
+ public Boolean birthRetain = true;
+
+ // Shutdown message parameters
+ public @Nullable String shutdownTopic;
+ public @Nullable String shutdownMessage;
+ public Boolean shutdownRetain = true;
}
<advanced>true</advanced>
</parameter>
+ <parameter name="birthMessage" type="text">
+ <label>Birth Message</label>
+ <description>The message to send to the broker when a connection is established.</description>
+ <advanced>true</advanced>
+ </parameter>
+
+ <parameter name="birthTopic" type="text">
+ <label>Birth Topic</label>
+ <description>Defaults to empty and therefore disables the birth message.</description>
+ <advanced>true</advanced>
+ </parameter>
+
+ <parameter name="birthRetain" type="boolean">
+ <label>Birth Message Retain</label>
+ <description>True if the birth message should be retained (defaults to true)</description>
+ <default>true</default>
+ <advanced>true</advanced>
+ </parameter>
+
+ <parameter name="shutdownMessage" type="text">
+ <label>Shutdown Message</label>
+ <description>The message to send to the broker before the connection terminates.</description>
+ <advanced>true</advanced>
+ </parameter>
+
+ <parameter name="shutdownTopic" type="text">
+ <label>Shutdown Topic</label>
+ <description>Defaults to empty and therefore disables the shutdown message.</description>
+ <advanced>true</advanced>
+ </parameter>
+
+ <parameter name="shutdownRetain" type="boolean">
+ <label>Shutdown Message Retain</label>
+ <description>True if the shutdown message should be retained (defaults to true)</description>
+ <default>false</default>
+ <advanced>true</advanced>
+ </parameter>
+
<parameter name="username" type="text">
<label>Username</label>
<description>The MQTT username</description>