Skip to content

Commit

Permalink
[tellstick] Fix for openhab#9841, adding support for Tellstick local …
Browse files Browse the repository at this point in the history
…API. (openhab#10020)

* Fix for openhab#9841.

Signed-off-by: Jan Gustafsson <[email protected]>
  • Loading branch information
jannegpriv authored and thinkingstone committed Nov 7, 2021
1 parent bc753ad commit ccdebc5
Show file tree
Hide file tree
Showing 22 changed files with 1,317 additions and 68 deletions.
53 changes: 46 additions & 7 deletions bundles/org.openhab.binding.tellstick/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ The latest versions have also implemented Z-Wave as transmission protocol which
<img src="doc/tellstick_duo.jpg" alt="Tellstick Duo with device" width="300px"/>
</p>

<p align="center">
<img src="doc/znet.jpeg" alt="Tellstick Znet lite v2" width="300px"/>
</p>

## Supported Things

This binding supports the following thing types:
Expand All @@ -24,6 +28,7 @@ Additionally the binding have two types of bridge things which correspond to ava

* *Telldus Core Bridge* - Oldest API, used by USB devices. `telldus-core`
* *Telldus Live Bridge* - Telldus Cloud service, all devices with online access. `telldus-live`
* *Telldus Local Bridge* - Telldus Local API, Tellstick Net v2/Tellstick ZNet Lite v1/v2. `telldus-local`


***Switchbased sensors workaround***
Expand All @@ -32,11 +37,12 @@ Additionally the binding have two types of bridge things which correspond to ava

## Discovery

Devices which is added to *Telldus Core* and *Telldus Live* can be discovered by openHAB.
Devices which is added to *Telldus Core*, *Telldus Live* and *Telldus Local* 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.

If you want to use the *Telldus Live* or *Telldus Local*, their bridges, *Telldus Live bridge* or *Tellstick Local*, needs to be added manually.

## Binding Configuration

Expand All @@ -54,13 +60,13 @@ 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:
Depending on your Tellstick device type there is different ways of using this binding.
The binding implements three different APIs:
**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>
**2)** *Telldus Live* which is a REST based cloud service maintained by Telldus.
**3)** *Telldus Local* which is a REST based local 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:

Expand Down Expand Up @@ -110,6 +116,36 @@ Optional:

- **refreshInterval:** How often we should contact *Telldus Live* to check for updates (in ms)

#### Telldus Local Bridge

To configure Telldus Local you need to know the local IP address of your Tellstick device and also request an access token.

Goto this page:
<https://tellstick-server.readthedocs.io/en/latest/api/authentication.html>
and follow steps 1), 2) and 3) to generate an access token.

In step 2) when you authenticate the application in your favorite browser, choose the options '1 year' and 'Auto renew access'.

Copy the 'token' returned in Step 3) and use that as accessToken in the local bridge config.

```
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImF1ZCI6IkV4YW1wbGUgYXBwIiwiZXhwIjoxNDUyOTUxNTYyfQ.eyJyZW5ldyI6dHJ1ZSwidHRsIjo4NjQwMH0.HeqoFM6-K5IuQa08Zr9HM9V2TKGRI9VxXlgdsutP7sg"
```


```
Bridge tellstick:telldus-local:3 "Tellstick Local ZWave" [ipAddress="x.y.z.w" , accesToken= "XYZ...W"]
```

Required:

- **ipAddress:** Local IP address of your Tellstick device
- **accessToken:** Access Token

Optional:

- **refreshInterval:** How often we should contact *Telldus Local* to check for updates (in ms)

## Channels

