[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
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.io.IOException;
import java.net.SocketException; import java.net.SocketException;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
@@ -115,31 +114,27 @@ public class EpsonProjectorDiscoveryService extends AbstractDiscoveryService {
} }
while (!terminate) { while (!terminate) {
boolean beaconReceived;
try { try {
// Wait for a discovery beacon. // Wait for a discovery beacon to return properties for an Epson projector.
beaconReceived = epsonMulticastListener.waitForBeacon(); Map<String, Object> thingProperties = epsonMulticastListener.waitForBeacon();
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);
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, ipAddress);
thingDiscovered(DiscoveryResultBuilder.create(thingUid).withProperties(thingProperties)
.withLabel("Epson Projector " + uid).withRepresentationProperty(THING_PROPERTY_MAC)
.build());
}
}
} catch (IOException ioe) { } catch (IOException ioe) {
logger.debug("Discovery job got exception waiting for beacon: {}", ioe.getMessage()); logger.debug("Discovery job got exception waiting for beacon: {}", ioe.getMessage());
beaconReceived = false;
}
if (beaconReceived) {
// We got a discovery beacon. Process it as a potential new thing
Map<String, Object> properties = new HashMap<>();
String uid = epsonMulticastListener.getUID();
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());
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());
} }
} }
epsonMulticastListener.shutdown(); epsonMulticastListener.shutdown();

View File

@@ -12,6 +12,11 @@
*/ */
package org.openhab.binding.epsonprojector.internal.discovery; 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.io.IOException;
import java.net.DatagramPacket; import java.net.DatagramPacket;
import java.net.InetAddress; import java.net.InetAddress;
@@ -20,8 +25,12 @@ import java.net.NetworkInterface;
import java.net.SocketException; import java.net.SocketException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets; 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.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -38,10 +47,6 @@ public class MulticastListener {
private MulticastSocket socket; 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 // Epson projector devices announce themselves on a multicast port
private static final String EPSON_MULTICAST_GROUP = "239.255.250.250"; private static final String EPSON_MULTICAST_GROUP = "239.255.250.250";
private static final int EPSON_MULTICAST_PORT = 9131; 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. * 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. * 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]; byte[] bytes = new byte[600];
boolean beaconFound; boolean beaconFound;
@@ -90,11 +95,11 @@ public class MulticastListener {
} }
if (beaconFound) { if (beaconFound) {
// Get the device properties from the announcement beacon // Return the device properties from the announcement beacon
parseAnnouncementBeacon(msgPacket); return parseAnnouncementBeacon(msgPacket);
} }
return beaconFound; return null;
} }
/* /*
@@ -103,47 +108,26 @@ public class MulticastListener {
* Example Epson beacon: * Example Epson beacon:
* AMXB<-UUID=000048746B33><-SDKClass=VideoProjector><-GUID=EPSON_EMP001><-Revision=1.0.0> * 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(); String beacon = (new String(packet.getData(), StandardCharsets.UTF_8)).trim();
logger.trace("Multicast listener parsing announcement packet: {}", beacon); logger.trace("Multicast listener parsing announcement packet: {}", beacon);
clearProperties(); if (beacon.toUpperCase(Locale.ENGLISH).contains("EPSON") && beacon.contains("VideoProjector")) {
String[] parameterList = beacon.replace(">", "").split("<-");
if (beacon.toUpperCase().contains("EPSON") && beacon.toUpperCase().contains("VIDEOPROJECTOR")) { for (String parameter : parameterList) {
ipAddress = packet.getAddress().getHostAddress(); String[] keyValue = parameter.split("=");
parseEpsonAnnouncementBeacon(beacon);
} else { 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); logger.debug("Multicast listener doesn't know how to parse beacon: {}", beacon);
} }
} return null;
private void parseEpsonAnnouncementBeacon(String beacon) {
String[] parameterList = beacon.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);
}
}
}
private void clearProperties() {
uid = "";
ipAddress = "";
}
public String getUID() {
return uid;
}
public String getIPAddress() {
return ipAddress;
} }
} }