2 * Copyright (c) 2010-2022 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.BAF_PORT;
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.net.SocketTimeoutException;
23 import java.net.UnknownHostException;
24 import java.nio.charset.StandardCharsets;
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(StandardCharsets.US_ASCII);
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);
70 public BigAssFanDevice waitForMessage() throws IOException, SocketTimeoutException {
71 // Wait to receive a packet
72 rcvPacket.setLength(rcvBuffer.length);
73 dSocket.receive(rcvPacket);
75 // Process the received packet
77 device.setIpAddress(rcvPacket.getAddress().getHostAddress());
78 String message = (new String(rcvBuffer, 0, rcvPacket.getLength()));
79 device.setDiscoveryMessage(message);
80 logger.debug("RECEIVED packet of length {} from {}: {}", message.length(), device.getIpAddress(), message);
85 public void pollForDevices() {
86 if (dSocket == null) {
87 logger.debug("Socket is null in discoveryListener.pollForDevices()");
91 logger.debug("Sending poll request for fans: {}", POLL_MESSAGE);
93 dSocket.send(bcastPacket);
94 } catch (IOException ioe) {
95 logger.warn("IOException sending poll request for fans: {}", ioe.getMessage(), ioe);
99 public void shutdown() {
100 logger.debug("DiscoveryListener closing socket");
101 if (dSocket != null) {