[epsonprojector] Fix discovery service to prevent erroneous inbox items (#12586)

* Fix discovery service to prevent erroneous inbox items
* improve EPSON string matching

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
This commit is contained in:
mlobstein 2022-04-09 09:10:36 -05:00 committed by GitHub
parent 0370ac61ba
commit 7613cbcd76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 69 deletions

View File

@ -16,7 +16,6 @@ import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingC
import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;
@ -115,31 +114,27 @@ public class EpsonProjectorDiscoveryService extends AbstractDiscoveryService {
}
while (!terminate) {
boolean beaconReceived;
try {
// Wait for a discovery beacon.
beaconReceived = epsonMulticastListener.waitForBeacon();
} catch (IOException ioe) {
logger.debug("Discovery job got exception waiting for beacon: {}", ioe.getMessage());
beaconReceived = false;
}
// Wait for a discovery beacon to return properties for an Epson projector.
Map<String, Object> thingProperties = epsonMulticastListener.waitForBeacon();
if (beaconReceived) {
// We got a discovery beacon. Process it as a potential new thing
Map<String, Object> properties = new HashMap<>();
String uid = epsonMulticastListener.getUID();
if (thingProperties != null) {
// The MulticastListener found a projector, add it as new thing
String uid = (String) thingProperties.get(THING_PROPERTY_MAC);
String ipAddress = (String) thingProperties.get(THING_PROPERTY_HOST);
properties.put(THING_PROPERTY_HOST, epsonMulticastListener.getIPAddress());
properties.put(THING_PROPERTY_PORT, DEFAULT_PORT);
logger.trace("Projector with UID {} discovered at IP: {}", uid, epsonMulticastListener.getIPAddress());
if (uid != null) {
logger.trace("Projector with UID {} discovered at IP: {}", uid, ipAddress);
ThingUID thingUid = new ThingUID(THING_TYPE_PROJECTOR_TCP, uid);
logger.trace("Creating epson projector discovery result for: {}, IP={}", uid,
epsonMulticastListener.getIPAddress());
thingDiscovered(DiscoveryResultBuilder.create(thingUid).withProperties(properties)
.withLabel("Epson Projector " + uid).withProperty(THING_PROPERTY_MAC, uid)
.withRepresentationProperty(THING_PROPERTY_MAC).build());
logger.trace("Creating epson projector discovery result for: {}, IP={}", uid, ipAddress);
thingDiscovered(DiscoveryResultBuilder.create(thingUid).withProperties(thingProperties)
.withLabel("Epson Projector " + uid).withRepresentationProperty(THING_PROPERTY_MAC)
.build());
}
}
} catch (IOException ioe) {
logger.debug("Discovery job got exception waiting for beacon: {}", ioe.getMessage());
}
}
epsonMulticastListener.shutdown();

View File

@ -12,6 +12,11 @@
*/
package org.openhab.binding.epsonprojector.internal.discovery;
import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingConstants.DEFAULT_PORT;
import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingConstants.THING_PROPERTY_HOST;
import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingConstants.THING_PROPERTY_MAC;
import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingConstants.THING_PROPERTY_PORT;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
@ -20,8 +25,12 @@ import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,10 +47,6 @@ public class MulticastListener {
private MulticastSocket socket;
// Epson-specific properties defined in this binding
private String uid = "";
private String ipAddress = "";
// Epson projector devices announce themselves on a multicast port
private static final String EPSON_MULTICAST_GROUP = "239.255.250.250";
private static final int EPSON_MULTICAST_PORT = 9131;
@ -70,10 +75,10 @@ public class MulticastListener {
}
/*
* Wait on the multicast socket for an announcement beacon. Return false on socket timeout or error.
* Otherwise, parse the beacon for information about the device.
* Wait on the multicast socket for an announcement beacon. Return null on socket timeout or error.
* Otherwise, parse the beacon for information about the device and return the device properties.
*/
public boolean waitForBeacon() throws IOException {
public @Nullable Map<String, Object> waitForBeacon() throws IOException {
byte[] bytes = new byte[600];
boolean beaconFound;
@ -90,11 +95,11 @@ public class MulticastListener {
}
if (beaconFound) {
// Get the device properties from the announcement beacon
parseAnnouncementBeacon(msgPacket);
// Return the device properties from the announcement beacon
return parseAnnouncementBeacon(msgPacket);
}
return beaconFound;
return null;
}
/*
@ -103,47 +108,26 @@ public class MulticastListener {
* Example Epson beacon:
* AMXB<-UUID=000048746B33><-SDKClass=VideoProjector><-GUID=EPSON_EMP001><-Revision=1.0.0>
*/
private void parseAnnouncementBeacon(DatagramPacket packet) {
private @Nullable Map<String, Object> parseAnnouncementBeacon(DatagramPacket packet) {
String beacon = (new String(packet.getData(), StandardCharsets.UTF_8)).trim();
logger.trace("Multicast listener parsing announcement packet: {}", beacon);
clearProperties();
if (beacon.toUpperCase().contains("EPSON") && beacon.toUpperCase().contains("VIDEOPROJECTOR")) {
ipAddress = packet.getAddress().getHostAddress();
parseEpsonAnnouncementBeacon(beacon);
} else {
logger.debug("Multicast listener doesn't know how to parse beacon: {}", beacon);
}
}
private void parseEpsonAnnouncementBeacon(String beacon) {
String[] parameterList = beacon.split("<-");
if (beacon.toUpperCase(Locale.ENGLISH).contains("EPSON") && beacon.contains("VideoProjector")) {
String[] parameterList = beacon.replace(">", "").split("<-");
for (String parameter : parameterList) {
String[] keyValue = parameter.split("=");
if (keyValue.length != 2) {
continue;
}
if (keyValue[0].contains("UUID")) {
uid = keyValue[1].substring(0, keyValue[1].length() - 1);
if (keyValue.length == 2 && keyValue[0].contains("UUID") && !keyValue[1].isEmpty()) {
Map<String, Object> properties = new HashMap<>();
properties.put(THING_PROPERTY_MAC, keyValue[1]);
properties.put(THING_PROPERTY_HOST, packet.getAddress().getHostAddress());
properties.put(THING_PROPERTY_PORT, DEFAULT_PORT);
return properties;
}
}
logger.debug("Multicast listener doesn't know how to parse beacon: {}", beacon);
}
private void clearProperties() {
uid = "";
ipAddress = "";
}
public String getUID() {
return uid;
}
public String getIPAddress() {
return ipAddress;
return null;
}
}