added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.binding.xmppclient/.classpath
Normal file
32
bundles/org.openhab.binding.xmppclient/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.binding.xmppclient/.project
Normal file
23
bundles/org.openhab.binding.xmppclient/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.xmppclient</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
bundles/org.openhab.binding.xmppclient/NOTICE
Normal file
13
bundles/org.openhab.binding.xmppclient/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
87
bundles/org.openhab.binding.xmppclient/README.md
Normal file
87
bundles/org.openhab.binding.xmppclient/README.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# XMPPClient Binding
|
||||
|
||||
XMPPClient binding provides support for sending and receiving XMPP (Jabber) messages.
|
||||
|
||||
## Supported Things
|
||||
|
||||
xmppBridge - Basic XMPP (Jabber) client thing, that can send and receive messages.
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
Sample configurations:
|
||||
|
||||
```
|
||||
Bridge xmppclient:xmppBridge:xmpp "XMPP Client" [ username="openhab", domain="example.com", password="********" ] {
|
||||
Channels:
|
||||
Trigger String : xmpp_command [ separator="##" ]
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
Bridge xmppclient:xmppBridge:xmpp "XMPP Client" [ host="xmpp.example.com", port=7222, username="openhab", domain="example.com", password="********" ] {
|
||||
Channels:
|
||||
Trigger String : xmpp_command [ separator="##" ]
|
||||
}
|
||||
```
|
||||
|
||||
**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 |
|
||||
|
||||
## 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 |
|
||||
|
||||
## Example Rules
|
||||
|
||||
Send message:
|
||||
|
||||
```
|
||||
rule "Leak detected"
|
||||
when
|
||||
Item Xi_Leak changed
|
||||
then
|
||||
if(Xi_Leak.state == ON) {
|
||||
val actions = getActions("xmpp","xmppclient:xmppBridge:xmpp")
|
||||
actions.publishXMPP("pavel@example.com","Warning! Leak detected!")
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
Receive and process message:
|
||||
|
||||
```
|
||||
rule "Turn off all lights without separator"
|
||||
when
|
||||
Channel "xmppclient:xmppBridge:xmpp:xmpp_command" triggered
|
||||
then
|
||||
var actionName = receivedEvent.getEvent()
|
||||
if(actionName.toLowerCase() == "turn off lights") {
|
||||
Group_Light_Home_All.sendCommand(OFF)
|
||||
}
|
||||
end
|
||||
|
||||
rule "Turn off all lights with separator and reply"
|
||||
when
|
||||
Channel "xmppclient:xmppBridge:xmpp:xmpp_command" triggered
|
||||
then
|
||||
var actionName = receivedEvent.getEvent().split("##")
|
||||
if(actionName.get(1).toLowerCase() == "turn off lights") {
|
||||
Group_Light_Home_All.sendCommand(OFF)
|
||||
|
||||
val actions = getActions("xmpp","xmppclient:xmppBridge:xmpp")
|
||||
actions.publishXMPP(actionName.get(0),"All lights was turned off")
|
||||
}
|
||||
end
|
||||
```
|
||||
54
bundles/org.openhab.binding.xmppclient/pom.xml
Normal file
54
bundles/org.openhab.binding.xmppclient/pom.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.xmppclient</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: XMPPClient Binding</name>
|
||||
|
||||
<properties>
|
||||
<smack.version>4.3.3</smack.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack</groupId>
|
||||
<artifactId>smack-java7</artifactId>
|
||||
<version>${smack.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack</groupId>
|
||||
<artifactId>smack-extensions</artifactId>
|
||||
<version>${smack.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack</groupId>
|
||||
<artifactId>smack-im</artifactId>
|
||||
<version>${smack.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack</groupId>
|
||||
<artifactId>smack-tcp</artifactId>
|
||||
<version>${smack.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.minidns</groupId>
|
||||
<artifactId>minidns-core</artifactId>
|
||||
<version>0.3.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.xmppclient-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-xmppclient" description="XMPP Client Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
|
||||
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-extensions/4.3.3</bundle>
|
||||
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-im/4.3.3</bundle>
|
||||
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-tcp/4.3.3</bundle>
|
||||
<bundle dependency="true">mvn:org.jxmpp/jxmpp-core/0.6.3</bundle>
|
||||
<bundle dependency="true">mvn:org.jxmpp/jxmpp-jid/0.6.3</bundle>
|
||||
<bundle dependency="true">mvn:org.jxmpp/jxmpp-util-cache/0.6.3</bundle>
|
||||
<bundle dependency="true">mvn:org.minidns/minidns-core/0.3.3</bundle>
|
||||
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-core/4.3.3</bundle>
|
||||
<bundle dependency="true">mvn:org.igniterealtime.smack/smack-sasl-javax/4.3.3</bundle>
|
||||
<bundle dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xpp3/1.1.4c_7</bundle>
|
||||
<!-- FIXME: implicit dependencies required at runtime but not automatically installed, this is a workaround -->
|
||||
<bundle start-level="80">mvn:org.igniterealtime.smack/smack-resolver-javax/4.3.3</bundle>
|
||||
<bundle start-level="80">mvn:org.igniterealtime.smack/smack-java7/4.3.3</bundle>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.xmppclient/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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;
|
||||
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link XMPPClientBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Pavel Gololobov - Initial contribution
|
||||
*/
|
||||
public class XMPPClientBindingConstants {
|
||||
private static final String BINDING_ID = "xmppclient";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID BRIDGE_TYPE_XMPP = new ThingTypeUID(BINDING_ID, "xmppBridge");
|
||||
public static final String PUBLISH_TRIGGER_CHANNEL = "publishTrigger";
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.action;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This is the automation engine action handler service for the publishXMPP action.
|
||||
* <p>
|
||||
* <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
|
||||
* the test <i>actions instanceof XMPPActions</i> fails. This test can fail
|
||||
* due to an issue in openHAB core v2.5.0 where the {@link IXMPPActions} class
|
||||
* can be loaded by a different classloader than the <i>actions</i> instance.
|
||||
*
|
||||
* @author Laurent Garnier - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface IXMPPActions {
|
||||
|
||||
public void publishXMPP(@Nullable String to, @Nullable String text);
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.action;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.xmppclient.handler.XMPPClientHandler;
|
||||
import org.openhab.binding.xmppclient.internal.XMPPClient;
|
||||
import org.openhab.core.automation.annotation.ActionInput;
|
||||
import org.openhab.core.automation.annotation.RuleAction;
|
||||
import org.openhab.core.thing.binding.ThingActions;
|
||||
import org.openhab.core.thing.binding.ThingActionsScope;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This is the automation engine action handler service for the publishXMPP action.
|
||||
* <p>
|
||||
* <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
|
||||
* the test <i>actions instanceof XMPPActions</i> fails. This test can fail
|
||||
* due to an issue in openHAB core v2.5.0 where the {@link XMPPActions} class
|
||||
* can be loaded by a different classloader than the <i>actions</i> instance.
|
||||
*
|
||||
* @author Pavel Gololobov - Initial contribution
|
||||
*/
|
||||
@ThingActionsScope(name = "xmpp")
|
||||
@NonNullByDefault
|
||||
public class XMPPActions implements ThingActions, IXMPPActions {
|
||||
private static final Logger logger = LoggerFactory.getLogger(XMPPActions.class);
|
||||
private @Nullable XMPPClientHandler handler;
|
||||
|
||||
@Override
|
||||
public void setThingHandler(@Nullable ThingHandler handler) {
|
||||
this.handler = (XMPPClientHandler) handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingHandler getThingHandler() {
|
||||
return this.handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@RuleAction(label = "publishXMPP", description = "Publish to XMPP")
|
||||
public void publishXMPP(@ActionInput(name = "to", label = "To", description = "Send to") @Nullable String to,
|
||||
@ActionInput(name = "text", label = "Text", description = "Message text") @Nullable String text) {
|
||||
XMPPClientHandler clientHandler = handler;
|
||||
if (clientHandler == null) {
|
||||
logger.warn("XMPP ThingHandler is null");
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
connection.sendMessage(to, text);
|
||||
}
|
||||
|
||||
public static void publishXMPP(@Nullable ThingActions actions, @Nullable String to, @Nullable String text) {
|
||||
invokeMethodOf(actions).publishXMPP(to, text);
|
||||
}
|
||||
|
||||
private static IXMPPActions invokeMethodOf(@Nullable ThingActions actions) {
|
||||
if (actions == null) {
|
||||
throw new IllegalArgumentException("actions cannot be null");
|
||||
}
|
||||
if (actions.getClass().getName().equals(XMPPActions.class.getName())) {
|
||||
if (actions instanceof IXMPPActions) {
|
||||
return (IXMPPActions) actions;
|
||||
} else {
|
||||
return (IXMPPActions) Proxy.newProxyInstance(IXMPPActions.class.getClassLoader(),
|
||||
new Class[] { IXMPPActions.class }, (Object proxy, Method method, Object[] args) -> {
|
||||
Method m = actions.getClass().getDeclaredMethod(method.getName(),
|
||||
method.getParameterTypes());
|
||||
return m.invoke(actions, args);
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Actions is not an instance of XMPPActions");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.handler;
|
||||
|
||||
import org.openhab.binding.xmppclient.internal.XMPPClient;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
|
||||
/**
|
||||
* Subscribes to a chat and calls {@link AbstractBrokerHandler#triggerChannel(ChannelUID, String)} if a value has been
|
||||
* received.
|
||||
*
|
||||
* @author Pavel Gololobov - Initial contribution
|
||||
*/
|
||||
public class PublishTriggerChannel implements XMPPClientMessageSubscriber {
|
||||
private final XMPPClient connection;
|
||||
private final PublishTriggerChannelConfig config;
|
||||
private final ChannelUID uid;
|
||||
private final XMPPClientHandler handler;
|
||||
|
||||
PublishTriggerChannel(PublishTriggerChannelConfig config, ChannelUID uid, XMPPClient connection,
|
||||
XMPPClientHandler handler) {
|
||||
this.config = config;
|
||||
this.uid = uid;
|
||||
this.connection = connection;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
connection.subscribe(this);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
connection.unsubscribe(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(String from, String payload) {
|
||||
// Check condition if exists
|
||||
String expectedPayload = config.payload;
|
||||
if ((expectedPayload != null) && (!expectedPayload.isEmpty()) && !payload.equals(expectedPayload)) {
|
||||
return;
|
||||
}
|
||||
String eventValue = "";
|
||||
if (!config.separator.isEmpty()) {
|
||||
eventValue = from + config.separator + payload;
|
||||
} else {
|
||||
eventValue = payload;
|
||||
}
|
||||
handler.triggerChannel(uid, eventValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return uid.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Holds the configuration of a {@link PublishTriggerChannel}.
|
||||
*
|
||||
* @author Pavel Gololobov - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PublishTriggerChannelConfig {
|
||||
public @Nullable String payload;
|
||||
public String separator = "";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link XMPPClientConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Pavel Gololobov - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class XMPPClientConfiguration {
|
||||
public @Nullable String host;
|
||||
public Integer port = 5222;
|
||||
public String username = "";
|
||||
public String password = "";
|
||||
public String domain = "";
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.openhab.binding.xmppclient.action.XMPPActions;
|
||||
import org.openhab.binding.xmppclient.internal.XMPPClient;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link XMPPClientHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Pavel Gololobov - Initial contribution
|
||||
*/
|
||||
|
||||
public class XMPPClientHandler extends BaseBridgeHandler {
|
||||
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);
|
||||
}
|
||||
|
||||
public XMPPClient getXMPPClient() {
|
||||
return xmppClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return Collections.singleton(XMPPActions.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void triggerChannel(ChannelUID channelUID, String event) {
|
||||
super.triggerChannel(channelUID, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
// not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
scheduler.schedule(this::doConnect, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
channelStateByChannelUID.values().forEach(c -> c.stop());
|
||||
channelStateByChannelUID.clear();
|
||||
xmppClient.disconnect();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private void doConnect() {
|
||||
config = getConfigAs(XMPPClientConfiguration.class);
|
||||
xmppClient = new XMPPClient();
|
||||
try {
|
||||
xmppClient.connect(config.host, config.port, config.username, config.domain, config.password);
|
||||
} catch (SmackException | IOException | XMPPException e) {
|
||||
logger.info("XMPP connection error", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
for (Channel channel : thing.getChannels()) {
|
||||
final PublishTriggerChannelConfig channelConfig = channel.getConfiguration()
|
||||
.as(PublishTriggerChannelConfig.class);
|
||||
PublishTriggerChannel c = new PublishTriggerChannel(channelConfig, channel.getUID(), xmppClient, this);
|
||||
channelStateByChannelUID.put(channel.getUID(), c);
|
||||
logger.info("XMPP added channel {} payload {}", channel.getUID().toString(), channelConfig.payload);
|
||||
}
|
||||
channelStateByChannelUID.values().forEach(c -> c.start());
|
||||
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.handler;
|
||||
|
||||
/**
|
||||
* Subscriber interface
|
||||
*
|
||||
* @author Pavel Gololobov - Initial contribution
|
||||
*/
|
||||
public interface XMPPClientMessageSubscriber {
|
||||
public void processMessage(String from, String payload);
|
||||
|
||||
public String getName();
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
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.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
import org.openhab.binding.xmppclient.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 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.openhab.binding.xmppclient.XMPPClientBindingConstants;
|
||||
import org.openhab.binding.xmppclient.handler.XMPPClientHandler;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link XMPPClientHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Pavel Gololobov - Initial contribution
|
||||
*/
|
||||
@Component(configurationPid = "binding.xmppclient", service = ThingHandlerFactory.class)
|
||||
public class XMPPClientHandlerFactory extends BaseThingHandlerFactory {
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
|
||||
.singleton(XMPPClientBindingConstants.BRIDGE_TYPE_XMPP);
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (thingTypeUID.equals(XMPPClientBindingConstants.BRIDGE_TYPE_XMPP)) {
|
||||
return new XMPPClientHandler((Bridge) thing);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="xmppclient" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>XMPPClient Binding</name>
|
||||
<description>This is the binding for XMPP (Jabber) notifications.</description>
|
||||
<author>Pavel Gololobov</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="xmppclient"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<bridge-type id="xmppBridge" extensible="publishTrigger">
|
||||
<label>XMPP Client</label>
|
||||
<description>A connection to a XMPP server</description>
|
||||
<config-description>
|
||||
<parameter name="username" type="text" required="true">
|
||||
<label>Username</label>
|
||||
<description>The XMPP Username (the left side of JID, e.g. user for JID user@example.com)</description>
|
||||
</parameter>
|
||||
<parameter name="domain" type="text" required="true">
|
||||
<label>Domain</label>
|
||||
<description>The XMPP Domain (the right side of JID, e.g. example.com for JID user@example.com)</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="password" type="text" required="true">
|
||||
<label>Password</label>
|
||||
<description>The XMPP Password</description>
|
||||
<context>password</context>
|
||||
</parameter>
|
||||
<parameter name="host" type="text">
|
||||
<label>Server Hostname/IP</label>
|
||||
<description>The IP/Hostname of the XMPP server (if not specified, the Domain will be used)</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="port" type="integer">
|
||||
<label>XMPP Server Port</label>
|
||||
<description>The default port is 5222.</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
<channel-type id="publishTrigger">
|
||||
<kind>trigger</kind>
|
||||
<label>Publish Trigger</label>
|
||||
<description>This channel is triggered when a message is received on the configured XMPP account. The event payload
|
||||
will be the received text.</description>
|
||||
<event></event>
|
||||
<config-description>
|
||||
<parameter name="payload" type="text" required="false">
|
||||
<label>Payload Condition</label>
|
||||
<description>An optional condition on the value</description>
|
||||
</parameter>
|
||||
<parameter name="separator" type="text" required="false">
|
||||
<label>Separator Character</label>
|
||||
<description>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.</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user