**xmppBridge** parameters:
-| Name | Label | Description | Required | Default value |
-|----------|--------------------|-------------------------------------------|-----------|-----------------------|
-| username | Username | The XMPP username (left part of JID) | true | - |
-| domain | Domain | The XMPP domain name (right part of JID) | true | - |
-| password | Password | The XMPP user password | true | - |
-| host | Server Hostname/IP | The IP/Hostname of the XMPP server | false | as "domain" parameter |
-| port | XMPP server Port | The typical port is 5222 | false | 5222 |
+| Name | Label | Description | Required | Default value |
+|--------------|--------------------|--------------------------------------------------------------------|----------|-----------------------|
+| username | Username | The XMPP username (left part of JID) | true | - |
+| domain | Domain | The XMPP domain name (right part of JID) | true | - |
+| password | Password | The XMPP user password | true | - |
+| host | Server Hostname/IP | The IP/Hostname of the XMPP server | false | as "domain" parameter |
+| port | XMPP server Port | The typical port is 5222 | false | 5222 |
+| securityMode | Security Mode | Sets the TLS security mode: `required`, `ifpossible` or `disabled` | false | `required` |
## Channels
**publishTrigger** parameters:
-| Name | Label | Description | Required |
-|-----------|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
-| payload | Payload condition | An optional condition on the value | false |
-| separator | Separator character | The trigger channel payload usually only contains the received text. If you define a separator character, for example '#', the sender UID and received text will be in the trigger channel payload. For example: pavel@example.com#My Message Text | false |
+| Name | Label | Description | Required |
+|-----------|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
+| payload | Payload condition | An optional condition on the value | false |
+| separator | Separator character | The trigger channel payload usually only contains the received text. If you define a separator character, for example '#', the sender UID and received text will be in the trigger channel payload. For example: pavel@example.com#My Message Text | false |
## Example Rules
+++ /dev/null
-/**
- * Copyright (c) 2010-2024 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.xmppclient.internal;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.jivesoftware.smack.AbstractXMPPConnection;
-import org.jivesoftware.smack.ConnectionListener;
-import org.jivesoftware.smack.ReconnectionManager;
-import org.jivesoftware.smack.SmackException;
-import org.jivesoftware.smack.XMPPConnection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.chat2.Chat;
-import org.jivesoftware.smack.chat2.ChatManager;
-import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.tcp.XMPPTCPConnection;
-import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
-import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
-import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity;
-import org.jivesoftware.smackx.httpfileupload.HttpFileUploadManager;
-import org.jxmpp.jid.EntityBareJid;
-import org.jxmpp.jid.impl.JidCreate;
-import org.jxmpp.stringprep.XmppStringprepException;
-import org.openhab.binding.xmppclient.internal.handler.XMPPClientMessageSubscriber;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link XMPPClient} is lib for handling XMPP connection and messaging
- *
- * @author Pavel Gololobov - Initial contribution
- */
-public class XMPPClient implements IncomingChatMessageListener, ConnectionListener {
- private final Logger logger = LoggerFactory.getLogger(XMPPClient.class);
- private AbstractXMPPConnection connection;
- private ChatManager chatManager;
- private HttpFileUploadManager httpFileUploadManager;
- private Set<XMPPClientMessageSubscriber> subscribers = new HashSet<>();
-
- public void subscribe(XMPPClientMessageSubscriber channel) {
- logger.debug("Channel {} subscribed", channel.getName());
- subscribers.add(channel);
- }
-
- public void unsubscribe(XMPPClientMessageSubscriber channel) {
- logger.debug("Channel {} unsubscribed", channel.getName());
- subscribers.remove(channel);
- }
-
- public void connect(String host, Integer port, String login, String domain, String password)
- throws XMPPException, SmackException, IOException {
- disconnect();
- String serverHost = domain;
- if ((host != null) && !host.isEmpty()) {
- serverHost = host;
- }
-
- XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder() //
- .setHost(serverHost) //
- .setPort(port) //
- .setUsernameAndPassword(login, password) //
- .setXmppDomain(domain) //
- .build();
-
- connection = new XMPPTCPConnection(config);
- connection.addConnectionListener(this);
-
- ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(connection);
- reconnectionManager.enableAutomaticReconnection();
-
- Identity identity = new Identity("client", "openHAB", "bot");
- ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
- sdm.setIdentity(identity);
-
- try {
- connection.connect().login();
- } catch (InterruptedException ex) {
- }
-
- chatManager = ChatManager.getInstanceFor(connection);
- chatManager.addIncomingListener(this);
- httpFileUploadManager = HttpFileUploadManager.getInstanceFor(connection);
- }
-
- public void disconnect() {
- if (connection != null) {
- connection.disconnect();
- }
- }
-
- public void sendMessage(String to, String message) {
- if (connection == null) {
- logger.warn("XMPP connection is null");
- return;
- }
- if (chatManager == null) {
- logger.warn("XMPP chatManager is null");
- return;
- }
- try {
- EntityBareJid jid = JidCreate.entityBareFrom(to);
- Chat chat = chatManager.chatWith(jid);
- chat.send(message);
- } catch (XmppStringprepException | SmackException.NotConnectedException | InterruptedException e) {
- logger.info("XMPP message sending error", e);
- }
- }
-
- public void sendImageByHTTP(String to, String filename) {
- if (connection == null) {
- logger.warn("XMPP connection is null");
- return;
- }
- if (httpFileUploadManager == null) {
- logger.warn("XMPP httpFileUploadManager is null");
- return;
- }
- try {
- URL u = httpFileUploadManager.uploadFile(new File(filename));
- // Use Stanza oob
- this.sendMessage(to, u.toString());
- } catch (XMPPException.XMPPErrorException | SmackException | InterruptedException | IOException e) {
- logger.warn("XMPP HTTP image sending error", e);
- }
- }
-
- @Override
- public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
- logger.debug("XMPP {} says {}", from.asBareJid().toString(), message.getBody());
- for (XMPPClientMessageSubscriber subscriber : subscribers) {
- logger.debug("Push to subscriber {}", subscriber.getName());
- subscriber.processMessage(from.asBareJid().toString(), message.getBody());
- }
- }
-
- @Override
- public void connected(XMPPConnection connection) {
- logger.debug("Connected to XMPP server.");
- }
-
- @Override
- public void authenticated(XMPPConnection connection, boolean resumed) {
- logger.debug("Authenticated to XMPP server.");
- }
-
- @Override
- public void connectionClosed() {
- logger.debug("XMPP connection was closed.");
- }
-
- @Override
- public void connectionClosedOnError(Exception e) {
- logger.debug("Connection to XMPP server was lost.");
- if (connection != null) {
- connection.disconnect();
- try {
- connection.connect().login();
- } catch (SmackException | IOException | XMPPException | InterruptedException ex) {
- logger.info("XMPP connection error", ex);
- }
- }
- }
-}
*/
package org.openhab.binding.xmppclient.internal;
+import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
/**
*
* @author Pavel Gololobov - Initial contribution
*/
+@NonNullByDefault
public class XMPPClientBindingConstants {
private static final String BINDING_ID = "xmppclient";
import java.util.Set;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.xmppclient.internal.handler.XMPPClientHandler;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
*
* @author Pavel Gololobov - Initial contribution
*/
+@NonNullByDefault
@Component(configurationPid = "binding.xmppclient", service = ThingHandlerFactory.class)
public class XMPPClientHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set
}
@Override
- protected ThingHandler createHandler(Thing thing) {
+ protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(XMPPClientBindingConstants.BRIDGE_TYPE_XMPP)) {
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.xmppclient.internal.XMPPClient;
+import org.openhab.binding.xmppclient.internal.client.XMPPClient;
import org.openhab.binding.xmppclient.internal.handler.XMPPClientHandler;
import org.openhab.core.automation.annotation.ActionInput;
import org.openhab.core.automation.annotation.RuleAction;
@ThingActionsScope(name = "xmppclient")
@NonNullByDefault
public class XMPPActions implements ThingActions {
- private static final Logger logger = LoggerFactory.getLogger(XMPPActions.class);
+ private final Logger logger = LoggerFactory.getLogger(XMPPActions.class);
private @Nullable XMPPClientHandler handler;
@Override
}
XMPPClient connection = clientHandler.getXMPPClient();
- if (connection == null) {
- logger.warn("XMPP ThingHandler connection is null");
- return;
- }
- if ((to == null) || (text == null)) {
- logger.info("Skipping XMPP messaging to {} value {}", to, text);
+ if (to == null || text == null) {
+ logger.warn("Skipping XMPP messaging to {} value {}", to, text);
return;
}
connection.sendMessage(to, text);
}
XMPPClient connection = clientHandler.getXMPPClient();
- if (connection == null) {
- logger.warn("XMPP ThingHandler connection is null");
- return;
- }
- if ((to == null) || (filename == null)) {
+ if (to == null || filename == null) {
logger.warn("Skipping XMPP messaging to {} value {}", to, filename);
return;
}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.client;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.jivesoftware.smack.AbstractXMPPConnection;
+import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
+import org.jivesoftware.smack.ConnectionListener;
+import org.jivesoftware.smack.ReconnectionManager;
+import org.jivesoftware.smack.SmackException;
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.chat2.Chat;
+import org.jivesoftware.smack.chat2.ChatManager;
+import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.tcp.XMPPTCPConnection;
+import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
+import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
+import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity;
+import org.jivesoftware.smackx.httpfileupload.HttpFileUploadManager;
+import org.jxmpp.jid.EntityBareJid;
+import org.jxmpp.jid.impl.JidCreate;
+import org.jxmpp.stringprep.XmppStringprepException;
+import org.openhab.binding.xmppclient.internal.handler.XMPPClientMessageSubscriber;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link XMPPClient} is lib for handling XMPP connection and messaging
+ *
+ * @author Pavel Gololobov - Initial contribution
+ * @author Leo Siepel - Add reconnection logic
+ */
+@NonNullByDefault
+public class XMPPClient implements IncomingChatMessageListener, ConnectionListener {
+ private final Logger logger = LoggerFactory.getLogger(XMPPClient.class);
+ private @Nullable AbstractXMPPConnection connection;
+ private @Nullable ChatManager chatManager;
+ private @Nullable HttpFileUploadManager httpFileUploadManager;
+ private Set<XMPPClientMessageSubscriber> subscribers = new HashSet<>();
+ private final XMPPClientEventlistener eventListener;
+
+ public XMPPClient(XMPPClientEventlistener eventListener) {
+ this.eventListener = eventListener;
+ }
+
+ public void subscribe(XMPPClientMessageSubscriber channel) {
+ logger.debug("Channel {} subscribed", channel.getName());
+ subscribers.add(channel);
+ }
+
+ public void unsubscribe(XMPPClientMessageSubscriber channel) {
+ logger.debug("Channel {} unsubscribed", channel.getName());
+ subscribers.remove(channel);
+ }
+
+ public void connect(String host, Integer port, String login, String domain, String password,
+ SecurityMode securityMode) throws XMPPClientConfigException, XMPPClientException {
+ disconnect();
+ String serverHost = domain;
+ if (!host.isBlank()) {
+ serverHost = host;
+ }
+
+ XMPPTCPConnectionConfiguration config;
+ try {
+ config = XMPPTCPConnectionConfiguration.builder() //
+ .setHost(serverHost) //
+ .setPort(port) //
+ .setUsernameAndPassword(login, password) //
+ .setXmppDomain(domain) //
+ .setSecurityMode(securityMode)//
+ .build();
+ } catch (XmppStringprepException e) {
+ throw new XMPPClientConfigException(Objects.requireNonNullElse(e.getMessage(), "Unknown error message"));
+ }
+
+ AbstractXMPPConnection connectionLocal = new XMPPTCPConnection(config);
+ connection = connectionLocal;
+ connectionLocal.addConnectionListener(this);
+
+ ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(connectionLocal);
+ reconnectionManager.enableAutomaticReconnection();
+
+ Identity identity = new Identity("client", "openHAB", "bot");
+ ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
+ sdm.setIdentity(identity);
+
+ try {
+ connectionLocal.connect().login();
+ } catch (InterruptedException | XMPPException | SmackException | IOException e) {
+ throw new XMPPClientException(Objects.requireNonNullElse(e.getMessage(), "Unknown error message"),
+ e.getCause());
+ }
+
+ ChatManager chatManager = ChatManager.getInstanceFor(connection);
+ chatManager.addIncomingListener(this);
+ this.chatManager = chatManager;
+ httpFileUploadManager = HttpFileUploadManager.getInstanceFor(connection);
+ }
+
+ public void disconnect() {
+ AbstractXMPPConnection connection = this.connection;
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+
+ public void sendMessage(String to, String message) {
+ if (connection == null) {
+ eventListener.onErrorEvent("XMPP connection is null");
+ return;
+ }
+
+ ChatManager chatManager = this.chatManager;
+ if (chatManager == null) {
+ eventListener.onErrorEvent("XMPP chatManager is null");
+ return;
+ }
+ try {
+ EntityBareJid jid = JidCreate.entityBareFrom(to);
+ Chat chat = chatManager.chatWith(jid);
+ chat.send(message);
+ } catch (XmppStringprepException | SmackException.NotConnectedException | InterruptedException e) {
+ logger.warn("XMPP message sending error", e);
+ }
+ }
+
+ public void sendImageByHTTP(String to, String filename) {
+ if (connection == null) {
+ logger.warn("XMPP connection is null");
+ return;
+ }
+ HttpFileUploadManager httpFileUploadManagerLocal = httpFileUploadManager;
+ if (httpFileUploadManagerLocal == null) {
+ logger.warn("XMPP httpFileUploadManager is null");
+ return;
+ }
+ try {
+ URL u = httpFileUploadManagerLocal.uploadFile(new File(filename));
+ // Use Stanza oob
+ this.sendMessage(to, u.toString());
+ } catch (XMPPException.XMPPErrorException | SmackException | InterruptedException | IOException e) {
+ logger.warn("XMPP HTTP image sending error", e);
+ }
+ }
+
+ @Override
+ public void newIncomingMessage(@Nullable EntityBareJid from, @Nullable Message message, @Nullable Chat chat) {
+ if (from == null || message == null || chat == null) {
+ logger.debug("newIncomingMessage with atleast one null argument, should not happen");
+ return;
+ }
+
+ logger.debug("XMPP {} says {}", from.asBareJid().toString(), message.getBody());
+ for (XMPPClientMessageSubscriber subscriber : subscribers) {
+ logger.debug("Push to subscriber {}", subscriber.getName());
+ subscriber.processMessage(from.asBareJid().toString(), message.getBody());
+ }
+ }
+
+ @Override
+ public void connected(@Nullable XMPPConnection connection) {
+ logger.debug("Connected to XMPP server.");
+ eventListener.onAllOk();
+ }
+
+ @Override
+ public void authenticated(@Nullable XMPPConnection connection, boolean resumed) {
+ logger.debug("Authenticated to XMPP server.");
+ eventListener.onAllOk();
+ }
+
+ @Override
+ public void connectionClosed() {
+ logger.debug("XMPP connection was closed.");
+ eventListener.onErrorEvent("XMPP connection was closed.");
+ }
+
+ @Override
+ public void connectionClosedOnError(@Nullable Exception e) {
+ logger.debug("Connection to XMPP server was lost.");
+ eventListener.onErrorEvent("XMPP connection was closed.");
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.client;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * The {@link XMPPClientConfigException} represents a binding specific {@link Exception}.
+ *
+ * @author Leo Siepel - Initial contribution
+ */
+
+@NonNullByDefault
+public class XMPPClientConfigException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public XMPPClientConfigException(String message) {
+ super(message);
+ }
+
+ public XMPPClientConfigException(String message, @Nullable Throwable cause) {
+ super(message, cause);
+ }
+
+ public XMPPClientConfigException(@Nullable Throwable cause) {
+ super(cause);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.client;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link XMPPClientEventlistener} is an interface for handling XMPP connection events.
+ *
+ * @author Leo Siepel - Initial Contribution
+ */
+
+@NonNullByDefault
+public interface XMPPClientEventlistener {
+
+ void onErrorEvent(String errorMessage);
+
+ void onAllOk();
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.xmppclient.internal.client;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * The {@link XMPPClientException} represents a binding specific {@link Exception}.
+ *
+ * @author Leo Siepel - Initial contribution
+ */
+
+@NonNullByDefault
+public class XMPPClientException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public XMPPClientException(String message) {
+ super(message);
+ }
+
+ public XMPPClientException(String message, @Nullable Throwable cause) {
+ super(message, cause);
+ }
+
+ public XMPPClientException(@Nullable Throwable cause) {
+ super(cause);
+ }
+}
*/
package org.openhab.binding.xmppclient.internal.handler;
-import org.openhab.binding.xmppclient.internal.XMPPClient;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.xmppclient.internal.client.XMPPClient;
import org.openhab.core.thing.ChannelUID;
/**
*
* @author Pavel Gololobov - Initial contribution
*/
+@NonNullByDefault
public class PublishTriggerChannel implements XMPPClientMessageSubscriber {
private final XMPPClient connection;
private final PublishTriggerChannelConfig config;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
/**
* The {@link XMPPClientConfiguration} class contains fields mapping thing configuration parameters.
public String username = "";
public String password = "";
public String domain = "";
+ public String securityMode = SecurityMode.required.toString();
+
+ public boolean isValid() {
+ String host = this.host;
+ return !(host == null || host.isBlank());
+ }
}
*/
package org.openhab.binding.xmppclient.internal.handler;
-import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import org.jivesoftware.smack.SmackException;
-import org.jivesoftware.smack.XMPPException;
-import org.openhab.binding.xmppclient.internal.XMPPClient;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.openhab.binding.xmppclient.internal.action.XMPPActions;
+import org.openhab.binding.xmppclient.internal.client.XMPPClient;
+import org.openhab.binding.xmppclient.internal.client.XMPPClientConfigException;
+import org.openhab.binding.xmppclient.internal.client.XMPPClientEventlistener;
+import org.openhab.binding.xmppclient.internal.client.XMPPClientException;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
*
* @author Pavel Gololobov - Initial contribution
*/
-
-public class XMPPClientHandler extends BaseBridgeHandler {
+@NonNullByDefault
+public class XMPPClientHandler extends BaseBridgeHandler implements XMPPClientEventlistener {
private final Logger logger = LoggerFactory.getLogger(XMPPClientHandler.class);
private XMPPClient xmppClient;
- private XMPPClientConfiguration config;
private final Map<ChannelUID, PublishTriggerChannel> channelStateByChannelUID = new HashMap<>();
public XMPPClientHandler(Bridge thing) {
super(thing);
+ xmppClient = new XMPPClient(this);
}
public XMPPClient getXMPPClient() {
}
private void doConnect() {
- config = getConfigAs(XMPPClientConfiguration.class);
- xmppClient = new XMPPClient();
+ XMPPClientConfiguration config = getConfigAs(XMPPClientConfiguration.class);
+ if (!config.isValid()) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Please check configuration");
+ return;
+ }
+
try {
- xmppClient.connect(config.host, config.port, config.username, config.domain, config.password);
- } catch (SmackException | IOException | XMPPException e) {
- logger.info("XMPP connection error", e);
+ xmppClient.connect(Objects.requireNonNullElse(config.host, ""), config.port, config.username, config.domain,
+ config.password, SecurityMode.valueOf(config.securityMode));
+ updateStatus(ThingStatus.ONLINE);
+ } catch (XMPPClientConfigException e) {
+ logger.debug("XMPP connection error", e);
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+ return;
+ } catch (XMPPClientException e) {
+ logger.debug("XMPP connection error", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
return;
}
logger.info("XMPP added channel {} payload {}", channel.getUID().toString(), channelConfig.payload);
}
channelStateByChannelUID.values().forEach(c -> c.start());
+ }
+ @Override
+ public void onErrorEvent(String errorMessage) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, errorMessage);
+ }
+
+ @Override
+ public void onAllOk() {
updateStatus(ThingStatus.ONLINE);
}
}
*/
package org.openhab.binding.xmppclient.internal.handler;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
/**
* Subscriber interface
*
* @author Pavel Gololobov - Initial contribution
*/
+@NonNullByDefault
public interface XMPPClientMessageSubscriber {
void processMessage(String from, String payload);
<parameter name="port" type="integer">
<label>XMPP Server Port</label>
<description>The default port is 5222.</description>
+ <advanced>true</advanced>
+ </parameter>
+ <parameter name="securityMode" type="text" required="true">
+ <label>Security Mode</label>
+ <description>An enumeration for TLS security modes that are available when making a connection to the XMPP server.</description>
+ <limitToOptions>true</limitToOptions>
+ <options>
+ <option value="required">Required</option>
+ <option value="ifpossible">Optional</option>
+ <option value="disabled">Disabled</option>
+ </options>
+ <default>required</default>
+ <advanced>true</advanced>
</parameter>
</config-description>
</bridge-type>