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