]> git.basschouten.com Git - openhab-addons.git/blob
842eb47b89c2df3d85005cf34d302af5c0eaff60
[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.BAF_PORT;
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.net.SocketTimeoutException;
23 import java.net.UnknownHostException;
24 import java.nio.charset.StandardCharsets;
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(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);
67         }
68     }
69
70     public BigAssFanDevice waitForMessage() throws IOException, SocketTimeoutException {
71         // Wait to receive a packet
72         rcvPacket.setLength(rcvBuffer.length);
73         dSocket.receive(rcvPacket);
74
75         // Process the received packet
76         device.reset();
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);
81
82         return device;
83     }
84
85     public void pollForDevices() {
86         if (dSocket == null) {
87             logger.debug("Socket is null in discoveryListener.pollForDevices()");
88             return;
89         }
90
91         logger.debug("Sending poll request for fans: {}", POLL_MESSAGE);
92         try {
93             dSocket.send(bcastPacket);
94         } catch (IOException ioe) {
95             logger.warn("IOException sending poll request for fans: {}", ioe.getMessage(), ioe);
96         }
97     }
98
99     public void shutdown() {
100         logger.debug("DiscoveryListener closing socket");
101         if (dSocket != null) {
102             dSocket.close();
103             dSocket = null;
104         }
105     }
106 }