2 * Copyright (c) 2010-2020 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
14 package org.openhab.binding.touchwand.internal.discovery;
16 import static org.openhab.binding.touchwand.internal.TouchWandBindingConstants.THING_TYPE_BRIDGE;
18 import java.io.IOException;
19 import java.net.DatagramPacket;
20 import java.net.DatagramSocket;
21 import java.net.InetAddress;
22 import java.net.SocketException;
23 import java.nio.charset.StandardCharsets;
24 import java.util.HashMap;
27 import org.eclipse.jdt.annotation.NonNullByDefault;
28 import org.eclipse.jdt.annotation.Nullable;
29 import org.openhab.binding.touchwand.internal.TouchWandBindingConstants;
30 import org.openhab.binding.touchwand.internal.TouchWandBridgeHandler;
31 import org.openhab.core.config.discovery.AbstractDiscoveryService;
32 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
33 import org.openhab.core.config.discovery.DiscoveryService;
34 import org.openhab.core.thing.ThingUID;
35 import org.osgi.service.component.annotations.Component;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * The {@link TouchWandControllerDiscoveryService} Discovery service for Touchwand Controllers.
42 * @author Roie Geron - Initial contribution
44 @Component(service = DiscoveryService.class, configurationPid = "discovery.touchwand")
46 public class TouchWandControllerDiscoveryService extends AbstractDiscoveryService {
48 private static final int SEARCH_TIME_SEC = 2;
49 private static final int TOUCHWAND_BCAST_PORT = 35000;
50 private final Logger logger = LoggerFactory.getLogger(TouchWandControllerDiscoveryService.class);
52 private @Nullable Thread socketReceiveThread = null;
53 private DatagramSocket listenSocket;
55 public TouchWandControllerDiscoveryService() throws SocketException {
56 super(TouchWandBridgeHandler.SUPPORTED_THING_TYPES, SEARCH_TIME_SEC, true);
58 listenSocket = new DatagramSocket(TOUCHWAND_BCAST_PORT);
62 protected void startScan() {
63 DatagramSocket localListenSocket = listenSocket;
64 runReceiveThread(localListenSocket);
68 protected void stopScan() {
73 public void activate(@Nullable Map<String, @Nullable Object> configProperties) {
74 removeOlderResults(getTimestampOfLastScan());
75 super.activate(configProperties);
79 public void deactivate() {
80 Thread mySocketReceiveThread = socketReceiveThread;
81 if (mySocketReceiveThread != null) {
82 mySocketReceiveThread.interrupt();
83 socketReceiveThread = null;
90 private void addDeviceDiscoveryResult(String label, String ip) {
91 String id = ip.replaceAll("\\.", "");
92 ThingUID thingUID = new ThingUID(THING_TYPE_BRIDGE, id);
93 Map<String, Object> properties = new HashMap<>();
94 properties.put("label", label);
95 properties.put("ipAddress", ip);
97 logger.debug("Add new Bridge label:{} id {} ",label, id);
98 thingDiscovered(DiscoveryResultBuilder.create(thingUID)
99 .withThingType(THING_TYPE_BRIDGE)
101 .withProperties(properties)
102 .withRepresentationProperty("ipAddress")
108 protected void runReceiveThread(DatagramSocket socket) {
109 Thread localSocketReceivedThread = socketReceiveThread = new ReceiverThread(socket);
110 localSocketReceivedThread.setName(TouchWandBindingConstants.DISCOVERY_THREAD_ID);
111 localSocketReceivedThread.setDaemon(true);
112 localSocketReceivedThread.start();
115 private class ReceiverThread extends Thread {
117 private static final int BUFFER_LENGTH = 256;
118 private DatagramPacket dgram = new DatagramPacket(new byte[BUFFER_LENGTH], BUFFER_LENGTH);
119 private DatagramSocket mySocket;
121 public ReceiverThread(DatagramSocket socket) {
130 private void receiveData(DatagramPacket datagram) {
132 while (!isInterrupted()) {
133 mySocket.receive(datagram);
134 InetAddress address = datagram.getAddress();
135 String sentence = new String(dgram.getData(), 0, dgram.getLength(), StandardCharsets.US_ASCII);
136 addDeviceDiscoveryResult(sentence, address.getHostAddress().toString());
137 logger.debug("Received Datagram from {}:{} on Port {} message {}", address.getHostAddress(),
138 dgram.getPort(), mySocket.getLocalPort(), sentence);
140 } catch (IOException e) {
141 if (!isInterrupted()) {
142 logger.warn("Error while receiving {}", e.getMessage());
144 logger.debug("Receiver thread was interrupted {}", e.getMessage());