[mqtt] Support birth and shutdown message (#12152)

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
jimtng 2022-02-03 21:42:54 +10:00 committed by GitHub
parent ca1e2b0e42
commit 80819ca503
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 10 deletions

View File

@ -38,10 +38,22 @@ Reconnect parameters are:
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:

View File

@ -13,6 +13,7 @@
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;
@ -44,6 +45,7 @@ import org.slf4j.LoggerFactory;
* 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 {
@ -60,12 +62,16 @@ public class BrokerHandler extends AbstractBrokerHandler implements PinnedCallba
// 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);
}
}
}
@ -114,6 +120,8 @@ public class BrokerHandler extends AbstractBrokerHandler implements PinnedCallba
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.",
@ -236,4 +244,15 @@ public class BrokerHandler extends AbstractBrokerHandler implements PinnedCallba
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);
}
}

View File

@ -36,4 +36,14 @@ public class BrokerHandlerConfig extends MqttBrokerConnectionConfig {
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;
}

View File

@ -94,6 +94,44 @@
<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>