[tellstick] Fix for #9841, adding support for Tellstick local API. (#10020)

* Fix for #9841.

Signed-off-by: Jan Gustafsson <jannegpriv@gmail.com>
This commit is contained in:
Jan Gustafsson
2021-02-18 09:33:22 +01:00
committed by GitHub
parent 8a4b87e04e
commit 0853aa7cea
22 changed files with 1317 additions and 68 deletions

View 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);
}

View 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 {

View 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
*/

View File

@@ -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;
}

View 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;
}

View 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(),

View 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");

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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 "";
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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");
}
}

View File

@@ -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;
}
}

View 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">
@@ -34,12 +34,10 @@
<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>
@@ -57,4 +55,27 @@
</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>

View 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>

View 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>
@@ -91,14 +92,14 @@
<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>
@@ -126,9 +127,9 @@
<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>