]> git.basschouten.com Git - openhab-addons.git/commitdiff
[tellstick] Fix for #9841, adding support for Tellstick local API. (#10020)
authorJan Gustafsson <jannegpriv@gmail.com>
Thu, 18 Feb 2021 08:33:22 +0000 (09:33 +0100)
committerGitHub <noreply@github.com>
Thu, 18 Feb 2021 08:33:22 +0000 (09:33 +0100)
* Fix for #9841.

Signed-off-by: Jan Gustafsson <jannegpriv@gmail.com>
22 files changed:
bundles/org.openhab.binding.tellstick/README.md
bundles/org.openhab.binding.tellstick/doc/znet.jpeg [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/TellstickBindingConstants.java
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/TellstickHandlerFactory.java
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/conf/TelldusLiveConfiguration.java
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/conf/TelldusLocalConfiguration.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/discovery/TellstickDiscoveryService.java
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/handler/TelldusDevicesHandler.java
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/live/xml/LiveDataType.java
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalBridgeHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalDeviceController.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalException.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/LocalDataTypeValueDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TelldusLocalResponseDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalDeviceDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalDevicesDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorEventDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorsDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.tellstick/src/main/resources/OH-INF/thing/bridge.xml
bundles/org.openhab.binding.tellstick/src/main/resources/OH-INF/thing/devices.xml
bundles/org.openhab.binding.tellstick/src/main/resources/OH-INF/thing/sensor.xml

index 81f542e9f7833578ac96bc8cc1c251955843137e..72e2ba7e5e2a30693e9bd67cb2b563436a79af6f 100644 (file)
@@ -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:
@@ -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***
@@ -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
 
@@ -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:
 
@@ -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:
@@ -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
diff --git a/bundles/org.openhab.binding.tellstick/doc/znet.jpeg b/bundles/org.openhab.binding.tellstick/doc/znet.jpeg
new file mode 100644 (file)
index 0000000..8d324d5
Binary files /dev/null and b/bundles/org.openhab.binding.tellstick/doc/znet.jpeg differ
index a8690ec827a662cda6ddba560cfc24e5d37bd578..1f62da26158ee4a61b852567d890a995b62827b3 100644 (file)
@@ -14,10 +14,7 @@ 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;
@@ -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";
@@ -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";
@@ -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);
 }
index 3897fcee9bd65bc0433c731363469f721c10f9a5..266e7c8bd3d3f0b1ff7493b30aff9cf3b1f24dec 100644 (file)
@@ -16,19 +16,24 @@ import static org.openhab.binding.tellstick.internal.TellstickBindingConstants.*
 
 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;
 
@@ -37,11 +42,18 @@ import org.slf4j.LoggerFactory;
  * 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) {
@@ -68,6 +80,10 @@ public class TellstickHandlerFactory extends BaseThingHandlerFactory {
             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 {
index 32528e7c11593f474c4c7171997a5d7ec3dac2c2..e334c0b9fa9fc28b74258355b83425a6c2efa823 100644 (file)
@@ -14,7 +14,7 @@ package org.openhab.binding.tellstick.internal.conf;
 
 /**
  * Configuration class for {@link TellstickBridge} bridge used to connect to the
- * Tellus Live service.
+ * Telldus Live service.
  *
  * @author Jarle Hjortland - Initial contribution
  */
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/conf/TelldusLocalConfiguration.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/conf/TelldusLocalConfiguration.java
new file mode 100644 (file)
index 0000000..61e315a
--- /dev/null
@@ -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;
+}
index 424e805fdc35a7c52406441809a7f7de27d83be6..59ab0403784ecc444e0bcc7dba61bf162581f6bc 100644 (file)
@@ -22,6 +22,8 @@ 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.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;
@@ -141,6 +143,14 @@ public class TellstickDiscoveryService extends AbstractDiscoveryService implemen
                         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:
@@ -163,7 +173,7 @@ public class TellstickDiscoveryService extends AbstractDiscoveryService implemen
             } 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)) {
@@ -175,6 +185,18 @@ public class TellstickDiscoveryService extends AbstractDiscoveryService implemen
             } 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;
     }
index b46412e42653978ffca6f453fabe56a75a8ad502..e1b57874cc7e56846d6119cb23ae733f1f459ed4 100644 (file)
@@ -23,12 +23,16 @@ 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.binding.tellstick.internal.local.dto.LocalDataTypeValueDTO;
+import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalSensorDTO;
+import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalSensorEventDTO;
 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.library.unit.Units;
 import org.openhab.core.thing.Bridge;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
