]> git.basschouten.com Git - openhab-addons.git/blob
06fe455082233daa87bd6b6fb3f6009cb24ed3cf
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.bigassfan.internal.discovery;
14
15 import static org.openhab.binding.bigassfan.internal.BigAssFanBindingConstants.*;
16
17 import java.io.IOException;
18 import java.io.UnsupportedEncodingException;
19 import java.net.DatagramPacket;
20 import java.net.DatagramSocket;
21 import java.net.InetAddress;
22 import java.net.SocketException;
23 import java.net.SocketTimeoutException;
24 import java.net.UnknownHostException;
25
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * The {@link DiscoveryListener} is responsible for listening on the UDP socket for fan discovery messages.
31  *
32  * @author Mark Hilbush - Initial contribution
33  */
34 public class DiscoveryListener {
35     private final Logger logger = LoggerFactory.getLogger(DiscoveryListener.class);
36
37     private final String BCAST_ADDRESS = "255.255.255.255";
38     private final int SOCKET_RECEIVE_TIMEOUT = 500;
39
40     private final String POLL_MESSAGE = "<ALL;DEVICE;ID;GET>";
41
42     DatagramSocket dSocket;
43     DatagramPacket rcvPacket;
44     byte[] rcvBuffer;
45     InetAddress bcastAddress;
46     byte[] bcastBuffer;
47     DatagramPacket bcastPacket;
48
49     BigAssFanDevice device;
50
51     public DiscoveryListener() throws IOException, SocketException {
52         logger.debug("DiscoveryListener opening UDP broadcast socket");
53         dSocket = null;
54         device = new BigAssFanDevice();
55         try {
56             // Create a socket on the UDP port and get send & receive buffers
57             dSocket = new DatagramSocket(BAF_PORT);
58             dSocket.setSoTimeout(SOCKET_RECEIVE_TIMEOUT);
59             dSocket.setBroadcast(true);
60             rcvBuffer = new byte[256];
61             rcvPacket = new DatagramPacket(rcvBuffer, rcvBuffer.length);
62             bcastAddress = InetAddress.getByName(BCAST_ADDRESS);
63             bcastBuffer = POLL_MESSAGE.getBytes(CHARSET);
64             bcastPacket = new DatagramPacket(bcastBuffer, bcastBuffer.length, bcastAddress, BAF_PORT);
65         } catch (UnknownHostException uhe) {
66             logger.warn("UnknownHostException sending poll request for fans: {}", uhe.getMessage(), uhe);
67         } catch (UnsupportedEncodingException e) {
68             logger.warn("Unable to convert buffer to string using {} charset", CHARSET, e);
69         }
70     }
71
72     public BigAssFanDevice waitForMessage() throws IOException, SocketTimeoutException {
73         // Wait to receive a packet
74         rcvPacket.setLength(rcvBuffer.length);
75         dSocket.receive(rcvPacket);
76
77         // Process the received packet
78         device.reset();
79         device.setIpAddress(rcvPacket.getAddress().getHostAddress());
80         String message = (new String(rcvBuffer, 0, rcvPacket.getLength()));
81         device.setDiscoveryMessage(message);
82         logger.debug("RECEIVED packet of length {} from {}: {}", message.length(), device.getIpAddress(), message);
83
84         return device;
85     }
86
87     public void pollForDevices() {
88         if (dSocket == null) {
89             logger.debug("Socket is null in discoveryListener.pollForDevices()");
90             return;
91         }
92
93         logger.debug("Sending poll request for fans: {}", POLL_MESSAGE);
94         try {
95             dSocket.send(bcastPacket);
96         } catch (IOException ioe) {
97             logger.warn("IOException sending poll request for fans: {}", ioe.getMessage(), ioe);
98         }
99     }
100
101     public void shutdown() {
102         logger.debug("DiscoveryListener closing socket");
103         if (dSocket != null) {
104             dSocket.close();
105             dSocket = null;
106         }
107     }
108 }