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.bigassfan.internal.discovery;
15 import static org.openhab.binding.bigassfan.internal.BigAssFanBindingConstants.*;
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;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * The {@link DiscoveryListener} is responsible for listening on the UDP socket for fan discovery messages.
32 * @author Mark Hilbush - Initial contribution
34 public class DiscoveryListener {
35 private final Logger logger = LoggerFactory.getLogger(DiscoveryListener.class);
37 private final String BCAST_ADDRESS = "255.255.255.255";
38 private final int SOCKET_RECEIVE_TIMEOUT = 500;
40 private final String POLL_MESSAGE = "<ALL;DEVICE;ID;GET>";
42 DatagramSocket dSocket;
43 DatagramPacket rcvPacket;
45 InetAddress bcastAddress;
47 DatagramPacket bcastPacket;
49 BigAssFanDevice device;
51 public DiscoveryListener() throws IOException, SocketException {
52 logger.debug("DiscoveryListener opening UDP broadcast socket");
54 device = new BigAssFanDevice();
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);
72 public BigAssFanDevice waitForMessage() throws IOException, SocketTimeoutException {
73 // Wait to receive a packet
74 rcvPacket.setLength(rcvBuffer.length);
75 dSocket.receive(rcvPacket);
77 // Process the received packet
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);
87 public void pollForDevices() {
88 if (dSocket == null) {
89 logger.debug("Socket is null in discoveryListener.pollForDevices()");
93 logger.debug("Sending poll request for fans: {}", POLL_MESSAGE);
95 dSocket.send(bcastPacket);
96 } catch (IOException ioe) {
97 logger.warn("IOException sending poll request for fans: {}", ioe.getMessage(), ioe);
101 public void shutdown() {
102 logger.debug("DiscoveryListener closing socket");
103 if (dSocket != null) {