@@ -109,9 +113,15 @@ public class TelldusDevicesHandler extends BaseThingHandler implements DeviceSta
             return;
         }
         if (command instanceof RefreshType) {
-            getBridge().getHandler().handleCommand(channelUID, command);
-            refreshDevice(dev);
-            return;
+            Bridge bridge = getBridge();
+            if (bridge != null) {
+                TelldusBridgeHandler localBridgeHandler = (TelldusBridgeHandler) bridge.getHandler();
+                if (localBridgeHandler != null) {
+                    localBridgeHandler.handleCommand(channelUID, command);
+                    refreshDevice(dev);
+                    return;
+                }
+            }
         }
         if (channelUID.getId().equals(CHANNEL_DIMMER) || channelUID.getId().equals(CHANNEL_STATE)) {
             try {
@@ -123,9 +133,6 @@ public class TelldusDevicesHandler extends BaseThingHandler implements DeviceSta
             } 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);
@@ -159,8 +166,9 @@ public class TelldusDevicesHandler extends BaseThingHandler implements DeviceSta
         if (repeatCount != null) {
             resend = repeatCount.intValue();
         }
-        if (getBridge() != null) {
-            bridgeStatusChanged(getBridge().getStatusInfo());
+        Bridge bridge = getBridge();
+        if (bridge != null) {
+            bridgeStatusChanged(bridge.getStatusInfo());
         }
     }
 
@@ -169,31 +177,34 @@ public class TelldusDevicesHandler extends BaseThingHandler implements DeviceSta
         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);
+                Bridge localBridge = getBridge();
+                if (localBridge != null) {
+                    TelldusBridgeHandler telldusBridgeHandler = (TelldusBridgeHandler) localBridge.getHandler();
+                    logger.debug("Init bridge for {}, bridge:{}", deviceId, telldusBridgeHandler);
+                    if (telldusBridgeHandler != null) {
+                        this.bridgeHandler = telldusBridgeHandler;
+                        this.bridgeHandler.registerDeviceStatusListener(this);
+                        Configuration config = editConfiguration();
+                        Device dev = getDevice(telldusBridgeHandler, 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);
+                            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) {
@@ -240,6 +251,10 @@ public class TelldusDevicesHandler extends BaseThingHandler implements DeviceSta
             for (DataTypeValue type : ((TellstickNetSensor) dev).getData()) {
                 updateSensorDataState(type);
             }
+        } else if (dev instanceof TellstickLocalSensorDTO) {
+            for (LocalDataTypeValueDTO type : ((TellstickLocalSensorDTO) dev).getData()) {
+                updateSensorDataState(type);
+            }
         }
     }
 
@@ -260,6 +275,9 @@ public class TelldusDevicesHandler extends BaseThingHandler implements DeviceSta
             } else if (event instanceof TellstickNetSensorEvent) {
                 TellstickNetSensorEvent sensorevent = (TellstickNetSensorEvent) event;
                 updateSensorDataState(sensorevent.getDataTypeValue());
+            } else if (event instanceof TellstickLocalSensorEventDTO) {
+                TellstickLocalSensorEventDTO sensorevent = (TellstickLocalSensorEventDTO) event;
+                updateSensorDataState(sensorevent.getDataTypeValue());
             } else if (event instanceof TellstickSensorEvent) {
                 TellstickSensorEvent sensorevent = (TellstickSensorEvent) event;
                 updateSensorDataState(sensorevent.getDataType(), sensorevent.getData());
@@ -340,6 +358,46 @@ public class TelldusDevicesHandler extends BaseThingHandler implements DeviceSta
         }
     }
 
