2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.tellstick.internal.discovery;
15 import java.util.List;
17 import java.util.Vector;
19 import org.openhab.binding.tellstick.internal.TellstickBindingConstants;
20 import org.openhab.binding.tellstick.internal.handler.DeviceStatusListener;
21 import org.openhab.binding.tellstick.internal.handler.TelldusBridgeHandler;
22 import org.openhab.binding.tellstick.internal.live.xml.LiveDataType;
23 import org.openhab.binding.tellstick.internal.live.xml.TellstickNetDevice;
24 import org.openhab.binding.tellstick.internal.live.xml.TellstickNetSensor;
25 import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalDeviceDTO;
26 import org.openhab.binding.tellstick.internal.local.dto.TellstickLocalSensorDTO;
27 import org.openhab.core.config.discovery.AbstractDiscoveryService;
28 import org.openhab.core.config.discovery.DiscoveryResult;
29 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
30 import org.openhab.core.thing.Bridge;
31 import org.openhab.core.thing.ThingTypeUID;
32 import org.openhab.core.thing.ThingUID;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import org.tellstick.JNA;
36 import org.tellstick.device.TellstickSensor;
37 import org.tellstick.device.iface.Device;
38 import org.tellstick.device.iface.DimmableDevice;
39 import org.tellstick.device.iface.SwitchableDevice;
40 import org.tellstick.device.iface.TellstickEvent;
41 import org.tellstick.enums.DataType;
44 * The {@link TellstickDiscoveryService} class is used to discover Tellstick
45 * devices that are connected to the Lan gateway.
47 * @author Jarle Hjortland - Initial contribution
49 public class TellstickDiscoveryService extends AbstractDiscoveryService implements DeviceStatusListener {
50 private static final long DEFAULT_TTL = 60 * 60; // 1 Hour
52 public TellstickDiscoveryService(int timeout) throws IllegalArgumentException {
56 private final Logger logger = LoggerFactory.getLogger(TellstickDiscoveryService.class);
58 private List<TelldusBridgeHandler> telldusBridgeHandlers = new Vector<>();
60 public TellstickDiscoveryService(TelldusBridgeHandler telldusBridgeHandler) {
61 super(TellstickBindingConstants.SUPPORTED_DEVICE_THING_TYPES_UIDS, 10, true);
62 this.telldusBridgeHandlers.add(telldusBridgeHandler);
65 public void activate() {
66 for (TelldusBridgeHandler telldusBridgeHandler : telldusBridgeHandlers) {
67 telldusBridgeHandler.registerDeviceStatusListener(this);
72 public void deactivate() {
73 for (TelldusBridgeHandler telldusBridgeHandler : telldusBridgeHandlers) {
74 telldusBridgeHandler.unregisterDeviceStatusListener(this);
79 public Set<ThingTypeUID> getSupportedThingTypes() {
80 return TellstickBindingConstants.SUPPORTED_DEVICE_THING_TYPES_UIDS;
84 public void onDeviceAdded(Bridge bridge, Device device) {
85 logger.debug("Adding new TellstickDevice! '{}' with id '{}' and type '{}' to inbox", device, device.getId(),
86 device.getDeviceType());
87 ThingUID thingUID = getThingUID(bridge, device);
88 logger.debug("Detected thingUID: {}", thingUID);
89 if (thingUID != null) {
90 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withTTL(DEFAULT_TTL)
91 .withProperty(TellstickBindingConstants.DEVICE_ID, device.getUUId())
92 .withProperty(TellstickBindingConstants.DEVICE_NAME, device.getName()).withBridge(bridge.getUID())
93 .withLabel(device.getDeviceType() + ": " + device.getName()).build();
94 thingDiscovered(discoveryResult);
96 logger.warn("Discovered Tellstick! device is unsupported: type '{}' with id '{}'", device.getDeviceType(),
102 protected void startScan() {
103 for (TelldusBridgeHandler telldusBridgeHandler : telldusBridgeHandlers) {
104 telldusBridgeHandler.rescanTelldusDevices();
109 public void onDeviceStateChanged(Bridge bridge, Device device, TellstickEvent event) {
110 // this can be ignored here
114 public void onDeviceRemoved(Bridge bridge, Device device) {
115 ThingUID thingUID = getThingUID(bridge, device);
116 if (thingUID != null) {
117 thingRemoved(thingUID);
119 logger.warn("Removed Tellstick! device is unsupported: type '{}' with id '{}'", device.getDeviceType(),
124 private ThingUID getThingUID(Bridge bridge, Device device) {
125 ThingUID thingUID = null;
126 switch (device.getDeviceType()) {
128 ThingTypeUID sensorThingId = findSensorType(device);
129 thingUID = new ThingUID(sensorThingId, bridge.getUID(), device.getUUId());
132 if (device instanceof DimmableDevice) {
133 thingUID = new ThingUID(TellstickBindingConstants.DIMMER_THING_TYPE, bridge.getUID(),
135 } else if (device instanceof SwitchableDevice) {
136 thingUID = new ThingUID(TellstickBindingConstants.SWITCH_THING_TYPE, bridge.getUID(),
138 } else if (device instanceof TellstickNetDevice netDevice) {
139 if ((netDevice.getMethods() & JNA.CLibrary.TELLSTICK_DIM) > 0) {
140 thingUID = new ThingUID(TellstickBindingConstants.DIMMER_THING_TYPE, bridge.getUID(),
143 thingUID = new ThingUID(TellstickBindingConstants.SWITCH_THING_TYPE, bridge.getUID(),
146 } else if (device instanceof TellstickLocalDeviceDTO localDevice) {
147 if ((localDevice.getMethods() & JNA.CLibrary.TELLSTICK_DIM) > 0) {
148 thingUID = new ThingUID(TellstickBindingConstants.DIMMER_THING_TYPE, bridge.getUID(),
151 thingUID = new ThingUID(TellstickBindingConstants.SWITCH_THING_TYPE, bridge.getUID(),
162 private ThingTypeUID findSensorType(Device device) {
163 logger.debug("Device: {}", device);
164 ThingTypeUID sensorThingId;
165 if (device instanceof TellstickSensor sensor) {
166 logger.debug("Sensor: {}", device);
167 if (sensor.getData(DataType.WINDAVERAGE) != null || sensor.getData(DataType.WINDGUST) != null
168 || sensor.getData(DataType.WINDDIRECTION) != null) {
169 sensorThingId = TellstickBindingConstants.WINDSENSOR_THING_TYPE;
170 } else if (sensor.getData(DataType.RAINTOTAL) != null || sensor.getData(DataType.RAINRATE) != null) {
171 sensorThingId = TellstickBindingConstants.RAINSENSOR_THING_TYPE;
173 sensorThingId = TellstickBindingConstants.SENSOR_THING_TYPE;
175 } else if (device instanceof TellstickNetSensor sensor) {
176 if (sensor.isSensorOfType(LiveDataType.WINDAVERAGE) || sensor.isSensorOfType(LiveDataType.WINDDIRECTION)
177 || sensor.isSensorOfType(LiveDataType.WINDGUST)) {
178 sensorThingId = TellstickBindingConstants.WINDSENSOR_THING_TYPE;
179 } else if (sensor.isSensorOfType(LiveDataType.RAINRATE) || sensor.isSensorOfType(LiveDataType.RAINTOTAL)) {
180 sensorThingId = TellstickBindingConstants.RAINSENSOR_THING_TYPE;
181 } else if (sensor.isSensorOfType(LiveDataType.WATT)) {
182 sensorThingId = TellstickBindingConstants.POWERSENSOR_THING_TYPE;
184 sensorThingId = TellstickBindingConstants.SENSOR_THING_TYPE;
187 TellstickLocalSensorDTO sensor = (TellstickLocalSensorDTO) device;
188 if (sensor.isSensorOfType(LiveDataType.WINDAVERAGE) || sensor.isSensorOfType(LiveDataType.WINDDIRECTION)
189 || sensor.isSensorOfType(LiveDataType.WINDGUST)) {
190 sensorThingId = TellstickBindingConstants.WINDSENSOR_THING_TYPE;
191 } else if (sensor.isSensorOfType(LiveDataType.RAINRATE) || sensor.isSensorOfType(LiveDataType.RAINTOTAL)) {
192 sensorThingId = TellstickBindingConstants.RAINSENSOR_THING_TYPE;
193 } else if (sensor.isSensorOfType(LiveDataType.WATT)) {
194 sensorThingId = TellstickBindingConstants.POWERSENSOR_THING_TYPE;
196 sensorThingId = TellstickBindingConstants.SENSOR_THING_TYPE;
199 return sensorThingId;
202 public void addBridgeHandler(TelldusBridgeHandler tellstickBridgeHandler) {
203 telldusBridgeHandlers.add(tellstickBridgeHandler);
204 tellstickBridgeHandler.registerDeviceStatusListener(this);
207 public void removeBridgeHandler(TelldusBridgeHandler tellstickBridgeHandler) {
208 telldusBridgeHandlers.remove(tellstickBridgeHandler);
209 tellstickBridgeHandler.unregisterDeviceStatusListener(this);
212 public boolean isOnlyForOneBridgeHandler() {
213 return telldusBridgeHandlers.size() == 1;