added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.binding.tellstick/.classpath
Normal file
32
bundles/org.openhab.binding.tellstick/.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.tellstick/.project
Normal file
23
bundles/org.openhab.binding.tellstick/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.tellstick</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>
|
||||
41
bundles/org.openhab.binding.tellstick/NOTICE
Normal file
41
bundles/org.openhab.binding.tellstick/NOTICE
Normal file
@@ -0,0 +1,41 @@
|
||||
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
|
||||
|
||||
== Third-party Content
|
||||
|
||||
async-http
|
||||
* License: Apache 2.0 License
|
||||
* Project: https://github.com/AsyncHttpClient/async-http-client
|
||||
* Source: https://github.com/AsyncHttpClient/async-http-client
|
||||
|
||||
javatellstick
|
||||
* License: BSD-2-Clause License
|
||||
* Project: https://github.com/peec/javatellstick
|
||||
* Source: https://github.com/jannegpriv/javatellstick
|
||||
|
||||
netty
|
||||
* License: Apache 2.0 License
|
||||
* Project: https://netty.io
|
||||
* Source: https://github.com/netty/netty
|
||||
|
||||
reactive-streams
|
||||
* License: CC0 1.0 License
|
||||
* Project: https://www.reactive-streams.org
|
||||
* Source: https://github.com/reactive-streams/reactive-streams-jvm
|
||||
|
||||
jna
|
||||
* License: Apache 2.0 License
|
||||
* Project: https://github.com/java-native-access/jna
|
||||
* Source: https://github.com/java-native-access/jna
|
||||
|
||||
208
bundles/org.openhab.binding.tellstick/README.md
Normal file
208
bundles/org.openhab.binding.tellstick/README.md
Normal file
@@ -0,0 +1,208 @@
|
||||
# Tellstick Binding
|
||||
|
||||
This is an openHAB binding for Tellstick devices produced by Telldus, a Swedish company based in Lund.
|
||||
|
||||
The original Tellstick focused on controlling 433 MHz devices like switches, dimmers and reading sensors from different brands.
|
||||
Many of the supported devices are cheaper and "low-end" and support have been made by reverse engineer the transmission protocols.
|
||||
All of these 433 MHz devices is one-way, so some versions of the Tellstick monitoring the air to keep the state of all devices.
|
||||
|
||||
The latest versions have also implemented Z-Wave as transmission protocol which open up for more robust transmission due two-ways communication.
|
||||
|
||||
<p align="center">
|
||||
<img src="doc/tellstick_duo.jpg" alt="Tellstick Duo with device" width="300px"/>
|
||||
</p>
|
||||
|
||||
## Supported Things
|
||||
|
||||
This binding supports the following thing types:
|
||||
|
||||
* *Dimmable Device* - Usually for controlling lamps. `dimmer`
|
||||
* *Switchable Device* - On/Off only could be lamps or other electronic equipment. `switch`
|
||||
* *Sensors* - Temperature- and humidity-sensors. `sensor`
|
||||
|
||||
Additionally the binding have two types of bridge things which correspond to available API types:
|
||||
|
||||
* *Telldus Core Bridge* - Oldest API, used by USB devices. `telldus-core`
|
||||
* *Telldus Live Bridge* - Telldus Cloud service, all devices with online access. `telldus-live`
|
||||
|
||||
|
||||
***Switchbased sensors workaround***
|
||||
|
||||
* Some 433MHz magnetic & PIR sensors, for example, magnetic door sensors, are detected as regular `switch` Things instead of type `contact`. There is technically no way of distinguish them apart from regulur `switch` Things. For using them as sensors only (not paired to a lamp) please consult the workaround in the channel section.
|
||||
|
||||
## Discovery
|
||||
|
||||
Devices which is added to *Telldus Core* and *Telldus Live* can be discovered by openHAB.
|
||||
|
||||
When you add this binding it will try to discover the *Telldus Core Bridge*.
|
||||
If it is installed correct its devices will show up.
|
||||
If you want to use the *Telldus Live* its bridge, *Telldus Live bridge* need to be added manually.
|
||||
|
||||
## Binding Configuration
|
||||
|
||||
The binding itself requires no configuration.
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
Only the bridges require manual configuration.
|
||||
It is preferable that devices and sensors are discovered automatically; let the discovery/inbox initially configure them.
|
||||
You can add them either with karaf: `inbox approve <thingId>` or by using the inbox of the Paper UI.
|
||||
|
||||
### Dimmers & switches
|
||||
|
||||
There is an option to override the resend count of the commands.
|
||||
Use the option `repeat` for that. Default resend count is 2.
|
||||
|
||||
### Bridges
|
||||
|
||||
Depending on your tellstick device type there is different ways of using this binding.
|
||||
The binding implements two different API:
|
||||
**1)** *Telldus Core* which is a local only interface supported by USB based device. <br>
|
||||
**2)** *Telldus Live* which is a REST based cloud service maintained by Telldus. <br>
|
||||
|
||||
> Not implemented yet but supported by some new devices, contributions are welcome. [API documention.](https://api.telldus.net/localapi/api.html) <br>
|
||||
> **3)** *Local Rest API* is a local API which would work similar to Telldus Live but local.
|
||||
|
||||
Depending on your Tellstick model, different bridge-types are available:
|
||||
|
||||
| Model | Telldus Core | Telldus Live | Local REST API | Verified working with openHAB |
|
||||
|-------------------------|:------------:|:------------:|:--------------:|:-----------------------------:|
|
||||
| Tellstick Basic | X | X | | X |
|
||||
| Tellstick Duo | X | X | | X |
|
||||
| Tellstick Net v.1 | | X | | |
|
||||
| Tellstick Net v.2 | | X | X | |
|
||||
| Tellstick ZNet Lite v.1 | | X | X | X |
|
||||
| Tellstick ZNet Lite v.2 | | X | X | |
|
||||
|
||||
#### Telldus Core Bridge
|
||||
|
||||
> To enable communication between openHAB and tellstick-core service (Telldus center) they must use same architecture, eg. 32-bit or 64-bit. The supplied version from Telldus is compiled against 32-bit architecture. Therefore, it is better to use 32-bit java for openHAB. To check which version of Java is currently in use, run: `java -d32 -version`
|
||||
>
|
||||
> *For changing architecture in Linux check out: `dpkg --add-architecture`*
|
||||
|
||||
The telldus-core bridge uses a library on the local computer which is a `.dll` file for Windows and a `.so` file for Linux. The default one is usually correct.
|
||||
|
||||
```
|
||||
Bridge tellstick:telldus-core:1 "Tellstick Duo" [resendInterval=200,libraryPath="C:/Program Files/Telldus/;C:/Program Files (x86)/Telldus/"]
|
||||
```
|
||||
|
||||
Optional:
|
||||
|
||||
- **libraryPath:** The path to tellduscore.dll/so semicolon seperated list of folders.
|
||||
- **resendInterval:** The interval between each transmission of command in ms, default 100ms.
|
||||
|
||||
#### Telldus Live Bridge
|
||||
|
||||
To configure Telldus Live you have request OAuth tokens from Telldus.
|
||||
Goto this page <https://api.telldus.com/keys/index> and request your keys and update the config.
|
||||
|
||||
```
|
||||
Bridge tellstick:telldus-live:2 "Tellstick ZWave" [publicKey="XXX", privateKey="YYYY", token= "ZZZZ", tokenSecret="UUUU"]
|
||||
```
|
||||
|
||||
Required:
|
||||
|
||||
- **privateKey:** Private key
|
||||
- **publicKey:** Public key
|
||||
- **token:** Token
|
||||
- **tokenSecret:** Token secret
|
||||
|
||||
Optional:
|
||||
|
||||
- **refreshInterval:** How often we should contact *Telldus Live* to check for updates (in ms)
|
||||
|
||||
## Channels
|
||||
|
||||
Actuators (dimmer/switch) support the following channels:
|
||||
|
||||
| Channel Type ID | Item Type | Description |
|
||||
|-----------------|-----------|---------------------------------------------------------------|
|
||||
| dimmer | Number | This channel indicates the current dim level |
|
||||
| state | Switch | This channel indicates whether a device is turned on or off. |
|
||||
| timestamp | DateTime | This channel reports the last time this device state changed. |
|
||||
|
||||
Sensors (sensor) support the following channels:
|
||||
|
||||
| Channel Type ID | Item Type | Description |
|
||||
|-----------------|---------------------|-------------------------------------------------------------|
|
||||
| humidity | Number:Dimensionless| This channel reports the current humidity in percentage. |
|
||||
| temperature | Number:Temperature | This channel reports the current temperature. |
|
||||
| timestamp | DateTime | This channel reports the last time this sensor was updates. |
|
||||
|
||||
PowerSensors ([powersensor]) support the following channels:
|
||||
|
||||
| Channel Type ID | Item Type | Description |
|
||||
|-----------------|------------------------|-------------------------------------------------------------|
|
||||
| watt | Number:Power | This channel reports the current watt. |
|
||||
| ampere | Number:ElectricCurrent | This channel reports the current ampere. |
|
||||
| timestamp | DateTime | This channel reports the last time this sensor was updates. |
|
||||
|
||||
WindSensors ([windsensor]) support the following channels:
|
||||
|
||||
| Channel Type ID | Item Type | Description |
|
||||
|-----------------|--------------|------------------------------|
|
||||
| windgust | Number:Speed | The current peak wind gust. |
|
||||
| winddirection | Number:Angle | The current wind direction. |
|
||||
| windaverage | Number:Speed | The current wind average. |
|
||||
|
||||
RainSensors ([rainsensor]) support the following channels:
|
||||
|
||||
| Channel Type ID | Item Type | Description |
|
||||
|-----------------|---------------|----------------------------|
|
||||
| rainrate | Number:Length | This current rate of rain. |
|
||||
| raintotal | Number:Length | The total rain. |
|
||||
|
||||
### Switchbased sensor workaround
|
||||
|
||||
All switchbased sensors are binary and the goal is to represent them as a `contact` item in openHAB. Eg. a door is open or closed and can't be altered by sending a radio signal.
|
||||
To achieve that we will create a proxy item which is updated by a rule.
|
||||
|
||||
First create another proxy item for every sensor:
|
||||
|
||||
```
|
||||
Switch front_door_sensor "Front door" <door> {channel="tellstick:switch:1:7:state"}
|
||||
Contact front_door_proxy "Front door" <door>
|
||||
```
|
||||
|
||||
Then create a rule which updates the proxy item:
|
||||
|
||||
```
|
||||
rule "proxy_front_door_on"
|
||||
when
|
||||
Item front_door_sensor changed to ON
|
||||
then
|
||||
front_door_proxy.postUpdate(OPEN);
|
||||
end
|
||||
|
||||
rule "proxy_front_door_off"
|
||||
when
|
||||
Item front_door_sensor changed to OFF
|
||||
then
|
||||
front_door_proxy.postUpdate(CLOSED);
|
||||
end
|
||||
```
|
||||
|
||||
## Full Example
|
||||
|
||||
### tellstick.things
|
||||
|
||||
```
|
||||
Bridge tellstick:telldus-core:1 "Tellstick Duo" [resendInterval=200] {
|
||||
dimmer BedroomCeilingLamp1 [protocol="arctech",model="selflearning-dimmer",name="BedroomCeilingLamp1",deviceId="8"]
|
||||
switch LivingTV [protocol="arctech",name="LivingTV",deviceId="5"]
|
||||
sensor OutsideSensor1 [protocol="fineoffset",model="temperaturehumidity",name="temperaturehumidity:125",deviceId="125_temperaturehumidity_fineoffset"]
|
||||
}
|
||||
Bridge tellstick:telldus-live:2 "Tellstick ZWave" [refreshInterval=10000, publicKey="XXXXXXXX", privateKey="YYYYYY", token= "ZZZZZZZZ", tokenSecret="UUUUUUUUUU"] {
|
||||
sensor OutsideSensor2 [protocol="fineoffset",model="temperaturehumidity",name="temperaturehumidity:120",deviceId="120_temperaturehumidity_fineoffset"]
|
||||
}
|
||||
```
|
||||
|
||||
### tellstick.items
|
||||
|
||||
```
|
||||
Number OutsideSensor1_Temperture <temperature> { channel="tellstick:sensor:tellstickgateway:OutsideSensor1:temperature"}
|
||||
Number OutsideSensor1_Humidity <humidity> { channel="tellstick:sensor:tellstickgateway:OutsideSensor1:humidity"}
|
||||
|
||||
Switch LivingTV_Power <screen> { channel="tellstick:switch:tellstickgateway:LivingTV:switch"}
|
||||
Dimmer BedroomCeilingLamp1_Brightness <lightbulb> { channel="tellstick:dimmer:tellstickgateway:BedroomCeilingLamp1:dimmer"}
|
||||
```
|
||||
BIN
bundles/org.openhab.binding.tellstick/doc/tellstick_duo.jpg
Normal file
BIN
bundles/org.openhab.binding.tellstick/doc/tellstick_duo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
116
bundles/org.openhab.binding.tellstick/pom.xml
Normal file
116
bundles/org.openhab.binding.tellstick/pom.xml
Normal file
@@ -0,0 +1,116 @@
|
||||
<?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.tellstick</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Tellstick Binding</name>
|
||||
|
||||
<properties>
|
||||
<bnd.importpackage>!com.luckycatlabs.*,!com.jcraft.jzlib.*,!org.apache.commons.cli.*,!org.eclipse.swt.*</bnd.importpackage>
|
||||
<dep.noembedding>netty-transport-native-unix-common,netty-common,netty-transport,netty-transport-native-epoll,netty-buffer,netty-resolver,netty-codec,netty-codec-http,netty-handler</dep.noembedding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- JNA -->
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<version>4.5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tellstick</groupId>
|
||||
<artifactId>javatellstick</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.asynchttpclient</groupId>
|
||||
<artifactId>async-http-client</artifactId>
|
||||
<version>2.0.19</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.asynchttpclient</groupId>
|
||||
<artifactId>async-http-client-netty-utils</artifactId>
|
||||
<version>2.0.19</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.netty</groupId>
|
||||
<artifactId>netty-reactive-streams</artifactId>
|
||||
<version>2.0.4</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-unix-common</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec-http</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-common</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-handler</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-resolver</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-buffer</artifactId>
|
||||
<version>4.1.42.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.reactivestreams</groupId>
|
||||
<artifactId>reactive-streams</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.tellstick-${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-tellstick" description="Tellstick Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<feature>openhab-transport-serial</feature>
|
||||
<feature dependency="true">openhab.tp-netty</feature>
|
||||
<feature dependency="true">openhab.tp-jaxb</feature>
|
||||
<bundle dependency="true">mvn:net.java.dev.jna/jna/4.5.2</bundle>
|
||||
<bundle dependency="true">mvn:net.java.dev.jna/jna-platform/4.5.2</bundle>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.tellstick/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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.tellstick.internal;
|
||||
|
||||
import org.tellstick.device.TellstickException;
|
||||
|
||||
/**
|
||||
* {@link TelldusBindingException} is used when there is exception communicating with Telldus Live.
|
||||
* This exception extends the Telldus Core exception.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TelldusBindingException extends TellstickException {
|
||||
|
||||
private static final long serialVersionUID = 30671795474333158L;
|
||||
|
||||
private String msg;
|
||||
|
||||
public TelldusBindingException(String message) {
|
||||
super(null, 0);
|
||||
this.msg = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* 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.tellstick.internal;
|
||||
|
||||
import static org.openhab.core.library.unit.MetricPrefix.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.measure.Unit;
|
||||
import javax.measure.quantity.Angle;
|
||||
import javax.measure.quantity.Dimensionless;
|
||||
import javax.measure.quantity.ElectricCurrent;
|
||||
import javax.measure.quantity.Illuminance;
|
||||
import javax.measure.quantity.Length;
|
||||
import javax.measure.quantity.Power;
|
||||
import javax.measure.quantity.Pressure;
|
||||
import javax.measure.quantity.Speed;
|
||||
import javax.measure.quantity.Temperature;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.SmartHomeUnits;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link TellstickBinding} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author jarlebh - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class TellstickBindingConstants {
|
||||
|
||||
public static final String BINDING_ID = "tellstick";
|
||||
|
||||
public static final Unit<Dimensionless> HUMIDITY_UNIT = SmartHomeUnits.PERCENT;
|
||||
public static final Unit<Temperature> TEMPERATURE_UNIT = SIUnits.CELSIUS;
|
||||
public static final Unit<Pressure> PRESSURE_UNIT = HECTO(SIUnits.PASCAL);
|
||||
public static final Unit<Speed> WIND_SPEED_UNIT_MS = SmartHomeUnits.METRE_PER_SECOND;
|
||||
public static final Unit<Angle> WIND_DIRECTION_UNIT = SmartHomeUnits.DEGREE_ANGLE;
|
||||
public static final Unit<Length> RAIN_UNIT = MILLI(SIUnits.METRE);
|
||||
public static final Unit<Illuminance> LUX_UNIT = SmartHomeUnits.LUX;
|
||||
public static final Unit<ElectricCurrent> ELECTRIC_UNIT = SmartHomeUnits.AMPERE;
|
||||
public static final Unit<Power> POWER_UNIT = KILO(SmartHomeUnits.WATT);
|
||||
|
||||
public static final String CONFIGPATH_ID = "location";
|
||||
public static final String DEVICE_ID = "deviceId";
|
||||
public static final String DEVICE_PROTOCOL = "protocol";
|
||||
public static final String DEVICE_MODEL = "model";
|
||||
public static final String DEVICE_NAME = "name";
|
||||
public static final String DEVICE_RESEND_COUNT = "repeat";
|
||||
public static final String DEVICE_ISDIMMER = "dimmer";
|
||||
public static final String BRIDGE_TELLDUS_CORE = "telldus-core";
|
||||
public static final String BRIDGE_TELLDUS_LIVE = "telldus-live";
|
||||
public static final String DEVICE_SENSOR = "sensor";
|
||||
public static final String DEVICE_WINDSENSOR = "windsensor";
|
||||
public static final String DEVICE_RAINSENSOR = "rainsensor";
|
||||
public static final String DEVICE_POWERSENSOR = "powersensor";
|
||||
public static final String DEVICE_DIMMER = "dimmer";
|
||||
public static final String DEVICE_SWITCH = "switch";
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID DIMMER_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_DIMMER);
|
||||
public static final ThingTypeUID SWITCH_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_SWITCH);
|
||||
public static final ThingTypeUID SENSOR_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_SENSOR);
|
||||
public static final ThingTypeUID RAINSENSOR_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_RAINSENSOR);
|
||||
public static final ThingTypeUID POWERSENSOR_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_POWERSENSOR);
|
||||
public static final ThingTypeUID WINDSENSOR_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_WINDSENSOR);
|
||||
|
||||
public static final ThingTypeUID TELLDUSBRIDGE_THING_TYPE = new ThingTypeUID(BINDING_ID, BRIDGE_TELLDUS_CORE);
|
||||
public static final ThingTypeUID TELLDUSCOREBRIDGE_THING_TYPE = new ThingTypeUID(BINDING_ID, BRIDGE_TELLDUS_CORE);
|
||||
public static final ThingTypeUID TELLDUSLIVEBRIDGE_THING_TYPE = new ThingTypeUID(BINDING_ID, BRIDGE_TELLDUS_LIVE);
|
||||
// List of all Channel ids
|
||||
public static final String CHANNEL_DIMMER = "dimmer";
|
||||
public static final String CHANNEL_STATE = "state";
|
||||
public static final String CHANNEL_HUMIDITY = "humidity";
|
||||
public static final String CHANNEL_TIMESTAMP = "timestamp";
|
||||
public static final String CHANNEL_TEMPERATURE = "temperature";
|
||||
public static final String CHANNEL_RAINTOTAL = "raintotal";
|
||||
public static final String CHANNEL_RAINRATE = "rainrate";
|
||||
public static final String CHANNEL_WINDAVERAGE = "windaverage";
|
||||
public static final String CHANNEL_WINDDIRECTION = "winddirection";
|
||||
public static final String CHANNEL_WINDGUST = "windgust";
|
||||
public static final String CHANNEL_WATT = "watt";
|
||||
public static final String CHANNEL_AMPERE = "ampere";
|
||||
public static final String CHANNEL_LUX = "lux";
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_BRIDGE_THING_TYPES_UIDS = Collections.unmodifiableSet(
|
||||
Stream.of(TELLDUSCOREBRIDGE_THING_TYPE, TELLDUSLIVEBRIDGE_THING_TYPE).collect(Collectors.toSet()));
|
||||
public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES_UIDS = Collections
|
||||
.unmodifiableSet(Stream.of(DIMMER_THING_TYPE, SWITCH_THING_TYPE, SENSOR_THING_TYPE, RAINSENSOR_THING_TYPE,
|
||||
WINDSENSOR_THING_TYPE, POWERSENSOR_THING_TYPE).collect(Collectors.toSet()));
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream
|
||||
.of(DIMMER_THING_TYPE, SWITCH_THING_TYPE, SENSOR_THING_TYPE, RAINSENSOR_THING_TYPE, WINDSENSOR_THING_TYPE,
|
||||
POWERSENSOR_THING_TYPE, TELLDUSCOREBRIDGE_THING_TYPE, TELLDUSLIVEBRIDGE_THING_TYPE)
|
||||
.collect(Collectors.toSet()));
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 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.tellstick.internal;
|
||||
|
||||
import static org.openhab.binding.tellstick.internal.TellstickBindingConstants.*;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.openhab.binding.tellstick.internal.core.TelldusCoreBridgeHandler;
|
||||
import org.openhab.binding.tellstick.internal.discovery.TellstickDiscoveryService;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusBridgeHandler;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusDevicesHandler;
|
||||
import org.openhab.binding.tellstick.internal.live.TelldusLiveBridgeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
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;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link TellstickHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.tellstick")
|
||||
public class TellstickHandlerFactory extends BaseThingHandlerFactory {
|
||||
private final Logger logger = LoggerFactory.getLogger(TellstickHandlerFactory.class);
|
||||
private TellstickDiscoveryService discoveryService = null;
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
private void registerDeviceDiscoveryService(TelldusBridgeHandler tellstickBridgeHandler) {
|
||||
if (discoveryService == null) {
|
||||
discoveryService = new TellstickDiscoveryService(tellstickBridgeHandler);
|
||||
discoveryService.activate();
|
||||
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>());
|
||||
} else {
|
||||
discoveryService.addBridgeHandler(tellstickBridgeHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThingHandler createHandler(Thing thing) {
|
||||
if (thing.getThingTypeUID().equals(TELLDUSCOREBRIDGE_THING_TYPE)) {
|
||||
TelldusCoreBridgeHandler handler = new TelldusCoreBridgeHandler((Bridge) thing);
|
||||
registerDeviceDiscoveryService(handler);
|
||||
return handler;
|
||||
} else if (thing.getThingTypeUID().equals(TELLDUSLIVEBRIDGE_THING_TYPE)) {
|
||||
TelldusLiveBridgeHandler handler = new TelldusLiveBridgeHandler((Bridge) thing);
|
||||
registerDeviceDiscoveryService(handler);
|
||||
return handler;
|
||||
} else if (supportsThingType(thing.getThingTypeUID())) {
|
||||
return new TelldusDevicesHandler(thing);
|
||||
} else {
|
||||
logger.debug("ThingHandler not found for {}", thing.getThingTypeUID());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.tellstick.internal;
|
||||
|
||||
/**
|
||||
* Runtime exception in tellstick binding.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TellstickRuntimeException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -1644730263645760297L;
|
||||
|
||||
public TellstickRuntimeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -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.tellstick.internal.conf;
|
||||
|
||||
/**
|
||||
* Configuration class for {@link TellstickBridge} bridge used to connect to the
|
||||
* Tellus Live service.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TelldusLiveConfiguration {
|
||||
public String publicKey;
|
||||
public String privateKey;
|
||||
public String token;
|
||||
public String tokenSecret;
|
||||
public long refreshInterval;
|
||||
}
|
||||
@@ -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.tellstick.internal.conf;
|
||||
|
||||
/**
|
||||
* Configuration class for {@link TellstickBridge} bridge used to connect to the
|
||||
* Telldus Core service on the local machine.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TellstickBridgeConfiguration {
|
||||
public int resendInterval;
|
||||
public String libraryPath;
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
* 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.tellstick.internal.core;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.openhab.binding.tellstick.internal.conf.TellstickBridgeConfiguration;
|
||||
import org.openhab.binding.tellstick.internal.handler.DeviceStatusListener;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusBridgeHandler;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusDeviceController;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusDevicesHandler;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
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.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tellstick.JNA;
|
||||
import org.tellstick.device.SupportedMethodsException;
|
||||
import org.tellstick.device.TellstickDevice;
|
||||
import org.tellstick.device.TellstickDeviceEvent;
|
||||
import org.tellstick.device.TellstickEventHandler;
|
||||
import org.tellstick.device.TellstickSensor;
|
||||
import org.tellstick.device.TellstickSensorEvent;
|
||||
import org.tellstick.device.iface.Device;
|
||||
import org.tellstick.device.iface.DeviceChangeListener;
|
||||
import org.tellstick.device.iface.SensorListener;
|
||||
import org.tellstick.enums.ChangeType;
|
||||
import org.tellstick.enums.DataType;
|
||||
|
||||
/**
|
||||
* {@link TelldusCoreBridgeHandler} is the handler for Telldus Core (Duo and Basic) and connects it
|
||||
* to the framework. All {@link TelldusDevicesHandler}s use the
|
||||
* {@link TelldusCoreDeviceController} to execute the actual commands.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TelldusCoreBridgeHandler extends BaseBridgeHandler
|
||||
implements DeviceChangeListener, SensorListener, TelldusBridgeHandler {
|
||||
|
||||
public TelldusCoreBridgeHandler(Bridge br) {
|
||||
super(br);
|
||||
}
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(TelldusCoreBridgeHandler.class);
|
||||
private TelldusDeviceController deviceController = null;
|
||||
private List<TellstickDevice> deviceList = new Vector<>();
|
||||
private List<TellstickSensor> sensorList = new Vector<>();
|
||||
private TellstickEventHandler eventHandler;
|
||||
private static boolean initialized = false;
|
||||
private List<DeviceStatusListener> deviceStatusListeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
logger.debug("Refresh command received.");
|
||||
rescanTelldusDevices();
|
||||
} else {
|
||||
logger.warn("No bridge commands defined.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Telldus Core Handler disposed.");
|
||||
if (deviceController != null) {
|
||||
deviceController.dispose();
|
||||
deviceController = null;
|
||||
}
|
||||
if (eventHandler != null) {
|
||||
eventHandler.remove();
|
||||
eventHandler = null;
|
||||
}
|
||||
clearDeviceList();
|
||||
initialized = false;
|
||||
JNA.CLibrary.INSTANCE.tdClose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private String init(String libraryPath) {
|
||||
if (!initialized) {
|
||||
if (libraryPath != null) {
|
||||
logger.info("Loading {} from {}", JNA.nativeLibrary, libraryPath);
|
||||
System.setProperty("jna.library.path", libraryPath);
|
||||
} else {
|
||||
logger.info("Loading {} from system default paths", JNA.nativeLibrary);
|
||||
}
|
||||
TellstickDevice.setSupportedMethods(JNA.CLibrary.TELLSTICK_BELL | JNA.CLibrary.TELLSTICK_TURNOFF
|
||||
| JNA.CLibrary.TELLSTICK_TURNON | JNA.CLibrary.TELLSTICK_DIM);
|
||||
JNA.CLibrary.INSTANCE.tdInit();
|
||||
initialized = true;
|
||||
}
|
||||
return libraryPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing Tellstick bridge handler.");
|
||||
TellstickBridgeConfiguration configuration = getConfigAs(TellstickBridgeConfiguration.class);
|
||||
init(configuration.libraryPath);
|
||||
|
||||
scheduler.submit(() -> {
|
||||
rescanTelldusDevices();
|
||||
setupListeners();
|
||||
setupDeviceController(configuration);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
});
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
}
|
||||
|
||||
private void setupDeviceController(TellstickBridgeConfiguration configuration) {
|
||||
deviceController = new TelldusCoreDeviceController(configuration.resendInterval);
|
||||
eventHandler.addListener((TelldusCoreDeviceController) deviceController);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rescanTelldusDevices() {
|
||||
try {
|
||||
deviceList = Collections.synchronizedList(TellstickDevice.getDevices());
|
||||
for (TellstickDevice device : deviceList) {
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceAdded(getThing(), device);
|
||||
}
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceStateChanged(getThing(), device,
|
||||
new TellstickDeviceEvent(device, null, null, null, System.currentTimeMillis()));
|
||||
}
|
||||
}
|
||||
|
||||
sensorList = Collections.synchronizedList(TellstickSensor.getAllSensors());
|
||||
for (TellstickSensor sensor : sensorList) {
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceAdded(getThing(), sensor);
|
||||
}
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
for (DataType type : sensor.getData().keySet()) {
|
||||
listener.onDeviceStateChanged(getThing(), sensor,
|
||||
new TellstickSensorEvent(sensor.getId(), sensor.getData(type), type,
|
||||
sensor.getProtocol(), sensor.getModel(), System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SupportedMethodsException e) {
|
||||
logger.error("Failed to get devices ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void setupListeners() {
|
||||
eventHandler = new TellstickEventHandler(deviceList);
|
||||
eventHandler.addListener(this);
|
||||
}
|
||||
|
||||
public void onConnectionLost() {
|
||||
logger.debug("Bridge connection lost. Updating thing status to OFFLINE.");
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
}
|
||||
|
||||
public void onConnection() {
|
||||
logger.debug("Bridge connected. Updating thing status to ONLINE.");
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerDeviceStatusListener(DeviceStatusListener deviceStatusListener) {
|
||||
if (deviceStatusListener == null) {
|
||||
throw new IllegalArgumentException("It's not allowed to pass a null deviceStatusListener.");
|
||||
}
|
||||
return deviceStatusListeners.add(deviceStatusListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unregisterDeviceStatusListener(DeviceStatusListener deviceStatusListener) {
|
||||
return deviceStatusListeners.remove(deviceStatusListener);
|
||||
}
|
||||
|
||||
public void clearDeviceList() {
|
||||
deviceList.clear();
|
||||
sensorList.clear();
|
||||
}
|
||||
|
||||
private Device getDevice(String id, List<TellstickDevice> devices) {
|
||||
for (Device device : devices) {
|
||||
if (device.getId() == Integer.valueOf(id)) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device getDevice(String serialNumber) {
|
||||
return getDevice(serialNumber, deviceList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequest(TellstickSensorEvent newEvent) {
|
||||
String uuid = TellstickSensor.createUUId(newEvent.getSensorId(), newEvent.getModel(), newEvent.getProtocol());
|
||||
Device device = getSensor(uuid);
|
||||
logger.debug("Sensor Event for {} event {}", device, newEvent);
|
||||
if (device == null) {
|
||||
TellstickSensor sensor = new TellstickSensor(newEvent.getSensorId(), newEvent.getProtocol(),
|
||||
newEvent.getModel());
|
||||
sensor.setData(newEvent.getDataType(), newEvent.getData());
|
||||
sensorList.add(sensor);
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceAdded(getThing(), sensor);
|
||||
}
|
||||
} else {
|
||||
TellstickSensor useSensor = (TellstickSensor) device;
|
||||
String currentValue = useSensor.getData(newEvent.getDataType());
|
||||
Calendar compdate = Calendar.getInstance();
|
||||
compdate.add(Calendar.MINUTE, -1);
|
||||
logger.debug("Update curr {} new {}", currentValue, newEvent.getData());
|
||||
if (currentValue == null || !currentValue.equals(newEvent.getData())
|
||||
|| useSensor.getTimeStamp().before(compdate.getTime())) {
|
||||
// Changed or more than 1 minute since update
|
||||
useSensor.setData(newEvent.getDataType(), newEvent.getData());
|
||||
useSensor.setTimeStamp(new Date(newEvent.getTimestamp()));
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceStateChanged(getThing(), useSensor, newEvent);
|
||||
}
|
||||
} else {
|
||||
logger.trace("Ignored update {}", newEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequest(TellstickDeviceEvent newEvent) {
|
||||
if (newEvent.getChangeType() == ChangeType.ADDED) {
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceAdded(getThing(), newEvent.getDevice());
|
||||
}
|
||||
} else if (newEvent.getChangeType() == ChangeType.REMOVED) {
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceRemoved(getThing(), newEvent.getDevice());
|
||||
}
|
||||
} else {
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceStateChanged(getThing(), newEvent.getDevice(), newEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device getSensor(String deviceUUId) {
|
||||
for (Device device : sensorList) {
|
||||
if (device.getUUId().equals(deviceUUId)) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TelldusDeviceController getController() {
|
||||
return this.deviceController;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* 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.tellstick.internal.core;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.openhab.binding.tellstick.internal.TelldusBindingException;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusDeviceController;
|
||||
import org.openhab.core.library.types.IncreaseDecreaseType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tellstick.JNA;
|
||||
import org.tellstick.device.TellstickDevice;
|
||||
import org.tellstick.device.TellstickDeviceEvent;
|
||||
import org.tellstick.device.TellstickException;
|
||||
import org.tellstick.device.TellstickSensorEvent;
|
||||
import org.tellstick.device.iface.Device;
|
||||
import org.tellstick.device.iface.DeviceChangeListener;
|
||||
import org.tellstick.device.iface.DimmableDevice;
|
||||
import org.tellstick.device.iface.SensorListener;
|
||||
import org.tellstick.device.iface.SwitchableDevice;
|
||||
|
||||
/**
|
||||
* Device controller for telldus core (Basic and Duo).
|
||||
* This communicates with the telldus DLL using the javatellstick
|
||||
* library.
|
||||
*
|
||||
* @author Jarle Hjortland, Elias Gabrielsson - Initial contribution
|
||||
*/
|
||||
public class TelldusCoreDeviceController implements DeviceChangeListener, SensorListener, TelldusDeviceController {
|
||||
private final Logger logger = LoggerFactory.getLogger(TelldusCoreDeviceController.class);
|
||||
private long lastSend = 0;
|
||||
long resendInterval = 100;
|
||||
public static final long DEFAULT_INTERVAL_BETWEEN_SEND = 250;
|
||||
|
||||
private TelldusCoreWorker telldusCoreWorker;
|
||||
private Thread workerThread;
|
||||
private SortedMap<Device, TelldusCoreSendEvent> messageQue;
|
||||
|
||||
public TelldusCoreDeviceController(long resendInterval) {
|
||||
this.resendInterval = resendInterval;
|
||||
messageQue = Collections.synchronizedSortedMap(new TreeMap<>());
|
||||
telldusCoreWorker = new TelldusCoreWorker(messageQue);
|
||||
workerThread = new Thread(telldusCoreWorker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
workerThread.interrupt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSendEvent(Device device, int resendCount, boolean isDimmer, Command command)
|
||||
throws TellstickException {
|
||||
if (!workerThread.isAlive()) {
|
||||
workerThread.start();
|
||||
}
|
||||
|
||||
Long eventTime = System.currentTimeMillis();
|
||||
synchronized (messageQue) {
|
||||
messageQue.put(device, new TelldusCoreSendEvent(device, resendCount, isDimmer, command, eventTime));
|
||||
messageQue.notify();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public State calcState(Device dev) {
|
||||
TellstickDevice device = (TellstickDevice) dev;
|
||||
State st = null;
|
||||
switch (device.getStatus()) {
|
||||
case JNA.CLibrary.TELLSTICK_TURNON:
|
||||
st = OnOffType.ON;
|
||||
break;
|
||||
case JNA.CLibrary.TELLSTICK_TURNOFF:
|
||||
st = OnOffType.OFF;
|
||||
break;
|
||||
case JNA.CLibrary.TELLSTICK_DIM:
|
||||
BigDecimal dimValue = new BigDecimal(device.getData());
|
||||
if (dimValue.intValue() == 0) {
|
||||
st = OnOffType.OFF;
|
||||
} else if (dimValue.intValue() >= 255) {
|
||||
st = OnOffType.ON;
|
||||
} else {
|
||||
st = OnOffType.ON;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logger.warn("Could not handle {} for {}", device.getStatus(), device);
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal calcDimValue(Device device) {
|
||||
BigDecimal dimValue = new BigDecimal(0);
|
||||
switch (((TellstickDevice) device).getStatus()) {
|
||||
case JNA.CLibrary.TELLSTICK_TURNON:
|
||||
dimValue = new BigDecimal(100);
|
||||
break;
|
||||
case JNA.CLibrary.TELLSTICK_TURNOFF:
|
||||
break;
|
||||
case JNA.CLibrary.TELLSTICK_DIM:
|
||||
dimValue = new BigDecimal(((TellstickDevice) device).getData());
|
||||
dimValue = dimValue.multiply(new BigDecimal(100));
|
||||
dimValue = dimValue.divide(new BigDecimal(255), 0, BigDecimal.ROUND_HALF_UP);
|
||||
break;
|
||||
default:
|
||||
logger.warn("Could not handle {} for {}", ((TellstickDevice) device).getStatus(), device);
|
||||
}
|
||||
return dimValue;
|
||||
}
|
||||
|
||||
public long getLastSend() {
|
||||
return lastSend;
|
||||
}
|
||||
|
||||
public void setLastSend(long currentTimeMillis) {
|
||||
lastSend = currentTimeMillis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequest(TellstickSensorEvent newDevices) {
|
||||
setLastSend(newDevices.getTimestamp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequest(TellstickDeviceEvent newDevices) {
|
||||
setLastSend(newDevices.getTimestamp());
|
||||
}
|
||||
|
||||
private void sendEvent(Device device, int resendCount, boolean isdimmer, Command command)
|
||||
throws TellstickException {
|
||||
for (int i = 0; i < resendCount; i++) {
|
||||
checkLastAndWait(resendInterval);
|
||||
logger.debug("Send {} to {} times={}", command, device, i);
|
||||
if (device instanceof DimmableDevice) {
|
||||
if (command == OnOffType.ON) {
|
||||
turnOn(device);
|
||||
} else if (command == OnOffType.OFF) {
|
||||
turnOff(device);
|
||||
} else if (command instanceof PercentType) {
|
||||
dim(device, (PercentType) command);
|
||||
} else if (command instanceof IncreaseDecreaseType) {
|
||||
increaseDecrease(device, ((IncreaseDecreaseType) command));
|
||||
}
|
||||
} else if (device instanceof SwitchableDevice) {
|
||||
if (command == OnOffType.ON) {
|
||||
if (isdimmer) {
|
||||
logger.debug("Turn off first in case it is allready on");
|
||||
turnOff(device);
|
||||
checkLastAndWait(resendInterval);
|
||||
}
|
||||
turnOn(device);
|
||||
} else if (command == OnOffType.OFF) {
|
||||
turnOff(device);
|
||||
}
|
||||
} else {
|
||||
logger.warn("Cannot send to {}", device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void increaseDecrease(Device dev, IncreaseDecreaseType increaseDecreaseType) throws TellstickException {
|
||||
String strValue = ((TellstickDevice) dev).getData();
|
||||
double value = 0;
|
||||
if (strValue != null) {
|
||||
value = Double.valueOf(strValue);
|
||||
}
|
||||
int percent = (int) Math.round((value / 255) * 100);
|
||||
if (IncreaseDecreaseType.INCREASE == increaseDecreaseType) {
|
||||
percent = Math.min(percent + 10, 100);
|
||||
} else if (IncreaseDecreaseType.DECREASE == increaseDecreaseType) {
|
||||
percent = Math.max(percent - 10, 0);
|
||||
}
|
||||
|
||||
dim(dev, new PercentType(percent));
|
||||
}
|
||||
|
||||
private void dim(Device dev, PercentType command) throws TellstickException {
|
||||
double value = command.doubleValue();
|
||||
|
||||
// 0 means OFF and 100 means ON
|
||||
if (value == 0 && dev instanceof SwitchableDevice) {
|
||||
((SwitchableDevice) dev).off();
|
||||
} else if (value == 100 && dev instanceof SwitchableDevice) {
|
||||
((SwitchableDevice) dev).on();
|
||||
} else if (dev instanceof DimmableDevice) {
|
||||
long tdVal = Math.round((value / 100) * 255);
|
||||
((DimmableDevice) dev).dim((int) tdVal);
|
||||
} else {
|
||||
throw new TelldusBindingException("Cannot send DIM to " + dev);
|
||||
}
|
||||
}
|
||||
|
||||
private void turnOff(Device dev) throws TellstickException {
|
||||
if (dev instanceof SwitchableDevice) {
|
||||
((SwitchableDevice) dev).off();
|
||||
} else {
|
||||
throw new TelldusBindingException("Cannot send OFF to " + dev);
|
||||
}
|
||||
}
|
||||
|
||||
private void turnOn(Device dev) throws TellstickException {
|
||||
if (dev instanceof SwitchableDevice) {
|
||||
((SwitchableDevice) dev).on();
|
||||
} else {
|
||||
throw new TelldusBindingException("Cannot send ON to " + dev);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkLastAndWait(long resendInterval) {
|
||||
while ((System.currentTimeMillis() - lastSend) < resendInterval) {
|
||||
logger.debug("Wait for {} millisec", resendInterval);
|
||||
try {
|
||||
Thread.sleep(resendInterval);
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("Failed to sleep", e);
|
||||
}
|
||||
}
|
||||
lastSend = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a worker which execute the commands sent to the TelldusCoreDeviceController.
|
||||
* This enables separation between Telldus Core and openHAB for preventing latency on the bus.
|
||||
* The Tellstick have an send pace of 4 Hz which is far slower then the bus itself.
|
||||
*
|
||||
* @author Elias Gabrielsson
|
||||
*
|
||||
*/
|
||||
private class TelldusCoreWorker implements Runnable {
|
||||
private SortedMap<Device, TelldusCoreSendEvent> messageQue;
|
||||
|
||||
public TelldusCoreWorker(SortedMap<Device, TelldusCoreSendEvent> messageQue) {
|
||||
this.messageQue = messageQue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
try {
|
||||
TelldusCoreSendEvent sendEvent;
|
||||
// Get event to send
|
||||
synchronized (messageQue) {
|
||||
while (messageQue.isEmpty()) {
|
||||
messageQue.wait();
|
||||
}
|
||||
sendEvent = messageQue.remove(messageQue.firstKey());
|
||||
}
|
||||
// Send event
|
||||
try {
|
||||
sendEvent(sendEvent.getDevice(), sendEvent.getResendCount(), sendEvent.getDimmer(),
|
||||
sendEvent.getCommand());
|
||||
} catch (TellstickException e) {
|
||||
logger.error("Failed to send msg:{} to {}", sendEvent.getCommand(), sendEvent.getDevice(), e);
|
||||
}
|
||||
|
||||
} catch (InterruptedException ie) {
|
||||
break; // Terminate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a wrapper class to enable queuing of send events between the controller and the working thread.
|
||||
*
|
||||
* @author Elias Gabrielsson
|
||||
*
|
||||
*/
|
||||
private class TelldusCoreSendEvent implements Comparable<TelldusCoreSendEvent> {
|
||||
private Device device;
|
||||
private int resendCount;
|
||||
private boolean isDimmer;
|
||||
private Command command;
|
||||
private Long eventTime;
|
||||
|
||||
public TelldusCoreSendEvent(Device device, int resendCount, boolean isDimmer, Command command, Long eventTime) {
|
||||
this.device = device;
|
||||
this.resendCount = resendCount;
|
||||
this.isDimmer = isDimmer;
|
||||
this.command = command;
|
||||
this.eventTime = eventTime;
|
||||
}
|
||||
|
||||
public Device getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public int getResendCount() {
|
||||
return resendCount;
|
||||
}
|
||||
|
||||
public boolean getDimmer() {
|
||||
return isDimmer;
|
||||
}
|
||||
|
||||
public Command getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public Long getEventTime() {
|
||||
return eventTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(TelldusCoreSendEvent o) {
|
||||
return eventTime.compareTo(o.getEventTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* 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.tellstick.internal.discovery;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.openhab.binding.tellstick.internal.TellstickBindingConstants;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tellstick.device.TellstickController;
|
||||
|
||||
/**
|
||||
* The {@link TellstickBridgeDiscovery} is responsible for discovering new Telldus gateway devices on the network
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*
|
||||
*/
|
||||
@Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.tellstick")
|
||||
public class TellstickBridgeDiscovery extends AbstractDiscoveryService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(TellstickBridgeDiscovery.class);
|
||||
|
||||
static boolean discoveryRunning = false;
|
||||
static boolean initilized = false;
|
||||
|
||||
public TellstickBridgeDiscovery() {
|
||||
super(TellstickBindingConstants.SUPPORTED_BRIDGE_THING_TYPES_UIDS, 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypes() {
|
||||
return TellstickBindingConstants.SUPPORTED_BRIDGE_THING_TYPES_UIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
discoverController();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startBackgroundDiscovery() {
|
||||
discoverController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBackgroundDiscoveryEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private synchronized void discoverController() {
|
||||
if (!discoveryRunning) {
|
||||
discoveryRunning = true;
|
||||
listBridge();
|
||||
}
|
||||
}
|
||||
|
||||
private void listBridge() {
|
||||
try {
|
||||
List<TellstickController> cntrls = TellstickController.getControllers();
|
||||
for (TellstickController contrl : cntrls) {
|
||||
discoveryResultSubmission(contrl);
|
||||
}
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
logger.error(
|
||||
"Could not load telldus core, please make sure Telldus is installed and correct 32/64 bit java.",
|
||||
e);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
logger.error(
|
||||
"Could not load telldus core, please make sure Telldus is installed and correct 32/64 bit java.",
|
||||
e);
|
||||
} finally {
|
||||
// Close the port!
|
||||
discoveryRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void discoveryResultSubmission(TellstickController controller) {
|
||||
if (controller != null && controller.isOnline()) {
|
||||
logger.trace("Adding new Telldus Controller {}", controller);
|
||||
Map<String, Object> properties = new HashMap<>(2);
|
||||
ThingUID uid = new ThingUID(TellstickBindingConstants.TELLDUSCOREBRIDGE_THING_TYPE,
|
||||
Integer.toString(controller.getId()));
|
||||
thingDiscovered(DiscoveryResultBuilder.create(uid).withProperties(properties)
|
||||
.withLabel(controller.getType().name() + ": " + controller.getName()).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* 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.tellstick.internal.discovery;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.openhab.binding.tellstick.internal.TellstickBindingConstants;
|
||||
import org.openhab.binding.tellstick.internal.handler.DeviceStatusListener;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusBridgeHandler;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.LiveDataType;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetDevice;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetSensor;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tellstick.JNA;
|
||||
import org.tellstick.device.TellstickSensor;
|
||||
import org.tellstick.device.iface.Device;
|
||||
import org.tellstick.device.iface.DimmableDevice;
|
||||
import org.tellstick.device.iface.SwitchableDevice;
|
||||
import org.tellstick.device.iface.TellstickEvent;
|
||||
import org.tellstick.enums.DataType;
|
||||
|
||||
/**
|
||||
* The {@link TellstickDiscoveryService} class is used to discover Tellstick
|
||||
* devices that are connected to the Lan gateway.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TellstickDiscoveryService extends AbstractDiscoveryService implements DeviceStatusListener {
|
||||
private static final long DEFAULT_TTL = 60 * 60; // 1 Hour
|
||||
|
||||
public TellstickDiscoveryService(int timeout) throws IllegalArgumentException {
|
||||
super(timeout);
|
||||
}
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(TellstickDiscoveryService.class);
|
||||
|
||||
private List<TelldusBridgeHandler> telldusBridgeHandlers = new Vector<>();
|
||||
|
||||
public TellstickDiscoveryService(TelldusBridgeHandler telldusBridgeHandler) {
|
||||
super(TellstickBindingConstants.SUPPORTED_DEVICE_THING_TYPES_UIDS, 10, true);
|
||||
this.telldusBridgeHandlers.add(telldusBridgeHandler);
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
for (TelldusBridgeHandler telldusBridgeHandler : telldusBridgeHandlers) {
|
||||
telldusBridgeHandler.registerDeviceStatusListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
for (TelldusBridgeHandler telldusBridgeHandler : telldusBridgeHandlers) {
|
||||
telldusBridgeHandler.unregisterDeviceStatusListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypes() {
|
||||
return TellstickBindingConstants.SUPPORTED_DEVICE_THING_TYPES_UIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceAdded(Bridge bridge, Device device) {
|
||||
logger.debug("Adding new TellstickDevice! '{}' with id '{}' and type '{}' to smarthome inbox", device,
|
||||
device.getId(), device.getDeviceType());
|
||||
ThingUID thingUID = getThingUID(bridge, device);
|
||||
logger.debug("Detected thingUID: {}", thingUID);
|
||||
if (thingUID != null) {
|
||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withTTL(DEFAULT_TTL)
|
||||
.withProperty(TellstickBindingConstants.DEVICE_ID, device.getUUId())
|
||||
.withProperty(TellstickBindingConstants.DEVICE_NAME, device.getName()).withBridge(bridge.getUID())
|
||||
.withLabel(device.getDeviceType() + ": " + device.getName()).build();
|
||||
thingDiscovered(discoveryResult);
|
||||
} else {
|
||||
logger.warn("Discovered Tellstick! device is unsupported: type '{}' with id '{}'", device.getDeviceType(),
|
||||
device.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startScan() {
|
||||
for (TelldusBridgeHandler telldusBridgeHandler : telldusBridgeHandlers) {
|
||||
telldusBridgeHandler.rescanTelldusDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceStateChanged(Bridge bridge, Device device, TellstickEvent event) {
|
||||
// this can be ignored here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceRemoved(Bridge bridge, Device device) {
|
||||
ThingUID thingUID = getThingUID(bridge, device);
|
||||
if (thingUID != null) {
|
||||
thingRemoved(thingUID);
|
||||
} else {
|
||||
logger.warn("Removed Tellstick! device is unsupported: type '{}' with id '{}'", device.getDeviceType(),
|
||||
device.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private ThingUID getThingUID(Bridge bridge, Device device) {
|
||||
ThingUID thingUID = null;
|
||||
switch (device.getDeviceType()) {
|
||||
case SENSOR:
|
||||
ThingTypeUID sensorThingId = findSensorType(device);
|
||||
thingUID = new ThingUID(sensorThingId, bridge.getUID(), device.getUUId());
|
||||
break;
|
||||
case DEVICE:
|
||||
if (device instanceof DimmableDevice) {
|
||||
thingUID = new ThingUID(TellstickBindingConstants.DIMMER_THING_TYPE, bridge.getUID(),
|
||||
device.getUUId());
|
||||
} else if (device instanceof SwitchableDevice) {
|
||||
thingUID = new ThingUID(TellstickBindingConstants.SWITCH_THING_TYPE, bridge.getUID(),
|
||||
device.getUUId());
|
||||
} else if (device instanceof TellstickNetDevice) {
|
||||
if ((((TellstickNetDevice) device).getMethods() & JNA.CLibrary.TELLSTICK_DIM) > 0) {
|
||||
thingUID = new ThingUID(TellstickBindingConstants.DIMMER_THING_TYPE, bridge.getUID(),
|
||||
device.getUUId());
|
||||
} else {
|
||||
thingUID = new ThingUID(TellstickBindingConstants.SWITCH_THING_TYPE, bridge.getUID(),
|
||||
device.getUUId());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return thingUID;
|
||||
}
|
||||
|
||||
private ThingTypeUID findSensorType(Device device) {
|
||||
logger.debug("Device: {}", device);
|
||||
ThingTypeUID sensorThingId;
|
||||
if (device instanceof TellstickSensor) {
|
||||
TellstickSensor sensor = (TellstickSensor) device;
|
||||
logger.debug("Sensor: {}", device);
|
||||
if (sensor.getData(DataType.WINDAVERAGE) != null || sensor.getData(DataType.WINDGUST) != null
|
||||
|| sensor.getData(DataType.WINDDIRECTION) != null) {
|
||||
sensorThingId = TellstickBindingConstants.WINDSENSOR_THING_TYPE;
|
||||
} else if (sensor.getData(DataType.RAINTOTAL) != null || sensor.getData(DataType.RAINRATE) != null) {
|
||||
sensorThingId = TellstickBindingConstants.RAINSENSOR_THING_TYPE;
|
||||
} else {
|
||||
sensorThingId = TellstickBindingConstants.SENSOR_THING_TYPE;
|
||||
}
|
||||
} else {
|
||||
TellstickNetSensor sensor = (TellstickNetSensor) device;
|
||||
if (sensor.isSensorOfType(LiveDataType.WINDAVERAGE) || sensor.isSensorOfType(LiveDataType.WINDDIRECTION)
|
||||
|| sensor.isSensorOfType(LiveDataType.WINDGUST)) {
|
||||
sensorThingId = TellstickBindingConstants.WINDSENSOR_THING_TYPE;
|
||||
} else if (sensor.isSensorOfType(LiveDataType.RAINRATE) || sensor.isSensorOfType(LiveDataType.RAINTOTAL)) {
|
||||
sensorThingId = TellstickBindingConstants.RAINSENSOR_THING_TYPE;
|
||||
} else if (sensor.isSensorOfType(LiveDataType.WATT)) {
|
||||
sensorThingId = TellstickBindingConstants.POWERSENSOR_THING_TYPE;
|
||||
} else {
|
||||
sensorThingId = TellstickBindingConstants.SENSOR_THING_TYPE;
|
||||
}
|
||||
}
|
||||
return sensorThingId;
|
||||
}
|
||||
|
||||
public void addBridgeHandler(TelldusBridgeHandler tellstickBridgeHandler) {
|
||||
telldusBridgeHandlers.add(tellstickBridgeHandler);
|
||||
tellstickBridgeHandler.registerDeviceStatusListener(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.tellstick.internal.handler;
|
||||
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.tellstick.device.iface.Device;
|
||||
import org.tellstick.device.iface.TellstickEvent;
|
||||
|
||||
/**
|
||||
* The {@link DeviceStatusListener} is notified when a device status has changed
|
||||
* or a device has been removed or added.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public interface DeviceStatusListener {
|
||||
|
||||
/**
|
||||
* This method is called whenever the state of the given device has changed.
|
||||
* The new state can be obtained by {@link FullLight#getState()}.
|
||||
*
|
||||
* @param bridge
|
||||
* The Tellstick bridge the changed device is connected to.
|
||||
* @param device
|
||||
* The device which received the state update.
|
||||
*/
|
||||
public void onDeviceStateChanged(Bridge bridge, Device device, TellstickEvent deviceEvent);
|
||||
|
||||
/**
|
||||
* This method us called whenever a device is removed.
|
||||
*
|
||||
* @param bridge
|
||||
* The Tellstick bridge the removed device was connected to.
|
||||
* @param device
|
||||
* The device which is removed.
|
||||
*/
|
||||
public void onDeviceRemoved(Bridge bridge, Device device);
|
||||
|
||||
/**
|
||||
* This method us called whenever a device is added.
|
||||
*
|
||||
* @param bridge
|
||||
* The Tellstick bridge the added device was connected to.
|
||||
* @param device
|
||||
* The device which is added.
|
||||
*/
|
||||
public void onDeviceAdded(Bridge bridge, Device device);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 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.tellstick.internal.handler;
|
||||
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.tellstick.device.iface.Device;
|
||||
|
||||
/**
|
||||
* Interface for the telldus bridge modules
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public interface TelldusBridgeHandler {
|
||||
|
||||
/**
|
||||
* TelldusDeviceController
|
||||
* Add a status listener.
|
||||
*
|
||||
* @param deviceStatusListener
|
||||
* @return
|
||||
*/
|
||||
boolean registerDeviceStatusListener(DeviceStatusListener deviceStatusListener);
|
||||
|
||||
/**
|
||||
* Remove a status listener.
|
||||
*
|
||||
* @param deviceStatusListener
|
||||
* @return
|
||||
*/
|
||||
boolean unregisterDeviceStatusListener(DeviceStatusListener deviceStatusListener);
|
||||
|
||||
/**
|
||||
* Get a device from the bridgehandler.
|
||||
*
|
||||
* @param serialNumber
|
||||
* @return
|
||||
*/
|
||||
Device getDevice(String serialNumber);
|
||||
|
||||
/**
|
||||
* Get a sensor from the bridgehandler.
|
||||
*
|
||||
* @param serialNumber
|
||||
* @return
|
||||
*/
|
||||
Device getSensor(String deviceUUId);
|
||||
|
||||
/**
|
||||
* Tell the bridge to rescan for new devices.
|
||||
*
|
||||
*/
|
||||
void rescanTelldusDevices();
|
||||
|
||||
/**
|
||||
* Get the controller to communicate with devices.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TelldusDeviceController getController();
|
||||
|
||||
/**
|
||||
* Send a command to the controller.
|
||||
*
|
||||
* @param channelUID
|
||||
* @param command
|
||||
*/
|
||||
void handleCommand(ChannelUID channelUID, Command command);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* 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.tellstick.internal.handler;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.tellstick.device.TellstickException;
|
||||
import org.tellstick.device.iface.Device;
|
||||
|
||||
/**
|
||||
* Interface for telldus controllers. This is used to send and get status of devices from the controller.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public interface TelldusDeviceController {
|
||||
|
||||
/**
|
||||
* Send an event to the controller.
|
||||
*
|
||||
* @param device
|
||||
* @param resendCount
|
||||
* @param isdimmer
|
||||
* @param command
|
||||
* @throws TellstickException
|
||||
*/
|
||||
void handleSendEvent(Device device, int resendCount, boolean isdimmer, Command command) throws TellstickException;
|
||||
|
||||
/**
|
||||
* Get the state of the given device.
|
||||
*
|
||||
* @param dev
|
||||
* @return
|
||||
*/
|
||||
State calcState(Device dev);
|
||||
|
||||
/**
|
||||
* Get the current dim state for a device.
|
||||
*
|
||||
* @param device
|
||||
* @return
|
||||
*/
|
||||
BigDecimal calcDimValue(Device device);
|
||||
|
||||
/**
|
||||
*
|
||||
* Clean up the device controller before shutdown.
|
||||
*
|
||||
*/
|
||||
void dispose();
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
/**
|
||||
* 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.tellstick.internal.handler;
|
||||
|
||||
import static org.openhab.binding.tellstick.internal.TellstickBindingConstants.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.openhab.binding.tellstick.internal.TellstickBindingConstants;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.DataTypeValue;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetSensor;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetSensorEvent;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tellstick.device.TellstickDeviceEvent;
|
||||
import org.tellstick.device.TellstickException;
|
||||
import org.tellstick.device.TellstickSensor;
|
||||
import org.tellstick.device.TellstickSensorEvent;
|
||||
import org.tellstick.device.iface.Device;
|
||||
import org.tellstick.device.iface.DimmableDevice;
|
||||
import org.tellstick.device.iface.TellstickEvent;
|
||||
import org.tellstick.enums.DataType;
|
||||
import org.tellstick.enums.DeviceType;
|
||||
|
||||
/**
|
||||
* Handler for telldus and tellstick devices. This sends the commands to the correct bridge.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TelldusDevicesHandler extends BaseThingHandler implements DeviceStatusListener {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(TelldusDevicesHandler.class);
|
||||
private String deviceId;
|
||||
private Boolean isDimmer = Boolean.FALSE;
|
||||
private int resend = 1;
|
||||
private TelldusBridgeHandler bridgeHandler = null;
|
||||
private final ChannelUID stateChannel;
|
||||
private final ChannelUID dimChannel;
|
||||
private final ChannelUID humidityChannel;
|
||||
private final ChannelUID tempChannel;
|
||||
private final ChannelUID raintTotChannel;
|
||||
private final ChannelUID rainRateChannel;
|
||||
private final ChannelUID windAverageChannel;
|
||||
private final ChannelUID windDirectionChannel;
|
||||
private final ChannelUID windGuestChannel;
|
||||
private final ChannelUID wattChannel;
|
||||
private final ChannelUID ampereChannel;
|
||||
private final ChannelUID luxChannel;
|
||||
private final ChannelUID timestampChannel;
|
||||
|
||||
public TelldusDevicesHandler(Thing thing) {
|
||||
super(thing);
|
||||
stateChannel = new ChannelUID(getThing().getUID(), CHANNEL_STATE);
|
||||
dimChannel = new ChannelUID(getThing().getUID(), CHANNEL_DIMMER);
|
||||
humidityChannel = new ChannelUID(getThing().getUID(), CHANNEL_HUMIDITY);
|
||||
tempChannel = new ChannelUID(getThing().getUID(), CHANNEL_TEMPERATURE);
|
||||
raintTotChannel = new ChannelUID(getThing().getUID(), CHANNEL_RAINTOTAL);
|
||||
rainRateChannel = new ChannelUID(getThing().getUID(), CHANNEL_RAINRATE);
|
||||
windAverageChannel = new ChannelUID(getThing().getUID(), CHANNEL_WINDAVERAGE);
|
||||
windDirectionChannel = new ChannelUID(getThing().getUID(), CHANNEL_WINDDIRECTION);
|
||||
windGuestChannel = new ChannelUID(getThing().getUID(), CHANNEL_WINDGUST);
|
||||
wattChannel = new ChannelUID(getThing().getUID(), CHANNEL_WATT);
|
||||
ampereChannel = new ChannelUID(getThing().getUID(), CHANNEL_AMPERE);
|
||||
timestampChannel = new ChannelUID(getThing().getUID(), CHANNEL_TIMESTAMP);
|
||||
luxChannel = new ChannelUID(getThing().getUID(), CHANNEL_LUX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
logger.debug("Handle event {} for {}", command, channelUID);
|
||||
TelldusBridgeHandler bridgeHandler = getTellstickBridgeHandler();
|
||||
if (bridgeHandler == null) {
|
||||
logger.warn("Tellstick bridge handler not found. Cannot handle command without bridge.");
|
||||
return;
|
||||
}
|
||||
Device dev = getDevice(bridgeHandler, deviceId);
|
||||
|
||||
if (dev == null) {
|
||||
logger.warn("Device not found. Can't send command to device '{}'", deviceId);
|
||||
return;
|
||||
}
|
||||
if (command instanceof RefreshType) {
|
||||
getBridge().getHandler().handleCommand(channelUID, command);
|
||||
refreshDevice(dev);
|
||||
return;
|
||||
}
|
||||
if (channelUID.getId().equals(CHANNEL_DIMMER) || channelUID.getId().equals(CHANNEL_STATE)) {
|
||||
try {
|
||||
if (dev.getDeviceType() == DeviceType.DEVICE) {
|
||||
getTellstickBridgeHandler().getController().handleSendEvent(dev, resend, isDimmer, command);
|
||||
} else {
|
||||
logger.warn("{} is not an updateable device. Read-only", dev);
|
||||
}
|
||||
} catch (TellstickException e) {
|
||||
logger.debug("Failed to send command to tellstick", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to send command to tellstick", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
} else {
|
||||
logger.warn("Setting of channel {} not possible. Read-only", channelUID);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshDevice(Device dev) {
|
||||
if (deviceId != null && isSensor()) {
|
||||
updateSensorStates(dev);
|
||||
} else if (deviceId != null) {
|
||||
updateDeviceState(dev);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
Configuration config = getConfig();
|
||||
logger.debug("Initialize TelldusDeviceHandler {}. class {}", config, config.getClass());
|
||||
final Object configDeviceId = config.get(TellstickBindingConstants.DEVICE_ID);
|
||||
if (configDeviceId != null) {
|
||||
deviceId = configDeviceId.toString();
|
||||
} else {
|
||||
logger.debug("Initialized TellStick device missing serialNumber configuration... troubles ahead");
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
}
|
||||
final Boolean isADimmer = (Boolean) config.get(TellstickBindingConstants.DEVICE_ISDIMMER);
|
||||
if (isADimmer != null) {
|
||||
this.isDimmer = isADimmer;
|
||||
}
|
||||
final BigDecimal repeatCount = (BigDecimal) config.get(TellstickBindingConstants.DEVICE_RESEND_COUNT);
|
||||
if (repeatCount != null) {
|
||||
resend = repeatCount.intValue();
|
||||
}
|
||||
if (getBridge() != null) {
|
||||
bridgeStatusChanged(getBridge().getStatusInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||
logger.debug("device: {} bridgeStatusChanged: {}", deviceId, bridgeStatusInfo);
|
||||
if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
|
||||
try {
|
||||
TelldusBridgeHandler tellHandler = (TelldusBridgeHandler) getBridge().getHandler();
|
||||
logger.debug("Init bridge for {}, bridge:{}", deviceId, tellHandler);
|
||||
if (tellHandler != null) {
|
||||
this.bridgeHandler = tellHandler;
|
||||
this.bridgeHandler.registerDeviceStatusListener(this);
|
||||
Configuration config = editConfiguration();
|
||||
Device dev = getDevice(tellHandler, deviceId);
|
||||
if (dev != null) {
|
||||
if (dev.getName() != null) {
|
||||
config.put(TellstickBindingConstants.DEVICE_NAME, dev.getName());
|
||||
}
|
||||
if (dev.getProtocol() != null) {
|
||||
config.put(TellstickBindingConstants.DEVICE_PROTOCOL, dev.getProtocol());
|
||||
}
|
||||
if (dev.getModel() != null) {
|
||||
config.put(TellstickBindingConstants.DEVICE_MODEL, dev.getModel());
|
||||
}
|
||||
updateConfiguration(config);
|
||||
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} else {
|
||||
logger.warn(
|
||||
"Could not find {}, please make sure it is defined and that telldus service is running",
|
||||
deviceId);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to init bridge for {}", deviceId, e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, bridgeStatusInfo.getStatusDetail());
|
||||
}
|
||||
}
|
||||
|
||||
private Device getDevice(TelldusBridgeHandler tellHandler, String deviceId) {
|
||||
Device dev = null;
|
||||
if (deviceId != null) {
|
||||
if (isSensor()) {
|
||||
dev = tellHandler.getSensor(deviceId);
|
||||
} else {
|
||||
dev = tellHandler.getDevice(deviceId);
|
||||
updateDeviceState(dev);
|
||||
}
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
private boolean isSensor() {
|
||||
return (getThing().getThingTypeUID().equals(TellstickBindingConstants.SENSOR_THING_TYPE)
|
||||
|| getThing().getThingTypeUID().equals(TellstickBindingConstants.RAINSENSOR_THING_TYPE)
|
||||
|| getThing().getThingTypeUID().equals(TellstickBindingConstants.WINDSENSOR_THING_TYPE)
|
||||
|| getThing().getThingTypeUID().equals(TellstickBindingConstants.POWERSENSOR_THING_TYPE));
|
||||
}
|
||||
|
||||
private void updateSensorStates(Device dev) {
|
||||
if (dev instanceof TellstickSensor) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
for (DataType type : ((TellstickSensor) dev).getData().keySet()) {
|
||||
updateSensorDataState(type, ((TellstickSensor) dev).getData(type));
|
||||
}
|
||||
} else if (dev instanceof TellstickNetSensor) {
|
||||
if (((TellstickNetSensor) dev).getOnline()) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
for (DataTypeValue type : ((TellstickNetSensor) dev).getData()) {
|
||||
updateSensorDataState(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized TelldusBridgeHandler getTellstickBridgeHandler() {
|
||||
if (this.bridgeHandler == null) {
|
||||
logger.debug("No available bridge handler found for {} bridge {} .", deviceId, getBridge());
|
||||
}
|
||||
return this.bridgeHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceStateChanged(Bridge bridge, Device device, TellstickEvent event) {
|
||||
logger.debug("Updating states of ({} {} ({}) id: {} or {}", device.getDeviceType(), device.getName(),
|
||||
device.getUUId(), getThing().getUID(), deviceId);
|
||||
if (device.getUUId().equals(deviceId)) {
|
||||
if (event instanceof TellstickDeviceEvent) {
|
||||
updateDeviceState(device);
|
||||
} else if (event instanceof TellstickNetSensorEvent) {
|
||||
TellstickNetSensorEvent sensorevent = (TellstickNetSensorEvent) event;
|
||||
updateSensorDataState(sensorevent.getDataTypeValue());
|
||||
} else if (event instanceof TellstickSensorEvent) {
|
||||
TellstickSensorEvent sensorevent = (TellstickSensorEvent) event;
|
||||
updateSensorDataState(sensorevent.getDataType(), sensorevent.getData());
|
||||
} else {
|
||||
logger.debug("Unhandled Device {}.", device.getDeviceType());
|
||||
}
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(event.getTimestamp());
|
||||
updateState(timestampChannel,
|
||||
new DateTimeType(ZonedDateTime.ofInstant(cal.toInstant(), ZoneId.systemDefault())));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSensorDataState(DataType dataType, String data) {
|
||||
switch (dataType) {
|
||||
case HUMIDITY:
|
||||
updateState(humidityChannel, new QuantityType<>(new BigDecimal(data), HUMIDITY_UNIT));
|
||||
break;
|
||||
case TEMPERATURE:
|
||||
updateState(tempChannel, new QuantityType<>(new BigDecimal(data), SIUnits.CELSIUS));
|
||||
break;
|
||||
case RAINRATE:
|
||||
updateState(rainRateChannel, new QuantityType<>(new BigDecimal(data), RAIN_UNIT));
|
||||
break;
|
||||
case RAINTOTAL:
|
||||
updateState(raintTotChannel, new QuantityType<>(new BigDecimal(data), RAIN_UNIT));
|
||||
break;
|
||||
case WINDAVERAGE:
|
||||
updateState(windAverageChannel, new QuantityType<>(new BigDecimal(data), WIND_SPEED_UNIT_MS));
|
||||
break;
|
||||
case WINDDIRECTION:
|
||||
updateState(windDirectionChannel, new QuantityType<>(new BigDecimal(data), WIND_DIRECTION_UNIT));
|
||||
break;
|
||||
case WINDGUST:
|
||||
updateState(windGuestChannel, new QuantityType<>(new BigDecimal(data), WIND_SPEED_UNIT_MS));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSensorDataState(DataTypeValue dataType) {
|
||||
switch (dataType.getName()) {
|
||||
case HUMIDITY:
|
||||
updateState(humidityChannel, new QuantityType<>(new BigDecimal(dataType.getValue()), HUMIDITY_UNIT));
|
||||
break;
|
||||
case TEMPERATURE:
|
||||
updateState(tempChannel, new QuantityType<>(new BigDecimal(dataType.getValue()), SIUnits.CELSIUS));
|
||||
break;
|
||||
case RAINRATE:
|
||||
updateState(rainRateChannel, new QuantityType<>(new BigDecimal(dataType.getValue()), RAIN_UNIT));
|
||||
break;
|
||||
case RAINTOTAL:
|
||||
updateState(raintTotChannel, new QuantityType<>(new BigDecimal(dataType.getValue()), RAIN_UNIT));
|
||||
break;
|
||||
case WINDAVERAGE:
|
||||
updateState(windAverageChannel,
|
||||
new QuantityType<>(new BigDecimal(dataType.getValue()), WIND_SPEED_UNIT_MS));
|
||||
break;
|
||||
case WINDDIRECTION:
|
||||
updateState(windDirectionChannel,
|
||||
new QuantityType<>(new BigDecimal(dataType.getValue()), WIND_DIRECTION_UNIT));
|
||||
break;
|
||||
case WINDGUST:
|
||||
updateState(windGuestChannel,
|
||||
new QuantityType<>(new BigDecimal(dataType.getValue()), WIND_SPEED_UNIT_MS));
|
||||
break;
|
||||
case WATT:
|
||||
if (dataType.getUnit() != null && dataType.getUnit().equals("A")) {
|
||||
updateState(ampereChannel, new QuantityType<>(new BigDecimal(dataType.getValue()), ELECTRIC_UNIT));
|
||||
} else {
|
||||
updateState(wattChannel, new QuantityType<>(new BigDecimal(dataType.getValue()), POWER_UNIT));
|
||||
}
|
||||
break;
|
||||
case LUMINATION:
|
||||
updateState(luxChannel, new QuantityType<>(new DecimalType(dataType.getValue()), LUX_UNIT));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDeviceState(Device device) {
|
||||
if (device != null) {
|
||||
logger.debug("Updating state of {} {} ({}) id: {}", device.getDeviceType(), device.getName(),
|
||||
device.getUUId(), getThing().getUID());
|
||||
TelldusBridgeHandler bridgeHandler = getTellstickBridgeHandler();
|
||||
State st = null;
|
||||
if (bridgeHandler != null && bridgeHandler.getController() != null) {
|
||||
st = bridgeHandler.getController().calcState(device);
|
||||
}
|
||||
if (st != null && bridgeHandler != null) {
|
||||
BigDecimal dimValue = bridgeHandler.getController().calcDimValue(device);
|
||||
updateState(stateChannel, st);
|
||||
if (device instanceof DimmableDevice) {
|
||||
updateState(dimChannel, new PercentType(dimValue));
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.REMOVED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceRemoved(Bridge bridge, Device device) {
|
||||
if (device.getUUId().equals(deviceId)) {
|
||||
updateStatus(ThingStatus.REMOVED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceAdded(Bridge bridge, Device device) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openhab.binding.tellstick.internal.conf.TelldusLiveConfiguration;
|
||||
import org.openhab.binding.tellstick.internal.handler.DeviceStatusListener;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusBridgeHandler;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusDeviceController;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusDevicesHandler;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.DataTypeValue;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetDevice;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetDevices;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetSensor;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetSensorEvent;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetSensors;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tellstick.device.TellstickDeviceEvent;
|
||||
import org.tellstick.device.TellstickException;
|
||||
import org.tellstick.device.iface.Device;
|
||||
|
||||
/**
|
||||
* {@link TelldusLiveBridgeHandler} is the handler for Telldus Live service (Tellstick.NET and ZNET) and connects it
|
||||
* to the framework. All {@link TelldusDevicesHandler}s use the
|
||||
* {@link TelldusLiveDeviceController} to execute the actual commands.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TelldusLiveBridgeHandler extends BaseBridgeHandler implements TelldusBridgeHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(TelldusLiveBridgeHandler.class);
|
||||
|
||||
private TellstickNetDevices deviceList = null;
|
||||
private TellstickNetSensors sensorList = null;
|
||||
private TelldusLiveDeviceController controller = new TelldusLiveDeviceController();
|
||||
private List<DeviceStatusListener> deviceStatusListeners = new Vector<>();
|
||||
|
||||
private static final int REFRESH_DELAY = 10;
|
||||
|
||||
public TelldusLiveBridgeHandler(Bridge bridge) {
|
||||
super(bridge);
|
||||
}
|
||||
|
||||
private ScheduledFuture<?> pollingJob;
|
||||
private ScheduledFuture<?> immediateRefreshJob;
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Live Handler disposed.");
|
||||
if (pollingJob != null) {
|
||||
pollingJob.cancel(true);
|
||||
}
|
||||
if (this.controller != null) {
|
||||
this.controller.dispose();
|
||||
}
|
||||
deviceList = null;
|
||||
sensorList = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing TelldusLive bridge handler.");
|
||||
TelldusLiveConfiguration configuration = getConfigAs(TelldusLiveConfiguration.class);
|
||||
this.controller = new TelldusLiveDeviceController();
|
||||
this.controller.connectHttpClient(configuration.publicKey, configuration.privateKey, configuration.token,
|
||||
configuration.tokenSecret);
|
||||
startAutomaticRefresh(configuration.refreshInterval);
|
||||
refreshDeviceList();
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
private synchronized void startAutomaticRefresh(long refreshInterval) {
|
||||
if (pollingJob != null && !pollingJob.isCancelled()) {
|
||||
pollingJob.cancel(true);
|
||||
}
|
||||
pollingJob = scheduler.scheduleWithFixedDelay(this::refreshDeviceList, 0, refreshInterval,
|
||||
TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void scheduleImmediateRefresh() {
|
||||
// We schedule in 10 sec, to avoid multiple updates
|
||||
logger.debug("Current remaining delay {}", pollingJob.getDelay(TimeUnit.SECONDS));
|
||||
if (pollingJob.getDelay(TimeUnit.SECONDS) > REFRESH_DELAY) {
|
||||
if (immediateRefreshJob == null || immediateRefreshJob.isDone()) {
|
||||
immediateRefreshJob = scheduler.schedule(this::refreshDeviceList, REFRESH_DELAY, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void refreshDeviceList() {
|
||||
try {
|
||||
updateDevices(deviceList);
|
||||
updateSensors(sensorList);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} catch (TellstickException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
logger.error("Failed to update", e);
|
||||
} catch (Exception e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
logger.error("Failed to update", e);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updateDevices(TellstickNetDevices previouslist) throws TellstickException {
|
||||
TellstickNetDevices newList = controller.callRestMethod(TelldusLiveDeviceController.HTTP_TELLDUS_DEVICES,
|
||||
TellstickNetDevices.class);
|
||||
logger.debug("Device list {}", newList.getDevices());
|
||||
if (newList.getDevices() != null) {
|
||||
if (previouslist == null) {
|
||||
logger.debug("updateDevices, Creating devices.");
|
||||
for (TellstickNetDevice device : newList.getDevices()) {
|
||||
device.setUpdated(true);
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceAdded(getThing(), device);
|
||||
}
|
||||
}
|
||||
this.deviceList = newList;
|
||||
} else {
|
||||
logger.debug("updateDevices, Updating devices.");
|
||||
for (TellstickNetDevice device : newList.getDevices()) {
|
||||
int index = previouslist.getDevices().indexOf(device);
|
||||
logger.debug("Device:{} found at {}", device, index);
|
||||
if (index >= 0) {
|
||||
TellstickNetDevice orgDevice = previouslist.getDevices().get(index);
|
||||
if (device.getState() != orgDevice.getState()) {
|
||||
orgDevice.setState(device.getState());
|
||||
orgDevice.setStatevalue(device.getStatevalue());
|
||||
orgDevice.setUpdated(true);
|
||||
}
|
||||
} else {
|
||||
logger.debug("New Device - Adding:{}", device);
|
||||
previouslist.getDevices().add(device);
|
||||
device.setUpdated(true);
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceAdded(getThing(), device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (TellstickNetDevice device : deviceList.getDevices()) {
|
||||
if (device.isUpdated()) {
|
||||
logger.debug("Updated device:{}", device);
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceStateChanged(getThing(), device,
|
||||
new TellstickDeviceEvent(device, null, null, null, System.currentTimeMillis()));
|
||||
}
|
||||
device.setUpdated(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updateSensors(TellstickNetSensors previouslist) throws TellstickException {
|
||||
TellstickNetSensors newList = controller.callRestMethod(TelldusLiveDeviceController.HTTP_TELLDUS_SENSORS,
|
||||
TellstickNetSensors.class);
|
||||
logger.debug("Updated sensors:{}", newList.getSensors());
|
||||
if (newList.getSensors() != null) {
|
||||
if (previouslist == null) {
|
||||
logger.debug("First update of sensors");
|
||||
this.sensorList = newList;
|
||||
for (TellstickNetSensor sensor : sensorList.getSensors()) {
|
||||
sensor.setUpdated(true);
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceAdded(getThing(), sensor);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.debug("Update sensors, reset updated flag");
|
||||
for (TellstickNetSensor sensor : previouslist.getSensors()) {
|
||||
sensor.setUpdated(false);
|
||||
}
|
||||
logger.debug("Update sensors, reset updated flag1");
|
||||
|
||||
for (TellstickNetSensor sensor : newList.getSensors()) {
|
||||
int index = this.sensorList.getSensors().indexOf(sensor);
|
||||
if (index >= 0) {
|
||||
TellstickNetSensor orgSensor = this.sensorList.getSensors().get(index);
|
||||
logger.debug("Update sensor {}, prev update {}, new update {}", sensor.getId(),
|
||||
orgSensor.getLastUpdated(), sensor.getLastUpdated());
|
||||
if (sensor.getLastUpdated() > orgSensor.getLastUpdated()) {
|
||||
logger.debug("Update for sensor:{}", sensor);
|
||||
orgSensor.setData(sensor.getData());
|
||||
orgSensor.setLastUpdated(sensor.getLastUpdated());
|
||||
orgSensor.setUpdated(true);
|
||||
sensor.setUpdated(true);
|
||||
}
|
||||
} else {
|
||||
logger.debug("Adding sensor {}, new update {}", sensor.getId(), sensor.getLastUpdated());
|
||||
this.sensorList.getSensors().add(sensor);
|
||||
sensor.setUpdated(true);
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
listener.onDeviceAdded(getThing(), sensor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (TellstickNetSensor sensor : sensorList.getSensors()) {
|
||||
if (sensor.getData() != null && sensor.isUpdated()) {
|
||||
for (DeviceStatusListener listener : deviceStatusListeners) {
|
||||
for (DataTypeValue type : sensor.getData()) {
|
||||
listener.onDeviceStateChanged(getThing(), sensor,
|
||||
new TellstickNetSensorEvent(sensor.getId(), type.getValue(), type,
|
||||
sensor.getProtocol(), sensor.getModel(), System.currentTimeMillis()));
|
||||
}
|
||||
}
|
||||
sensor.setUpdated(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
scheduleImmediateRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRemoval() {
|
||||
super.handleRemoval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUpdate(ChannelUID channelUID, State newState) {
|
||||
super.handleUpdate(channelUID, newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void thingUpdated(Thing thing) {
|
||||
super.thingUpdated(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerDeviceStatusListener(DeviceStatusListener deviceStatusListener) {
|
||||
if (deviceStatusListener == null) {
|
||||
throw new IllegalArgumentException("It's not allowed to pass a null deviceStatusListener.");
|
||||
}
|
||||
return deviceStatusListeners.add(deviceStatusListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unregisterDeviceStatusListener(DeviceStatusListener deviceStatusListener) {
|
||||
return deviceStatusListeners.remove(deviceStatusListener);
|
||||
}
|
||||
|
||||
private Device getDevice(String id, List<TellstickNetDevice> devices) {
|
||||
for (Device device : devices) {
|
||||
if (device.getId() == Integer.valueOf(id)) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Device getSensor(String id, List<TellstickNetSensor> sensors) {
|
||||
for (Device sensor : sensors) {
|
||||
if (sensor.getId() == Integer.valueOf(id)) {
|
||||
return sensor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device getDevice(String serialNumber) {
|
||||
return getDevice(serialNumber, getDevices());
|
||||
}
|
||||
|
||||
private List<TellstickNetDevice> getDevices() {
|
||||
if (deviceList == null) {
|
||||
refreshDeviceList();
|
||||
}
|
||||
return deviceList.getDevices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device getSensor(String deviceUUId) {
|
||||
Device result = null;
|
||||
if (sensorList != null) {
|
||||
result = getSensor(deviceUUId, sensorList.getSensors());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rescanTelldusDevices() {
|
||||
this.deviceList = null;
|
||||
this.sensorList = null;
|
||||
refreshDeviceList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TelldusDeviceController getController() {
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.stream.FactoryConfigurationError;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import org.asynchttpclient.AsyncHttpClient;
|
||||
import org.asynchttpclient.AsyncHttpClientConfig;
|
||||
import org.asynchttpclient.DefaultAsyncHttpClient;
|
||||
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
|
||||
import org.asynchttpclient.DefaultAsyncHttpClientConfig.Builder;
|
||||
import org.asynchttpclient.Response;
|
||||
import org.asynchttpclient.oauth.ConsumerKey;
|
||||
import org.asynchttpclient.oauth.OAuthSignatureCalculator;
|
||||
import org.asynchttpclient.oauth.RequestToken;
|
||||
import org.openhab.binding.tellstick.internal.TelldusBindingException;
|
||||
import org.openhab.binding.tellstick.internal.handler.TelldusDeviceController;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TelldusLiveResponse;
|
||||
import org.openhab.binding.tellstick.internal.live.xml.TellstickNetDevice;
|
||||
import org.openhab.core.library.types.IncreaseDecreaseType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tellstick.JNA;
|
||||
import org.tellstick.device.TellstickDevice;
|
||||
import org.tellstick.device.TellstickDeviceEvent;
|
||||
import org.tellstick.device.TellstickException;
|
||||
import org.tellstick.device.TellstickSensorEvent;
|
||||
import org.tellstick.device.iface.Device;
|
||||
import org.tellstick.device.iface.DeviceChangeListener;
|
||||
import org.tellstick.device.iface.SensorListener;
|
||||
import org.tellstick.device.iface.SwitchableDevice;
|
||||
|
||||
/**
|
||||
* {@link TelldusLiveDeviceController} is the communication with Telldus Live service (Tellstick.NET and ZNET)
|
||||
* This controller uses XML based Rest API to communicate with Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TelldusLiveDeviceController implements DeviceChangeListener, SensorListener, TelldusDeviceController {
|
||||
private final Logger logger = LoggerFactory.getLogger(TelldusLiveDeviceController.class);
|
||||
private long lastSend = 0;
|
||||
public static final long DEFAULT_INTERVAL_BETWEEN_SEND = 250;
|
||||
static final int REQUEST_TIMEOUT_MS = 5000;
|
||||
private AsyncHttpClient client;
|
||||
static final String HTTP_API_TELLDUS_COM_XML = "http://api.telldus.com/xml/";
|
||||
static final String HTTP_TELLDUS_CLIENTS = HTTP_API_TELLDUS_COM_XML + "clients/list";
|
||||
static final String HTTP_TELLDUS_DEVICES = HTTP_API_TELLDUS_COM_XML + "devices/list?supportedMethods=19";
|
||||
static final String HTTP_TELLDUS_SENSORS = HTTP_API_TELLDUS_COM_XML
|
||||
+ "sensors/list?includeValues=1&includeScale=1&includeUnit=1";
|
||||
static final String HTTP_TELLDUS_SENSOR_INFO = HTTP_API_TELLDUS_COM_XML + "sensor/info";
|
||||
static final String HTTP_TELLDUS_DEVICE_DIM = HTTP_API_TELLDUS_COM_XML + "device/dim?id=%d&level=%d";
|
||||
static final String HTTP_TELLDUS_DEVICE_TURNOFF = HTTP_API_TELLDUS_COM_XML + "device/turnOff?id=%d";
|
||||
static final String HTTP_TELLDUS_DEVICE_TURNON = HTTP_API_TELLDUS_COM_XML + "device/turnOn?id=%d";
|
||||
private static final int MAX_RETRIES = 3;
|
||||
|
||||
public TelldusLiveDeviceController() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
client.close();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to close client", e);
|
||||
}
|
||||
}
|
||||
|
||||
void connectHttpClient(String publicKey, String privateKey, String token, String tokenSecret) {
|
||||
ConsumerKey consumer = new ConsumerKey(publicKey, privateKey);
|
||||
RequestToken user = new RequestToken(token, tokenSecret);
|
||||
OAuthSignatureCalculator calc = new OAuthSignatureCalculator(consumer, user);
|
||||
this.client = new DefaultAsyncHttpClient(createAsyncHttpClientConfig());
|
||||
try {
|
||||
this.client.setSignatureCalculator(calc);
|
||||
Response response = client.prepareGet(HTTP_TELLDUS_CLIENTS).execute().get();
|
||||
logger.debug("Response {} statusText {}", response.getResponseBody(), response.getStatusText());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
logger.error("Failed to connect", e);
|
||||
}
|
||||
}
|
||||
|
||||
private AsyncHttpClientConfig createAsyncHttpClientConfig() {
|
||||
Builder builder = new DefaultAsyncHttpClientConfig.Builder();
|
||||
builder.setConnectTimeout(REQUEST_TIMEOUT_MS);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSendEvent(Device device, int resendCount, boolean isdimmer, Command command)
|
||||
throws TellstickException {
|
||||
logger.info("Send {} to {}", command, device);
|
||||
if (device instanceof TellstickNetDevice) {
|
||||
if (command == OnOffType.ON) {
|
||||
turnOn(device);
|
||||
} else if (command == OnOffType.OFF) {
|
||||
turnOff(device);
|
||||
} else if (command instanceof PercentType) {
|
||||
dim(device, (PercentType) command);
|
||||
} else if (command instanceof IncreaseDecreaseType) {
|
||||
increaseDecrease(device, ((IncreaseDecreaseType) command));
|
||||
}
|
||||
} else if (device instanceof SwitchableDevice) {
|
||||
if (command == OnOffType.ON) {
|
||||
if (isdimmer) {
|
||||
logger.debug("Turn off first in case it is allready on");
|
||||
turnOff(device);
|
||||
}
|
||||
turnOn(device);
|
||||
} else if (command == OnOffType.OFF) {
|
||||
turnOff(device);
|
||||
}
|
||||
} else {
|
||||
logger.warn("Cannot send to {}", device);
|
||||
}
|
||||
}
|
||||
|
||||
private void increaseDecrease(Device dev, IncreaseDecreaseType increaseDecreaseType) throws TellstickException {
|
||||
String strValue = ((TellstickDevice) dev).getData();
|
||||
double value = 0;
|
||||
if (strValue != null) {
|
||||
value = Double.valueOf(strValue);
|
||||
}
|
||||
int percent = (int) Math.round((value / 255) * 100);
|
||||
if (IncreaseDecreaseType.INCREASE == increaseDecreaseType) {
|
||||
percent = Math.min(percent + 10, 100);
|
||||
} else if (IncreaseDecreaseType.DECREASE == increaseDecreaseType) {
|
||||
percent = Math.max(percent - 10, 0);
|
||||
}
|
||||
dim(dev, new PercentType(percent));
|
||||
}
|
||||
|
||||
private void dim(Device dev, PercentType command) throws TellstickException {
|
||||
double value = command.doubleValue();
|
||||
|
||||
// 0 means OFF and 100 means ON
|
||||
if (value == 0 && dev instanceof TellstickNetDevice) {
|
||||
turnOff(dev);
|
||||
} else if (value == 100 && dev instanceof TellstickNetDevice) {
|
||||
turnOn(dev);
|
||||
} else if (dev instanceof TellstickNetDevice
|
||||
&& (((TellstickNetDevice) dev).getMethods() & JNA.CLibrary.TELLSTICK_DIM) > 0) {
|
||||
long tdVal = Math.round((value / 100) * 255);
|
||||
TelldusLiveResponse response = callRestMethod(String.format(HTTP_TELLDUS_DEVICE_DIM, dev.getId(), tdVal),
|
||||
TelldusLiveResponse.class);
|
||||
handleResponse((TellstickNetDevice) dev, response);
|
||||
} else {
|
||||
throw new TelldusBindingException("Cannot send DIM to " + dev);
|
||||
}
|
||||
}
|
||||
|
||||
private void turnOff(Device dev) throws TellstickException {
|
||||
if (dev instanceof TellstickNetDevice) {
|
||||
TelldusLiveResponse response = callRestMethod(String.format(HTTP_TELLDUS_DEVICE_TURNOFF, dev.getId()),
|
||||
TelldusLiveResponse.class);
|
||||
handleResponse((TellstickNetDevice) dev, response);
|
||||
} else {
|
||||
throw new TelldusBindingException("Cannot send OFF to " + dev);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleResponse(TellstickNetDevice device, TelldusLiveResponse response) throws TellstickException {
|
||||
if (response == null || (response.status == null && response.error == null)) {
|
||||
throw new TelldusBindingException("No response " + response);
|
||||
} else if (response.error != null) {
|
||||
if (response.error.equals("The client for this device is currently offline")) {
|
||||
device.setOnline(false);
|
||||
device.setUpdated(true);
|
||||
}
|
||||
throw new TelldusBindingException("Error " + response.error);
|
||||
} else if (!response.status.trim().equals("success")) {
|
||||
throw new TelldusBindingException("Response " + response.status);
|
||||
}
|
||||
}
|
||||
|
||||
private void turnOn(Device dev) throws TellstickException {
|
||||
if (dev instanceof TellstickNetDevice) {
|
||||
TelldusLiveResponse response = callRestMethod(String.format(HTTP_TELLDUS_DEVICE_TURNON, dev.getId()),
|
||||
TelldusLiveResponse.class);
|
||||
handleResponse((TellstickNetDevice) dev, response);
|
||||
} else {
|
||||
throw new TelldusBindingException("Cannot send ON to " + dev);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public State calcState(Device dev) {
|
||||
TellstickNetDevice device = (TellstickNetDevice) dev;
|
||||
State st = null;
|
||||
if (device.getOnline()) {
|
||||
switch (device.getState()) {
|
||||
case JNA.CLibrary.TELLSTICK_TURNON:
|
||||
st = OnOffType.ON;
|
||||
break;
|
||||
case JNA.CLibrary.TELLSTICK_TURNOFF:
|
||||
st = OnOffType.OFF;
|
||||
break;
|
||||
case JNA.CLibrary.TELLSTICK_DIM:
|
||||
BigDecimal dimValue = new BigDecimal(device.getStatevalue());
|
||||
if (dimValue.intValue() == 0) {
|
||||
st = OnOffType.OFF;
|
||||
} else if (dimValue.intValue() >= 255) {
|
||||
st = OnOffType.ON;
|
||||
} else {
|
||||
st = OnOffType.ON;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logger.warn("Could not handle {} for {}", device.getState(), device);
|
||||
}
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal calcDimValue(Device device) {
|
||||
BigDecimal dimValue = new BigDecimal(0);
|
||||
switch (((TellstickNetDevice) device).getState()) {
|
||||
case JNA.CLibrary.TELLSTICK_TURNON:
|
||||
dimValue = new BigDecimal(100);
|
||||
break;
|
||||
case JNA.CLibrary.TELLSTICK_TURNOFF:
|
||||
break;
|
||||
case JNA.CLibrary.TELLSTICK_DIM:
|
||||
dimValue = new BigDecimal(((TellstickNetDevice) device).getStatevalue());
|
||||
dimValue = dimValue.multiply(new BigDecimal(100));
|
||||
dimValue = dimValue.divide(new BigDecimal(255), 0, BigDecimal.ROUND_HALF_UP);
|
||||
break;
|
||||
default:
|
||||
logger.warn("Could not handle {} for {}", (((TellstickNetDevice) device).getState()), device);
|
||||
}
|
||||
return dimValue;
|
||||
}
|
||||
|
||||
public long getLastSend() {
|
||||
return lastSend;
|
||||
}
|
||||
|
||||
public void setLastSend(long currentTimeMillis) {
|
||||
lastSend = currentTimeMillis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequest(TellstickSensorEvent newDevices) {
|
||||
setLastSend(newDevices.getTimestamp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequest(TellstickDeviceEvent newDevices) {
|
||||
setLastSend(newDevices.getTimestamp());
|
||||
}
|
||||
|
||||
<T> T callRestMethod(String uri, Class<T> response) throws TelldusLiveException {
|
||||
T resultObj = null;
|
||||
try {
|
||||
for (int i = 0; i < MAX_RETRIES; i++) {
|
||||
try {
|
||||
resultObj = innerCallRest(uri, response);
|
||||
break;
|
||||
} catch (TimeoutException e) {
|
||||
logger.warn("TimeoutException error in get", e);
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn("InterruptedException error in get", e);
|
||||
}
|
||||
}
|
||||
} catch (JAXBException e) {
|
||||
logger.warn("Encoding error in get", e);
|
||||
logResponse(uri, e);
|
||||
throw new TelldusLiveException(e);
|
||||
} catch (XMLStreamException e) {
|
||||
logger.warn("Communication error in get", e);
|
||||
logResponse(uri, e);
|
||||
throw new TelldusLiveException(e);
|
||||
} catch (ExecutionException e) {
|
||||
logger.warn("ExecutionException error in get", e);
|
||||
throw new TelldusLiveException(e);
|
||||
}
|
||||
return resultObj;
|
||||
}
|
||||
|
||||
private <T> T innerCallRest(String uri, Class<T> response) throws InterruptedException, ExecutionException,
|
||||
TimeoutException, JAXBException, FactoryConfigurationError, XMLStreamException {
|
||||
Future<Response> future = client.prepareGet(uri).execute();
|
||||
Response resp = future.get(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
// TelldusLiveHandler.logger.info("Devices" + resp.getResponseBody());
|
||||
JAXBContext jc = JAXBContext.newInstance(response);
|
||||
XMLInputFactory xif = XMLInputFactory.newInstance();
|
||||
XMLStreamReader xsr = xif.createXMLStreamReader(resp.getResponseBodyAsStream());
|
||||
// xsr = new PropertyRenamerDelegate(xsr);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
T obj = (T) jc.createUnmarshaller().unmarshal(xsr);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Request [{}] Response:{}", uri, resp.getResponseBody());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void logResponse(String uri, Exception e) {
|
||||
if (e != null) {
|
||||
logger.warn("Request [{}] Failure:{}", uri, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live;
|
||||
|
||||
import org.tellstick.device.TellstickException;
|
||||
|
||||
/**
|
||||
* {@link TelldusLiveException} is used when there is exception communicating with Telldus Live.
|
||||
* This exception extends the Telldus Core exception.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TelldusLiveException extends TellstickException {
|
||||
|
||||
public TelldusLiveException(Exception source) {
|
||||
super(null, 0);
|
||||
this.initCause(source);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 3067179547449451158L;
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return getCause().getMessage();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live.xml;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
/**
|
||||
* Class used to deserialize XML from Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
@XmlRootElement(name = "data")
|
||||
public class DataTypeValue {
|
||||
|
||||
@XmlAttribute(name = "name")
|
||||
@XmlJavaTypeAdapter(value = NameToDataType.class)
|
||||
private LiveDataType dataType;
|
||||
|
||||
@XmlAttribute(name = "value")
|
||||
private String data;
|
||||
|
||||
private String unit;
|
||||
|
||||
private Integer scale;
|
||||
|
||||
public LiveDataType getName() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public void setName(LiveDataType dataType) {
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setValue(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@XmlAttribute(name = "unit")
|
||||
public String getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public void setUnit(String unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@XmlAttribute(name = "scale")
|
||||
public Integer getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public void setScale(Integer scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DataTypeValue [dataType=" + dataType + ", data=" + data + ", unit=" + unit + "]";
|
||||
}
|
||||
}
|
||||
@@ -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.tellstick.internal.live.xml;
|
||||
|
||||
/**
|
||||
* This enum is used to describe the value types in the Live API from telldus.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public enum LiveDataType {
|
||||
HUMIDITY("humidity"),
|
||||
TEMPERATURE("temp"),
|
||||
WINDAVERAGE("windaverage"),
|
||||
WINDDIRECTION("winddirection"),
|
||||
WINDGUST("windgust"),
|
||||
RAINRATE("rainrate"),
|
||||
RAINTOTAL("rainttotal"),
|
||||
WATT("watt"),
|
||||
LUMINATION("lum"),
|
||||
UNKOWN("unkown");
|
||||
|
||||
private String name;
|
||||
|
||||
LiveDataType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static LiveDataType fromName(String name) {
|
||||
LiveDataType result = LiveDataType.UNKOWN;
|
||||
for (LiveDataType m : LiveDataType.values()) {
|
||||
if (m.name.equals(name)) {
|
||||
result = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -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.tellstick.internal.live.xml;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
/**
|
||||
* Class used to deserialize XML from Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class NameToDataType extends XmlAdapter<String, LiveDataType> {
|
||||
@Override
|
||||
public LiveDataType unmarshal(String v) throws Exception {
|
||||
return LiveDataType.fromName(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String marshal(LiveDataType v) throws Exception {
|
||||
return v.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live.xml;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
/**
|
||||
* Class used to deserialize XML from Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class NumberToBooleanMapper extends XmlAdapter<Integer, Boolean> {
|
||||
|
||||
@Override
|
||||
public Boolean unmarshal(Integer v) throws Exception {
|
||||
return v == 1 ? true : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer marshal(Boolean v) throws Exception {
|
||||
return v ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live.xml;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* Class used to deserialize XML from Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
@XmlRootElement(name = "device")
|
||||
public class TelldusLiveResponse {
|
||||
@XmlElement
|
||||
public String status;
|
||||
@XmlElement
|
||||
public String error;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TelldusLiveResponse [status=" + status + ", error=" + error + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live.xml;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import org.tellstick.device.iface.Device;
|
||||
import org.tellstick.enums.DeviceType;
|
||||
|
||||
/**
|
||||
* Class used to deserialize XML from Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class TellstickNetDevice implements Device {
|
||||
@XmlAttribute(name = "id")
|
||||
int deviceId;
|
||||
private String protocol;
|
||||
private String model;
|
||||
@XmlAttribute()
|
||||
private String name;
|
||||
@XmlAttribute()
|
||||
@XmlJavaTypeAdapter(value = NumberToBooleanMapper.class)
|
||||
private Boolean online;
|
||||
@XmlAttribute
|
||||
private int state;
|
||||
@XmlAttribute
|
||||
private String statevalue;
|
||||
@XmlAttribute
|
||||
private int methods;
|
||||
|
||||
private boolean updated;
|
||||
|
||||
public TellstickNetDevice() {
|
||||
}
|
||||
|
||||
public TellstickNetDevice(int id) {
|
||||
this.deviceId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUUId() {
|
||||
return Integer.toString(deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceType getDeviceType() {
|
||||
return DeviceType.DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setId(int deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean getOnline() {
|
||||
return online;
|
||||
}
|
||||
|
||||
// @XmlJavaTypeAdapter(value = NumberToBooleanMapper.class)
|
||||
public void setOnline(boolean online) {
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
public void setUpdated(boolean b) {
|
||||
this.updated = b;
|
||||
}
|
||||
|
||||
public boolean isUpdated() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(int state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getStatevalue() {
|
||||
return statevalue;
|
||||
}
|
||||
|
||||
public void setStatevalue(String statevalue) {
|
||||
this.statevalue = statevalue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + deviceId;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
TellstickNetDevice other = (TellstickNetDevice) obj;
|
||||
if (deviceId != other.deviceId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
public void setMethods(int methods) {
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TellstickNetDevice [deviceId=" + deviceId + ", name=" + name + ", online=" + online + ", state=" + state
|
||||
+ ", statevalue=" + statevalue + ", updated=" + updated + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live.xml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* Class used to deserialize XML from Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
@XmlRootElement(name = "devices")
|
||||
public class TellstickNetDevices {
|
||||
|
||||
List<TellstickNetDevice> devices;
|
||||
|
||||
@XmlElement(name = "device")
|
||||
public List<TellstickNetDevice> getDevices() {
|
||||
return devices;
|
||||
}
|
||||
|
||||
public void setDevices(List<TellstickNetDevice> devices) {
|
||||
this.devices = devices;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live.xml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import org.tellstick.device.iface.Device;
|
||||
import org.tellstick.enums.DeviceType;
|
||||
|
||||
/**
|
||||
* Class used to deserialize XML from Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name = "sensor")
|
||||
public class TellstickNetSensor implements Device {
|
||||
@XmlAttribute(name = "id")
|
||||
int deviceId;
|
||||
@XmlAttribute()
|
||||
private String protocol;
|
||||
@XmlAttribute()
|
||||
private String name;
|
||||
@XmlAttribute()
|
||||
@XmlJavaTypeAdapter(value = NumberToBooleanMapper.class)
|
||||
private Boolean online;
|
||||
@XmlElement(name = "data")
|
||||
private List<DataTypeValue> data;
|
||||
@XmlAttribute()
|
||||
private Long lastUpdated;
|
||||
private boolean updated;
|
||||
@XmlAttribute()
|
||||
private Long battery;
|
||||
|
||||
public TellstickNetSensor() {
|
||||
}
|
||||
|
||||
public TellstickNetSensor(int id) {
|
||||
this.deviceId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUUId() {
|
||||
return Integer.toString(deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceType getDeviceType() {
|
||||
return DeviceType.SENSOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setId(int deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean getOnline() {
|
||||
return online;
|
||||
}
|
||||
|
||||
// @XmlJavaTypeAdapter(value = NumberToBooleanMapper.class)
|
||||
public void setOnline(boolean online) {
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
public List<DataTypeValue> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(List<DataTypeValue> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Long getLastUpdated() {
|
||||
return lastUpdated;
|
||||
}
|
||||
|
||||
public void setLastUpdated(Long lastUpdated) {
|
||||
this.lastUpdated = lastUpdated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + deviceId;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
TellstickNetSensor other = (TellstickNetSensor) obj;
|
||||
if (deviceId != other.deviceId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setUpdated(boolean b) {
|
||||
this.updated = b;
|
||||
}
|
||||
|
||||
public boolean isUpdated() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
public boolean isSensorOfType(LiveDataType type) {
|
||||
boolean res = false;
|
||||
if (data != null) {
|
||||
for (DataTypeValue val : data) {
|
||||
if (val.getName() == type) {
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Long getBattery() {
|
||||
return battery;
|
||||
}
|
||||
|
||||
public void setBattery(Long battery) {
|
||||
this.battery = battery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("TellstickNetSensor [deviceId=").append(deviceId).append(", protocol=").append(protocol)
|
||||
.append(", name=").append(name).append(", online=").append(online).append(", data=").append(data)
|
||||
.append(", lastUpdated=").append(lastUpdated).append(", updated=").append(updated).append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live.xml;
|
||||
|
||||
import org.openhab.binding.tellstick.internal.TellstickRuntimeException;
|
||||
import org.tellstick.device.TellstickSensorEvent;
|
||||
import org.tellstick.device.iface.TellstickEvent;
|
||||
import org.tellstick.enums.DataType;
|
||||
|
||||
/**
|
||||
* This class is used for events for the telldus live sensors.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
public class TellstickNetSensorEvent extends TellstickSensorEvent implements TellstickEvent {
|
||||
|
||||
private DataTypeValue dataType;
|
||||
|
||||
public TellstickNetSensorEvent(int sensorId, String data, DataTypeValue dataValue, String protocol, String model,
|
||||
long timeStamp) {
|
||||
super(sensorId, data, null, protocol, model, timeStamp);
|
||||
this.dataType = dataValue;
|
||||
}
|
||||
|
||||
public DataTypeValue getDataTypeValue() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getDataType() {
|
||||
throw new TellstickRuntimeException("Should not call this method");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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.tellstick.internal.live.xml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* Class used to deserialize XML from Telldus Live.
|
||||
*
|
||||
* @author Jarle Hjortland - Initial contribution
|
||||
*/
|
||||
@XmlRootElement(name = "sensors")
|
||||
public class TellstickNetSensors {
|
||||
|
||||
List<TellstickNetSensor> sensors;
|
||||
|
||||
@XmlElement(name = "sensor")
|
||||
public List<TellstickNetSensor> getSensors() {
|
||||
return sensors;
|
||||
}
|
||||
|
||||
public void setSensors(List<TellstickNetSensor> devices) {
|
||||
this.sensors = devices;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="tellstick" 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>Tellstick Binding</name>
|
||||
<description>This is the binding for Telldus Tellstick Basic, Duo, .Net and Z-Net Lite.</description>
|
||||
<author>Jarle Hjortland</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config-description:config-descriptions
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0
|
||||
https://openhab.org/schemas/config-description-1.0.0.xsd">
|
||||
|
||||
<config-description uri="thing-type:tellstick:sensor-config">
|
||||
<parameter name="protocol" type="text">
|
||||
<label>Protocol</label>
|
||||
<description>The protocol used by a specific device.</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="model" type="text">
|
||||
<label>Model</label>
|
||||
<description>The model used by a specific device.</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="name" type="text">
|
||||
<label>Name</label>
|
||||
<description>The name of the device (manually entered)</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="deviceId" type="text">
|
||||
<label>DeviceID</label>
|
||||
<description>This function returns the unique id of a device with a specific index.</description>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</config-description:config-descriptions>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="tellstick"
|
||||
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="telldus-core">
|
||||
<label>Telldus Core Gateway</label>
|
||||
<description>This bridge represents the telldus center on a local computer.</description>
|
||||
|
||||
<config-description>
|
||||
<parameter name="libraryPath" type="text" required="false">
|
||||
<label>The Location of Telldus Core DLL/SO</label>
|
||||
<description>The location of Telldus Core DLL/SO
|
||||
</description>
|
||||
<default>C:/Program Files/Telldus/;C:/Program Files (x86)/Telldus/</default>
|
||||
</parameter>
|
||||
<parameter name="resendInterval" type="integer" required="false">
|
||||
<label>ResendInterval</label>
|
||||
<description>The interval between resend.</description>
|
||||
<default>100</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</bridge-type>
|
||||
<bridge-type id="telldus-live">
|
||||
<label>Telldus Live Gateway</label>
|
||||
<description>This bridge represents the telldus live cloud service.</description>
|
||||
|
||||
<config-description>
|
||||
<parameter name="privateKey" type="text" required="true">
|
||||
<context>password</context>
|
||||
<label>Private Key</label>
|
||||
<description>The private key from telldus</description>
|
||||
</parameter>
|
||||
<parameter name="publicKey" type="text" required="true">
|
||||
<context>credentials</context>
|
||||
<label>Public Key</label>
|
||||
<description>The public key from telldus</description>
|
||||
</parameter>
|
||||
<parameter name="token" type="text" required="true">
|
||||
<context>credentials</context>
|
||||
<label>Access Token</label>
|
||||
<description>The openauth token.</description>
|
||||
</parameter>
|
||||
<parameter name="tokenSecret" type="text" required="true">
|
||||
<context>password</context>
|
||||
<label>Token Secret</label>
|
||||
<description>The openauth token secret.</description>
|
||||
</parameter>
|
||||
<parameter name="refreshInterval" type="integer" required="false">
|
||||
<label>Refresh Interval</label>
|
||||
<description>The refresh interval in ms which is used to poll Telldus Live.
|
||||
</description>
|
||||
<default>60000</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</bridge-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="tellstick"
|
||||
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">
|
||||
|
||||
<!-- Tellstick Dimmer -->
|
||||
<thing-type id="dimmer">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="telldus-core"/>
|
||||
<bridge-type-ref id="telldus-live"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Dimmable Device</label>
|
||||
<description>This is a Dimmable device</description>
|
||||
|
||||
<channels>
|
||||
<channel id="dimmer" typeId="dimmer"/>
|
||||
<channel id="state" typeId="state"/>
|
||||
<channel id="timestamp" typeId="timestamp"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="protocol" type="text" required="false">
|
||||
<label>Protocol</label>
|
||||
<description>The protocol used by a specific device.</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="name" type="text">
|
||||
<label>Name</label>
|
||||
<description>The name of the device</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="deviceId" type="text">
|
||||
<label>DeviceID</label>
|
||||
<description>This is the unique id of a device.</description>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
<parameter name="model" type="text">
|
||||
<label>Model</label>
|
||||
<description>The model used by a specific device.</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="repeat" type="integer">
|
||||
<label>Repeat</label>
|
||||
<description>The number of times to resend.</description>
|
||||
<required>false</required>
|
||||
<default>2</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="switch">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="telldus-core"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>On/Off Device</label>
|
||||
<description>This Thing defines a Switch Device</description>
|
||||
|
||||
<channels>
|
||||
<channel id="state" typeId="state"/>
|
||||
<channel id="timestamp" typeId="timestamp"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="protocol" type="text">
|
||||
<label>Protocol</label>
|
||||
<description>The protocol used by a specific device.</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="name" type="text">
|
||||
<label>Name</label>
|
||||
<description>The name of the device</description>
|
||||
<required>false</required>
|
||||
</parameter>
|
||||
<parameter name="deviceId" type="text">
|
||||
<label>DeviceID</label>
|
||||
<description>This is the unique id of a device.</description>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
|
||||
<parameter name="repeat" type="integer">
|
||||
<label>Repeat</label>
|
||||
<description>The number of times to resend.</description>
|
||||
<required>false</required>
|
||||
<default>2</default>
|
||||
</parameter>
|
||||
<parameter name="dimmer" type="boolean">
|
||||
<label>Dimmer</label>
|
||||
<description>Is this a dimmer without absolute setting (e.g. you press on to start dim and then on again to stop
|
||||
it).</description>
|
||||
<required>false</required>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="dimmer">
|
||||
<item-type>Dimmer</item-type>
|
||||
<label>Dimmer Value</label>
|
||||
<description>The channel to control the dimmer</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="state">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Switch</label>
|
||||
<description>Turns the power on or off</description>
|
||||
<category>Switch</category>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="timestamp">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Last Device Update</label>
|
||||
<description>Last device update</description>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="tellstick"
|
||||
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">
|
||||
|
||||
<thing-type id="sensor">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="telldus-core"/>
|
||||
<bridge-type-ref id="telldus-live"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Sensor</label>
|
||||
<description>This Thing defines a Sensor</description>
|
||||
<channels>
|
||||
<channel id="humidity" typeId="humidity"/>
|
||||
<channel id="timestamp" typeId="timestamp"/>
|
||||
<channel id="temperature" typeId="temperature"/>
|
||||
<channel id="lux" typeId="lux"/>
|
||||
</channels>
|
||||
<config-description-ref uri="thing-type:tellstick:sensor-config"/>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="rainsensor">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="telldus-core"/>
|
||||
<bridge-type-ref id="telldus-live"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RainSensor</label>
|
||||
<description>This Thing defines a Rain Sensor</description>
|
||||
<channels>
|
||||
<channel id="timestamp" typeId="timestamp"/>
|
||||
<channel id="rainrate" typeId="rainrate"/>
|
||||
<channel id="raintotal" typeId="raintotal"/>
|
||||
</channels>
|
||||
<config-description-ref uri="thing-type:tellstick:sensor-config"/>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="powersensor">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="telldus-live"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>PowerSensor</label>
|
||||
<description>This Thing defines a Power Sensor</description>
|
||||
<channels>
|
||||
<channel id="timestamp" typeId="timestamp"/>
|
||||
<channel id="watt" typeId="watt"/>
|
||||
<channel id="ampere" typeId="ampere"/>
|
||||
</channels>
|
||||
<config-description-ref uri="thing-type:tellstick:sensor-config"/>
|
||||
</thing-type>
|
||||
|
||||
<thing-type id="windsensor">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="telldus-core"/>
|
||||
<bridge-type-ref id="telldus-live"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>WindSensor</label>
|
||||
<description>This Thing defines a Wind Sensor</description>
|
||||
<channels>
|
||||
<channel id="timestamp" typeId="timestamp"/>
|
||||
<channel id="windgust" typeId="windgust"/>
|
||||
<channel id="winddirection" typeId="winddirection"/>
|
||||
<channel id="windaverage" typeId="windaverage"/>
|
||||
</channels>
|
||||
<config-description-ref uri="thing-type:tellstick:sensor-config"/>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="temperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature</label>
|
||||
<description>Actual measured room temperature</description>
|
||||
<category>Temperature</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="humidity">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Humidity</label>
|
||||
<description>Actual measured room Humidity</description>
|
||||
<category>Humidity</category>
|
||||
<state pattern="%d %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="rainrate">
|
||||
<item-type>Number:Length</item-type>
|
||||
<label>Rainrate</label>
|
||||
<description>The current rain rate</description>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="raintotal">
|
||||
<item-type>Number:Length</item-type>
|
||||
<label>Total Rain</label>
|
||||
<description>Total rain</description>
|
||||
<state pattern="%d %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="windgust">
|
||||
<item-type>Number:Speed</item-type>
|
||||
<label>Wind Gust</label>
|
||||
<description>Current wind gust</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="windaverage">
|
||||
<item-type>Number:Speed</item-type>
|
||||
<label>Wind Average</label>
|
||||
<description>Current average wind</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="winddirection">
|
||||
<item-type>Number:Angle</item-type>
|
||||
<label>Wind Direction</label>
|
||||
<description>Current wind direction</description>
|
||||
<category>Wind</category>
|
||||
<state min="0" max="360" step="1" readOnly="true" pattern="%.1f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="watt">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Watt</label>
|
||||
<description>Current kWatt</description>
|
||||
<state readOnly="true" pattern="%f %unit%">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="lux">
|
||||
<item-type>Number:Illuminance</item-type>
|
||||
<label>Lux</label>
|
||||
<description>Current lumination</description>
|
||||
<state readOnly="true" pattern="%f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="ampere">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Ampere</label>
|
||||
<description>Current ampere</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="timestamp">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Last Device Update</label>
|
||||
<description>Last device update</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user