]> git.basschouten.com Git - openhab-addons.git/blob
048ba30ef3b6e5aeb628d0348c000d3887e5c2d6
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.touchwand.internal.discovery;
14
15 import static org.openhab.binding.touchwand.internal.TouchWandBindingConstants.THING_TYPE_BRIDGE;
16
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;
24 import java.util.Map;
25
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;
37
38 import com.google.gson.JsonObject;
39 import com.google.gson.JsonParser;
40 import com.google.gson.JsonSyntaxException;
41
42 /**
43  * The {@link TouchWandControllerDiscoveryService} Discovery service for Touchwand Controllers.
44  *
45  * @author Roie Geron - Initial contribution
46  */
47 @Component(service = DiscoveryService.class, configurationPid = "discovery.touchwand")
48 @NonNullByDefault
49 public class TouchWandControllerDiscoveryService extends AbstractDiscoveryService {
50
51     private static final int SEARCH_TIME_SEC = 2;
52     private static final int TOUCHWAND_BCAST_PORT = 35000;
53     private final Logger logger = LoggerFactory.getLogger(TouchWandControllerDiscoveryService.class);
54
55     private @Nullable Thread socketReceiveThread = null;
56     private DatagramSocket listenSocket;
57
58     public TouchWandControllerDiscoveryService() throws SocketException {
59         super(TouchWandBridgeHandler.SUPPORTED_THING_TYPES, SEARCH_TIME_SEC, true);
60
61         listenSocket = new DatagramSocket(TOUCHWAND_BCAST_PORT);
62     }
63
64     @Override
65     protected void startScan() {
66         DatagramSocket localListenSocket = listenSocket;
67         runReceiveThread(localListenSocket);
68     }
69
70     @Override
71     protected void stopScan() {
72         super.stopScan();
73     }
74
75     @Override
76     public void activate(@Nullable Map<String, Object> configProperties) {
77         removeOlderResults(getTimestampOfLastScan());
78         super.activate(configProperties);
79     }
80
81     @Override
82     public void deactivate() {
83         Thread mySocketReceiveThread = socketReceiveThread;
84         if (mySocketReceiveThread != null) {
85             mySocketReceiveThread.interrupt();
86             socketReceiveThread = null;
87         }
88
89         listenSocket.close();
90         super.deactivate();
91     }
92
93     private void addDeviceDiscoveryResult(String label, String ip) {
94         String id = ip.replace(".", "");
95         ThingUID thingUID = new ThingUID(THING_TYPE_BRIDGE, id);
96         Map<String, Object> properties = new HashMap<>();
97         properties.put("label", label);
98         properties.put("ipAddress", ip);
99         // @formatter:off
100         logger.debug("Add new Bridge label:{} id {} ",label, id);
101         thingDiscovered(DiscoveryResultBuilder.create(thingUID)
102                 .withThingType(THING_TYPE_BRIDGE)
103                 .withLabel(label)
104                 .withProperties(properties)
105                 .withRepresentationProperty("ipAddress")
106                 .build()
107         );
108         // @formatter:on
109     }
110
111     protected void runReceiveThread(DatagramSocket socket) {
112         Thread localSocketReceivedThread = socketReceiveThread = new ReceiverThread(socket);
113         localSocketReceivedThread.setName(TouchWandBindingConstants.DISCOVERY_THREAD_ID);
114         localSocketReceivedThread.setDaemon(true);
115         localSocketReceivedThread.start();
116     }
117
118     private class ReceiverThread extends Thread {
119
120         private static final int BUFFER_LENGTH = 256;
121         private DatagramPacket dgram = new DatagramPacket(new byte[BUFFER_LENGTH], BUFFER_LENGTH);
122         private DatagramSocket mySocket;
123
124         public ReceiverThread(DatagramSocket socket) {
125             mySocket = socket;
126         }
127
128         @Override
129         public void run() {
130             receiveData(dgram);
131         }
132
133         private void receiveData(DatagramPacket datagram) {
134             try {
135                 while (!isInterrupted()) {
136                     mySocket.receive(datagram);
137                     InetAddress address = datagram.getAddress();
138                     String sentence = new String(dgram.getData(), 0, dgram.getLength(), StandardCharsets.US_ASCII);
139                     JsonObject bridge = JsonParser.parseString(sentence).getAsJsonObject();//
140                     String name = bridge.get("name").getAsString();
141                     addDeviceDiscoveryResult(name, address.getHostAddress());
142                     logger.debug("Received Datagram from {}:{} on Port {} message {}", address.getHostAddress(),
143                             dgram.getPort(), mySocket.getLocalPort(), sentence);
144                 }
145             } catch (IOException | JsonSyntaxException e) {
146                 if (!isInterrupted()) {
147                     logger.debug("Error while receiving {}", e.getMessage());
148                 } else {
149                     logger.debug("Receiver thread was interrupted {}", e.getMessage());
150                 }
151             }
152         }
153     }
154 }