From 7613cbcd762eee9694318037146874b2047b2cfb Mon Sep 17 00:00:00 2001 From: mlobstein Date: Sat, 9 Apr 2022 09:10:36 -0500 Subject: [PATCH] [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 --- .../EpsonProjectorDiscoveryService.java | 41 +++++----- .../internal/discovery/MulticastListener.java | 76 ++++++++----------- 2 files changed, 48 insertions(+), 69 deletions(-) diff --git a/bundles/org.openhab.binding.epsonprojector/src/main/java/org/openhab/binding/epsonprojector/internal/discovery/EpsonProjectorDiscoveryService.java b/bundles/org.openhab.binding.epsonprojector/src/main/java/org/openhab/binding/epsonprojector/internal/discovery/EpsonProjectorDiscoveryService.java index f3192d33c..02a8a0f26 100644 --- a/bundles/org.openhab.binding.epsonprojector/src/main/java/org/openhab/binding/epsonprojector/internal/discovery/EpsonProjectorDiscoveryService.java +++ b/bundles/org.openhab.binding.epsonprojector/src/main/java/org/openhab/binding/epsonprojector/internal/discovery/EpsonProjectorDiscoveryService.java @@ -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(); + // Wait for a discovery beacon to return properties for an Epson projector. + Map 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) { 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 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(); diff --git a/bundles/org.openhab.binding.epsonprojector/src/main/java/org/openhab/binding/epsonprojector/internal/discovery/MulticastListener.java b/bundles/org.openhab.binding.epsonprojector/src/main/java/org/openhab/binding/epsonprojector/internal/discovery/MulticastListener.java index fd05ce2fd..ed3c66c4f 100644 --- a/bundles/org.openhab.binding.epsonprojector/src/main/java/org/openhab/binding/epsonprojector/internal/discovery/MulticastListener.java +++ b/bundles/org.openhab.binding.epsonprojector/src/main/java/org/openhab/binding/epsonprojector/internal/discovery/MulticastListener.java @@ -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 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 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(Locale.ENGLISH).contains("EPSON") && beacon.contains("VideoProjector")) { + String[] parameterList = beacon.replace(">", "").split("<-"); - if (beacon.toUpperCase().contains("EPSON") && beacon.toUpperCase().contains("VIDEOPROJECTOR")) { - ipAddress = packet.getAddress().getHostAddress(); - parseEpsonAnnouncementBeacon(beacon); - } else { + for (String parameter : parameterList) { + String[] keyValue = parameter.split("="); + + if (keyValue.length == 2 && keyValue[0].contains("UUID") && !keyValue[1].isEmpty()) { + Map 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 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; + return null; } }