+    private void updateSensorDataState(LocalDataTypeValueDTO 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.getScale() == 5) {
+                    updateState(ampereChannel, new QuantityType<>(new BigDecimal(dataType.getValue()), ELECTRIC_UNIT));
+                } else if (dataType.getScale() == 2) {
+                    updateState(wattChannel, new QuantityType<>(new BigDecimal(dataType.getValue()), Units.WATT));
+                }
+                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(),
index 67dd3f95c91c86bebd49c9c779631b7cffc3201c..9340acf11340b33bad7b144642d751f1f1f2644d 100644 (file)
@@ -20,11 +20,11 @@ package org.openhab.binding.tellstick.internal.live.xml;
 public enum LiveDataType {
     HUMIDITY("humidity"),
     TEMPERATURE("temp"),
-    WINDAVERAGE("windaverage"),
-    WINDDIRECTION("winddirection"),
-    WINDGUST("windgust"),
-    RAINRATE("rainrate"),
-    RAINTOTAL("rainttotal"),
+    WINDAVERAGE("wavg"),
+    WINDDIRECTION("wdir"),
+    WINDGUST("wgust"),
+    RAINRATE("rrate"),
+    RAINTOTAL("rtot"),
     WATT("watt"),
     LUMINATION("lum"),
     UNKOWN("unkown");
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalBridgeHandler.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalBridgeHandler.java
new file mode 100644 (file)
index 0000000..d1a7dd4
--- /dev/null
@@ -0,0 +1,290 @@
+/**
+ * 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.local;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.openhab.binding.tellstick.internal.conf.TelldusLocalConfiguration;
+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.local.dto.LocalDataTypeValueDTO;
+import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalDeviceDTO;
+import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalDevicesDTO;
+import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalSensorDTO;
+import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalSensorEventDTO;
+import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalSensorsDTO;
+import org.openhab.core.cache.ExpiringCache;
+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.device.TellstickDeviceEvent;
+import org.tellstick.device.TellstickException;
+import org.tellstick.device.iface.Device;
+
+/**
+ * {@link TelldusLocalBridgeHandler} is the handler for Telldus Local API (Tellstick ZNET v1/v2) and connects it
+ * to the framework. All {@link TelldusDevicesHandler}s use the
+ * {@link TelldusLocalDeviceController} to execute the actual commands.
+ *
+ * @author Jan Gustafsson- Initial contribution
+ */
+public class TelldusLocalBridgeHandler extends BaseBridgeHandler implements TelldusBridgeHandler {
+
+    private final Logger logger = LoggerFactory.getLogger(TelldusLocalBridgeHandler.class);
+
+    private TellstickLocalDevicesDTO deviceList = null;
+    private TellstickLocalSensorsDTO sensorList = null;
+    private TelldusLocalDeviceController controller = null;
+    private List<DeviceStatusListener> deviceStatusListeners = Collections.synchronizedList(new ArrayList<>());
+    private final HttpClient httpClient;
+    private ScheduledFuture<?> pollingJob;
+    /**
+     * Use cache for refresh command to not update again when call is made within 10 seconds of previous call.
+     */
+    private final ExpiringCache<Boolean> refreshCache = new ExpiringCache<>(Duration.ofSeconds(10),
+            this::refreshDeviceList);
+
+    public TelldusLocalBridgeHandler(Bridge bridge, HttpClient httpClient) {
+        super(bridge);
+        this.httpClient = httpClient;
+    }
+
+    @Override
+    public void initialize() {
+        TelldusLocalConfiguration configuration = getConfigAs(TelldusLocalConfiguration.class);
+        this.controller = new TelldusLocalDeviceController(configuration, httpClient);
+        pollingJob = scheduler.scheduleWithFixedDelay(this::refreshDeviceList, 11, configuration.refreshInterval,
+                TimeUnit.MILLISECONDS);
+        updateStatus(ThingStatus.UNKNOWN);
+    }
+
+    @Override
+    public void dispose() {
+        if (pollingJob != null) {
+            pollingJob.cancel(true);
+        }
+        if (this.controller != null) {
+            this.controller.dispose();
+        }
+        deviceList = null;
+        sensorList = null;
+        super.dispose();
+    }
+
+    private boolean refreshDeviceList() {
+        try {
+            updateDevices(deviceList);
+            updateSensors(sensorList);
+            updateStatus(ThingStatus.ONLINE);
+            return true;
+        } catch (TellstickException | InterruptedException e) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+        }
+        return false;
+    }
+
+    private synchronized void updateDevices(TellstickLocalDevicesDTO previouslist)
+            throws TellstickException, InterruptedException {
+        TellstickLocalDevicesDTO newList = controller
+                .callRestMethod(TelldusLocalDeviceController.HTTP_LOCAL_API_DEVICES, TellstickLocalDevicesDTO.class);
+        logger.debug("Device list {}", newList.getDevices());
+        if (newList.getDevices() != null) {
+            if (previouslist == null) {
+                for (TellstickLocalDeviceDTO device : newList.getDevices()) {
+                    device.setUpdated(true);
+                    synchronized (deviceStatusListeners) {
+                        for (DeviceStatusListener listener : deviceStatusListeners) {
+                            listener.onDeviceAdded(getThing(), device);
+                        }
+                    }
+                }
+                this.deviceList = newList;
+            } else {
+                for (TellstickLocalDeviceDTO device : newList.getDevices()) {
+                    int index = previouslist.getDevices().indexOf(device);
+                    logger.debug("Device:{} found at {}", device, index);
+                    if (index >= 0) {
+                        TellstickLocalDeviceDTO 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);
+                        synchronized (deviceStatusListeners) {
+                            for (DeviceStatusListener listener : deviceStatusListeners) {
+                                listener.onDeviceAdded(getThing(), device);
+                            }
+                        }
+                    }
+                }
+            }
+
+            for (TellstickLocalDeviceDTO device : deviceList.getDevices()) {
+                if (device.isUpdated()) {
+                    synchronized (deviceStatusListeners) {
+                        for (DeviceStatusListener listener : deviceStatusListeners) {
+                            listener.onDeviceStateChanged(getThing(), device,
+                                    new TellstickDeviceEvent(device, null, null, null, System.currentTimeMillis()));
+                        }
+                    }
+                    device.setUpdated(false);
+                }
+            }
+        }
+    }
+
+    private synchronized void updateSensors(TellstickLocalSensorsDTO previouslist)
+            throws TellstickException, InterruptedException {
+        TellstickLocalSensorsDTO newList = controller
+                .callRestMethod(TelldusLocalDeviceController.HTTP_LOCAL_API_SENSORS, TellstickLocalSensorsDTO.class);
+        logger.debug("Updated sensors:{}", newList.getSensors());
+        if (newList.getSensors() != null) {
+            if (previouslist == null) {
+                this.sensorList = newList;
+                for (TellstickLocalSensorDTO sensor : sensorList.getSensors()) {
+                    sensor.setUpdated(true);
+                    synchronized (deviceStatusListeners) {
+                        for (DeviceStatusListener listener : deviceStatusListeners) {
+                            listener.onDeviceAdded(getThing(), sensor);
+                        }
+                    }
+                }
+            } else {
+                for (TellstickLocalSensorDTO sensor : previouslist.getSensors()) {
+                    sensor.setUpdated(false);
+                }
+
+                for (TellstickLocalSensorDTO sensor : newList.getSensors()) {
+                    int index = this.sensorList.getSensors().indexOf(sensor);
+                    if (index >= 0) {
+                        TellstickLocalSensorDTO orgSensor = this.sensorList.getSensors().get(index);
+                        orgSensor.setData(sensor.getData());
+                        orgSensor.setUpdated(true);
+                        sensor.setUpdated(true);
+                    } else {
+                        this.sensorList.getSensors().add(sensor);
+                        sensor.setUpdated(true);
+                        synchronized (deviceStatusListeners) {
+                            for (DeviceStatusListener listener : deviceStatusListeners) {
+                                listener.onDeviceAdded(getThing(), sensor);
+                            }
+                        }
+                    }
+                }
+            }
+            for (TellstickLocalSensorDTO sensor : sensorList.getSensors()) {
+                if (sensor.getData() != null && sensor.isUpdated()) {
+                    synchronized (deviceStatusListeners) {
+                        for (DeviceStatusListener listener : deviceStatusListeners) {
+                            for (LocalDataTypeValueDTO type : sensor.getData()) {
+                                listener.onDeviceStateChanged(getThing(), sensor,
+                                        new TellstickLocalSensorEventDTO(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) {
+            refreshCache.getValue();
+        }
+    }
+
+    @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<TellstickLocalDeviceDTO> devices) {
+        for (Device device : devices) {
+            if (device.getId() == Integer.valueOf(id)) {
+                return device;
+            }
+        }
+        return null;
+    }
+
+    private Device getSensor(String id, List<TellstickLocalSensorDTO> 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<TellstickLocalDeviceDTO> 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;
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalDeviceController.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalDeviceController.java
new file mode 100644 (file)
index 0000000..425f76e
--- /dev/null
@@ -0,0 +1,282 @@
+/**
+ * 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.local;
+
+import java.math.BigDecimal;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.http.HttpMethod;
+import org.openhab.binding.tellstick.internal.TelldusBindingException;
+import org.openhab.binding.tellstick.internal.conf.TelldusLocalConfiguration;
+import org.openhab.binding.tellstick.internal.handler.TelldusDeviceController;
+import org.openhab.binding.tellstick.internal.local.dto.TelldusLocalResponseDTO;
+import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalDeviceDTO;
+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;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+
+/**
+ * {@link TelldusLocalDeviceController} handles the communication with Telldus Local API (Tellstick ZNET v1/v2)
+ * This controller uses JSON based Rest API to communicate with Telldus Local API.
+ *
+ * @author Jan Gustafsson - Initial contribution
+ */
+public class TelldusLocalDeviceController implements DeviceChangeListener, SensorListener, TelldusDeviceController {
+    private final Logger logger = LoggerFactory.getLogger(TelldusLocalDeviceController.class);
+    private long lastSend = 0;
+    public static final long DEFAULT_INTERVAL_BETWEEN_SEND_SEC = 250;
+    static final int REQUEST_TIMEOUT_MS = 5000;
+    private final HttpClient httpClient;
+    private final Gson gson = new Gson();
+    private String localApiUrl;
+    private String authorizationHeader = "Bearer ";
+    static final String HTTP_LOCAL_API = "api/";
+    static final String HTTP_LOCAL_API_DEVICES = HTTP_LOCAL_API + "devices/list?supportedMethods=19&includeIgnored=0";
+    static final String HTTP_LOCAL_API_SENSORS = HTTP_LOCAL_API
+            + "sensors/list?includeValues=1&includeScale=1&includeUnit=1&includeIgnored=0";
+    static final String HTTP_LOCAL_API_SENSOR_INFO = HTTP_LOCAL_API + "sensor/info";
+    static final String HTTP_LOCAL_API_DEVICE_DIM = HTTP_LOCAL_API + "device/dim?id=%d&level=%d";
+    static final String HTTP_LOCAL_API_DEVICE_TURNOFF = HTTP_LOCAL_API + "device/turnOff?id=%d";
+    static final String HTTP_LOCAL_DEVICE_TURNON = HTTP_LOCAL_API + "device/turnOn?id=%d";
+    private static final int MAX_RETRIES = 3;
+
+    public TelldusLocalDeviceController(TelldusLocalConfiguration configuration, HttpClient httpClient) {
+        this.httpClient = httpClient;
+        localApiUrl = "http://" + configuration.ipAddress + "/";
+        authorizationHeader = authorizationHeader + configuration.accessToken;
+    }
+
+    @Override
+    public void dispose() {
+    }
+
+    @Override
+    public void handleSendEvent(Device device, int resendCount, boolean isdimmer, Command command)
+            throws TellstickException {
+        logger.debug("Send {} to {}", command, device);
+        try {
+            if (device instanceof TellstickLocalDeviceDTO) {
+                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.trace("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);
+            }
+        } catch (InterruptedException e) {
+            logger.debug("OH is shut-down.");
+        }
+    }
+
+    private void increaseDecrease(Device dev, IncreaseDecreaseType increaseDecreaseType)
+            throws TellstickException, InterruptedException {
+        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, InterruptedException {
+        double value = command.doubleValue();
+
+        // 0 means OFF and 100 means ON
+        if (value == 0 && dev instanceof TellstickLocalDeviceDTO) {
+            turnOff(dev);
+        } else if (value == 100 && dev instanceof TellstickLocalDeviceDTO) {
+            turnOn(dev);
+        } else if (dev instanceof TellstickLocalDeviceDTO
+                && (((TellstickLocalDeviceDTO) dev).getMethods() & JNA.CLibrary.TELLSTICK_DIM) > 0) {
+            long tdVal = Math.round((value / 100) * 255);
+            TelldusLocalResponseDTO response = callRestMethod(
+                    String.format(HTTP_LOCAL_API_DEVICE_DIM, dev.getId(), tdVal), TelldusLocalResponseDTO.class);
+            handleResponse((TellstickLocalDeviceDTO) dev, response);
+        } else {
+            throw new TelldusBindingException("Cannot send DIM to " + dev);
+        }
+    }
+
+    private void turnOff(Device dev) throws TellstickException, InterruptedException {
+        if (dev instanceof TellstickLocalDeviceDTO) {
+            TelldusLocalResponseDTO response = callRestMethod(String.format(HTTP_LOCAL_API_DEVICE_TURNOFF, dev.getId()),
+                    TelldusLocalResponseDTO.class);
+            handleResponse((TellstickLocalDeviceDTO) dev, response);
+        } else {
+            throw new TelldusBindingException("Cannot send OFF to " + dev);
+        }
+    }
+
+    private void handleResponse(TellstickLocalDeviceDTO device, TelldusLocalResponseDTO response)
+            throws TellstickException {
+        if (response == null || (response.getStatus() == null && response.getError() == null)) {
+            throw new TelldusBindingException("No response " + response);
+        } else if (response.getError() != null) {
+            device.setUpdated(true);
+            throw new TelldusBindingException("Error " + response.getError());
+        } else if (!response.getStatus().trim().equals("success")) {
+            throw new TelldusBindingException("Response " + response.getStatus());
+        }
+    }
+
+    private void turnOn(Device dev) throws TellstickException, InterruptedException {
+        if (dev instanceof TellstickLocalDeviceDTO) {
+            TelldusLocalResponseDTO response = callRestMethod(String.format(HTTP_LOCAL_DEVICE_TURNON, dev.getId()),
+                    TelldusLocalResponseDTO.class);
+            handleResponse((TellstickLocalDeviceDTO) dev, response);
+        } else {
+            throw new TelldusBindingException("Cannot send ON to " + dev);
+        }
+    }
+
+    @Override
+    public State calcState(Device dev) {
+        TellstickLocalDeviceDTO device = (TellstickLocalDeviceDTO) dev;
+        State st = null;
+
+        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 = BigDecimal.ZERO;
+        switch (((TellstickLocalDeviceDTO) 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(((TellstickLocalDeviceDTO) 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 {}", (((TellstickLocalDeviceDTO) 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 TelldusLocalException, InterruptedException {
+        T resultObj = null;
+        try {
+            for (int i = 0; i < MAX_RETRIES; i++) {
+                try {
+                    resultObj = innerCallRest(localApiUrl + uri, response);
+                    break;
+                } catch (TimeoutException e) {
+                    logger.warn("TimeoutException error in get");
+                }
+            }
+        } catch (JsonSyntaxException e) {
+            throw new TelldusLocalException(e);
+        } catch (ExecutionException e) {
+            throw new TelldusLocalException(e);
+        }
+        return resultObj;
+    }
+
+    private <T> T innerCallRest(String uri, Class<T> json)
+            throws ExecutionException, InterruptedException, TimeoutException, JsonSyntaxException {
+        logger.trace("HTTP GET: {}", uri);
+
+        Request request = httpClient.newRequest(uri).method(HttpMethod.GET);
+        request.header("Authorization", authorizationHeader);
+
+        ContentResponse response = request.send();
+        String content = response.getContentAsString();
+        logger.trace("API response: {}", content);
+
+        return gson.fromJson(content, json);
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalException.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalException.java
new file mode 100644 (file)
index 0000000..f9da540
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * 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.local;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.tellstick.device.TellstickException;
+
+/**
+ * {@link TelldusLocalException} is used when there is exception communicating with Telldus local API.
+ * This exception extends the Telldus Core exception.
+ *
+ * @author Jan Gustafsson - Initial contribution
+ */
+@NonNullByDefault
+public class TelldusLocalException extends TellstickException {
+
+    public TelldusLocalException(Exception source) {
+        super(null, 0);
+        this.initCause(source);
+    }
+
+    private static final long serialVersionUID = 3067179547449454711L;
+
+    @Override
+    public @NonNull String getMessage() {
+        Throwable throwable = getCause();
+        if (throwable != null) {
+            String localMessage = throwable.getMessage();
+            if (localMessage != null) {
+                return localMessage;
+            }
+        }
+        return "";
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/LocalDataTypeValueDTO.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/LocalDataTypeValueDTO.java
new file mode 100644 (file)
index 0000000..63bab55
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * 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.local.dto;
+
+import org.openhab.binding.tellstick.internal.live.xml.LiveDataType;
+
+/**
+ * Class used to deserialize JSON from Telldus local API.
+ *
+ * @author Jan Gustafsson - Initial contribution
+ */
+public class LocalDataTypeValueDTO {
+
+    private String name;
+    private int scale;
+    private String value;
+
+    public LiveDataType getName() {
+        return LiveDataType.fromName(name);
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getScale() {
+        return scale;
+    }
+
+    public void setScale(int scale) {
+        this.scale = scale;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TelldusLocalResponseDTO.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TelldusLocalResponseDTO.java
new file mode 100644 (file)
index 0000000..9f6d772
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ * 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.local.dto;
+
+/**
+ * Class used to deserialize JSON from Telldus local API.
+ *
+ * @author Jan Gustafsson - Initial contribution
+ */
+public class TelldusLocalResponseDTO {
+
+    private String error;
+    private String status;
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalDeviceDTO.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalDeviceDTO.java
new file mode 100644 (file)
index 0000000..7289dcd
--- /dev/null
@@ -0,0 +1,115 @@
+/**
+ * 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.local.dto;
+
+import org.tellstick.device.iface.Device;
+import org.tellstick.enums.DeviceType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Class used to deserialize JSON from Telldus local API.
+ *
+ * @author Jan Gustafsson - Initial contribution
+ */
+public class TellstickLocalDeviceDTO implements Device {
+
+    @SerializedName("id")
+    private int deviceId;
+    private int methods;
+    private String name;
+    private int state;
+    private String statevalue;
+    private String type;
+    private String protocol;
+    private String model;
+    private boolean updated;
+
+    public void setUpdated(boolean b) {
+        this.updated = b;
+    }
+
+    public boolean isUpdated() {
+        return updated;
+    }
+
+    @Override
+    public int getId() {
+        return deviceId;
+    }
+
+    public void setId(int deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public int getMethods() {
+        return methods;
+    }
+
+    public void setMethods(int methods) {
+        this.methods = methods;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @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;
+    }
+
+    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;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalDevicesDTO.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalDevicesDTO.java
new file mode 100644 (file)
index 0000000..275768d
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * 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.local.dto;
+
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Class used to deserialize JSON from Telldus local API.
+ *
+ * @author Jan Gustafsson - Initial contribution
+ */
+public class TellstickLocalDevicesDTO {
+
+    @SerializedName("device")
+    private List<TellstickLocalDeviceDTO> devices = null;
+
+    public List<TellstickLocalDeviceDTO> getDevices() {
+        return devices;
+    }
+
+    public void setDevices(List<TellstickLocalDeviceDTO> devices) {
+        this.devices = devices;
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorDTO.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorDTO.java
new file mode 100644 (file)
index 0000000..f8087fb
--- /dev/null
@@ -0,0 +1,130 @@
+/**
+ * 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.local.dto;
+
+import java.util.List;
+
+import org.openhab.binding.tellstick.internal.live.xml.LiveDataType;
+import org.tellstick.device.iface.Device;
+import org.tellstick.enums.DeviceType;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Class used to deserialize JSON from Telldus local API.
+ *
+ * @author Jan Gustafsson - Initial contribution
+ */
+public class TellstickLocalSensorDTO implements Device {
+
+    private int battery;
+    private boolean updated;
+    private List<LocalDataTypeValueDTO> data = null;
+    @SerializedName("id")
+    private int deviceId;
+    private String model;
+    private String name;
+    private String protocol;
+    private int sensorId;
+
+    public int getBattery() {
+        return battery;
+    }
+
+    public void setBattery(int battery) {
+        this.battery = battery;
+    }
+
+    public List<LocalDataTypeValueDTO> getData() {
+        return data;
+    }
+
+    public void setData(List<LocalDataTypeValueDTO> data) {
+        this.data = data;
+    }
+
+    @Override
+    public int getId() {
+        return deviceId;
+    }
+
+    public void setId(int id) {
+        this.deviceId = id;
+    }
+
+    @Override
+    public String getModel() {
+        return model;
+    }
+
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    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 (LocalDataTypeValueDTO val : data) {
+                if (val.getName() == type) {
+                    res = true;
+                    break;
+                }
+            }
+        }
+        return res;
+    }
+
+    @Override
+    public DeviceType getDeviceType() {
+        return DeviceType.SENSOR;
+    }
+
+    public int getSensorId() {
+        return sensorId;
+    }
+
+    public void setSensorId(int sensorId) {
+        this.sensorId = sensorId;
+    }
+
+    @Override
+    public String getUUId() {
+        return Integer.toString(deviceId);
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorEventDTO.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorEventDTO.java
new file mode 100644 (file)
index 0000000..39e6744
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * 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.local.dto;
+
+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 Jan Gustafsson - Initial contribution
+ */
+public class TellstickLocalSensorEventDTO extends TellstickSensorEvent implements TellstickEvent {
+
+    private LocalDataTypeValueDTO dataType;
+
+    public TellstickLocalSensorEventDTO(int sensorId, String data, LocalDataTypeValueDTO dataValue, String protocol,
+            String model, long timeStamp) {
+        super(sensorId, data, null, protocol, model, timeStamp);
+        this.dataType = dataValue;
+    }
+
+    public LocalDataTypeValueDTO getDataTypeValue() {
+        return dataType;
+    }
+
+    @Override
+    public DataType getDataType() {
+        throw new TellstickRuntimeException("Should not call this method");
+    }
+}
diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorsDTO.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/dto/TellstickLocalSensorsDTO.java
new file mode 100644 (file)
index 0000000..ff6e64f
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * 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.local.dto;
+
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Class used to deserialize JSON from Telldus local API.
+ *
+ * @author Jan Gustafsson - Initial contribution
+ */
+public class TellstickLocalSensorsDTO {
+
+    @SerializedName("sensor")
+    private List<TellstickLocalSensorDTO> sensors = null;
+
+    public List<TellstickLocalSensorDTO> getSensors() {
+        return sensors;
+    }
+
+    public void setSensors(List<TellstickLocalSensorDTO> sensors) {
+        this.sensors = sensors;
+    }
+}
index da1ca16a0d627ef1b6c478c66cfba7809ff635b7..11f8e2b091fc7ee435ee406befe322010716bb97 100644 (file)
@@ -6,7 +6,7 @@
 
        <bridge-type id="telldus-core">
                <label>Telldus Core Gateway</label>
-               <description>This bridge represents the telldus center on a local computer.</description>
+               <description>This bridge represents the Telldus center on a local computer.</description>
 
                <config-description>
                        <parameter name="libraryPath" type="text" required="false">
@@ -25,7 +25,7 @@
        </bridge-type>
        <bridge-type id="telldus-live">
                <label>Telldus Live Gateway</label>
-               <description>This bridge represents the telldus live cloud service.</description>
+               <description>This bridge represents the Telldus live cloud service.</description>
 
                <config-description>
                        <parameter name="privateKey" type="text" required="true">
                                <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>
@@ -48,7 +46,7 @@
                                <label>Token Secret</label>
                                <description>The openauth token secret.</description>
                        </parameter>
-                       <parameter name="refreshInterval" type="integer" required="false">
+                       <parameter name="refreshInterval" type="integer" required="false" min="0" unit="ms">
                                <label>Refresh Interval</label>
                                <description>The refresh interval in ms which is used to poll Telldus Live.
                                </description>
                </config-description>
 
        </bridge-type>
+       <bridge-type id="telldus-local">
+               <label>Telldus Local API</label>
+               <description>This bridge represents the Telldus local API.</description>
+
+               <config-description>
+                       <parameter name="ipAddress" type="text" required="true">
+                               <label>Local IP Address</label>
+                               <description>The local IP address of the Tellstick.</description>
+                               <context>network-address</context>
+                       </parameter>
+                       <parameter name="accessToken" type="text" required="true">
+                               <label>Access Token</label>
+                               <description>The access token.</description>
+                       </parameter>
+                       <parameter name="refreshInterval" type="integer" required="false" min="0" unit="ms">
+                               <label>Refresh Interval</label>
+                               <description>The refresh interval in ms which is used to poll Telldus local API.
+                               </description>
+                               <default>60000</default>
+                       </parameter>
+               </config-description>
+
+       </bridge-type>
 </thing:thing-descriptions>
index 3e2fa9f1bc596fd7103166e317790b9c3b966dcc..f51e8f2d9d7f3175e1f315a01376f3da00e4ceeb 100644 (file)
@@ -9,6 +9,7 @@
                <supported-bridge-type-refs>
                        <bridge-type-ref id="telldus-core"/>
                        <bridge-type-ref id="telldus-live"/>
+                       <bridge-type-ref id="telldus-local"/>
                </supported-bridge-type-refs>
 
                <label>Dimmable Device</label>
index 4a598a43244eca1454de1f7290b1d8320c4b6adc..5e1820371b896dfe2999eccc992cb5b4f5c264b4 100644 (file)
@@ -8,6 +8,7 @@
                <supported-bridge-type-refs>
                        <bridge-type-ref id="telldus-core"/>
                        <bridge-type-ref id="telldus-live"/>
+                       <bridge-type-ref id="telldus-local"/>
                </supported-bridge-type-refs>
 
                <label>Sensor</label>
                <item-type>Number:Length</item-type>
                <label>Rainrate</label>
                <description>The current rain rate</description>
-               <state pattern="%d %unit%" readOnly="true"/>
+               <state pattern="%.1f %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 pattern="%.1f %unit%" readOnly="true">
                </state>
        </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%">
+               <label>Power</label>
+               <description>Current power</description>
+               <state readOnly="true" pattern="%.1f %unit%">
                </state>
        </channel-type>