Actuators (dimmer/switch) support the following channels:
Expand Down Expand Up @@ -194,6 +230,9 @@ Bridge tellstick:telldus-core:1 "Tellstick Duo" [resendInterval=200] {
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"]
}
Bridge tellstick:telldus-local:3 "Tellstick Local ZWave" [ipAddress="192.168.50.17" , accesToken= "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImF1ZCI6IkV4YW1wbGUgYXBwIiwiZXhwIjoxNDUyOTUxNTYyfQ.eyJyZW5ldyI6dHJ1ZSwidHRsIjo4NjQwMH0.HeqoFM6-K5IuQa08Zr9HM9V2TKGRI9VxXlgdsutP7sg"] {
sensor OutsideSensor3 [protocol="fineoffset",model="temperaturehumidity",name="temperaturehumidity:120",deviceId="120_temperaturehumidity_fineoffset"]
}
```

### tellstick.items
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@

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;
Expand Down Expand Up @@ -65,6 +62,7 @@ public class TellstickBindingConstants {
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 BRIDGE_TELLDUS_LOCAL = "telldus-local";
public static final String DEVICE_SENSOR = "sensor";
public static final String DEVICE_WINDSENSOR = "windsensor";
public static final String DEVICE_RAINSENSOR = "rainsensor";
Expand All @@ -82,6 +80,7 @@ public class TellstickBindingConstants {
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);
public static final ThingTypeUID TELLDUSLOCALBRIDGE_THING_TYPE = new ThingTypeUID(BINDING_ID, BRIDGE_TELLDUS_LOCAL);
// List of all Channel ids
public static final String CHANNEL_DIMMER = "dimmer";
public static final String CHANNEL_STATE = "state";
Expand All @@ -97,13 +96,11 @@ public class TellstickBindingConstants {
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()));
public static final Set<ThingTypeUID> SUPPORTED_BRIDGE_THING_TYPES_UIDS = Set.of(TELLDUSCOREBRIDGE_THING_TYPE,
TELLDUSLIVEBRIDGE_THING_TYPE);
public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES_UIDS = Set.of(DIMMER_THING_TYPE,
SWITCH_THING_TYPE, SENSOR_THING_TYPE, RAINSENSOR_THING_TYPE, WINDSENSOR_THING_TYPE, POWERSENSOR_THING_TYPE);
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.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, TELLDUSLOCALBRIDGE_THING_TYPE);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,24 @@

import java.util.Hashtable;

import org.eclipse.jetty.client.HttpClient;
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.binding.tellstick.internal.local.TelldusLocalBridgeHandler;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.io.net.http.HttpClientFactory;
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.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -37,11 +42,18 @@
* handlers.
*
* @author Jarle Hjortland - Initial contribution
* @author Jan Gustafsson - Adding support for local API
*/
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.tellstick")
public class TellstickHandlerFactory extends BaseThingHandlerFactory {
private final Logger logger = LoggerFactory.getLogger(TellstickHandlerFactory.class);
private TellstickDiscoveryService discoveryService = null;
private final HttpClient httpClient;

@Activate
public TellstickHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
this.httpClient = httpClientFactory.getCommonHttpClient();
}

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
Expand All @@ -68,6 +80,10 @@ protected ThingHandler createHandler(Thing thing) {
TelldusLiveBridgeHandler handler = new TelldusLiveBridgeHandler((Bridge) thing);
registerDeviceDiscoveryService(handler);
return handler;
} else if (thing.getThingTypeUID().equals(TELLDUSLOCALBRIDGE_THING_TYPE)) {
TelldusLocalBridgeHandler handler = new TelldusLocalBridgeHandler((Bridge) thing, httpClient);
registerDeviceDiscoveryService(handler);
return handler;
} else if (supportsThingType(thing.getThingTypeUID())) {
return new TelldusDevicesHandler(thing);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

/**
* Configuration class for {@link TellstickBridge} bridge used to connect to the
* Tellus Live service.
* Telldus Live service.
*
* @author Jarle Hjortland - Initial contribution
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) 2010-2021 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 local API.
*
* @author Jan Gustafsson - Initial contribution
*/
public class TelldusLocalConfiguration {
public String ipAddress;
public String accessToken;
public long refreshInterval;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
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.binding.tellstick.internal.local.dto.TellstickLocalDeviceDTO;
import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalSensorDTO;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
Expand Down Expand Up @@ -141,6 +143,14 @@ private ThingUID getThingUID(Bridge bridge, Device device) {
thingUID = new ThingUID(TellstickBindingConstants.SWITCH_THING_TYPE, bridge.getUID(),
device.getUUId());
}
} else if (device instanceof TellstickLocalDeviceDTO) {
if ((((TellstickLocalDeviceDTO) 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:
Expand All @@ -163,7 +173,7 @@ private ThingTypeUID findSensorType(Device device) {
} else {
sensorThingId = TellstickBindingConstants.SENSOR_THING_TYPE;
}
} else {
} else if (device instanceof TellstickNetSensor) {
TellstickNetSensor sensor = (TellstickNetSensor) device;
if (sensor.isSensorOfType(LiveDataType.WINDAVERAGE) || sensor.isSensorOfType(LiveDataType.WINDDIRECTION)
|| sensor.isSensorOfType(LiveDataType.WINDGUST)) {
Expand All @@ -175,6 +185,18 @@ private ThingTypeUID findSensorType(Device device) {
} else {
sensorThingId = TellstickBindingConstants.SENSOR_THING_TYPE;
}
} else {
TellstickLocalSensorDTO sensor = (TellstickLocalSensorDTO) 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;
}
Expand Down
Loading

0 comments on commit ccdebc5

Please sign in to comment.