2 * Copyright (c) 2010-2021 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.epsonprojector.internal.discovery;
15 import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingConstants.*;
17 import java.io.IOException;
18 import java.net.SocketException;
19 import java.util.HashMap;
22 import java.util.concurrent.ScheduledFuture;
23 import java.util.concurrent.TimeUnit;
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.core.config.discovery.AbstractDiscoveryService;
28 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
29 import org.openhab.core.config.discovery.DiscoveryService;
30 import org.openhab.core.net.NetworkAddressService;
31 import org.openhab.core.thing.ThingTypeUID;
32 import org.openhab.core.thing.ThingUID;
33 import org.osgi.service.component.annotations.Activate;
34 import org.osgi.service.component.annotations.Component;
35 import org.osgi.service.component.annotations.Reference;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * The {@link EpsonProjectoreDiscoveryService} class implements a service
41 * for discovering Epson projectors using the AMX Device Discovery protocol.
43 * @author Mark Hilbush - Initial contribution
44 * @author Michael Lobstein - Adapted for the Epson Projector binding
47 @Component(service = DiscoveryService.class, configurationPid = "discovery.epsonprojector")
48 public class EpsonProjectorDiscoveryService extends AbstractDiscoveryService {
49 private final Logger logger = LoggerFactory.getLogger(EpsonProjectorDiscoveryService.class);
50 private @Nullable ScheduledFuture<?> epsonDiscoveryJob;
52 // Discovery parameters
53 public static final boolean BACKGROUND_DISCOVERY_ENABLED = true;
54 public static final int BACKGROUND_DISCOVERY_DELAY_TIMEOUT_SEC = 10;
56 private NetworkAddressService networkAddressService;
58 private boolean terminate = false;
61 public EpsonProjectorDiscoveryService(@Reference NetworkAddressService networkAddressService) {
62 super(SUPPORTED_THING_TYPES_UIDS, 0, BACKGROUND_DISCOVERY_ENABLED);
63 this.networkAddressService = networkAddressService;
64 epsonDiscoveryJob = null;
69 public Set<ThingTypeUID> getSupportedThingTypes() {
70 return SUPPORTED_THING_TYPES_UIDS;
74 protected void startBackgroundDiscovery() {
75 if (epsonDiscoveryJob == null) {
77 logger.debug("Starting background discovery job in {} seconds", BACKGROUND_DISCOVERY_DELAY_TIMEOUT_SEC);
78 epsonDiscoveryJob = scheduler.schedule(this::discover, BACKGROUND_DISCOVERY_DELAY_TIMEOUT_SEC,
84 protected void stopBackgroundDiscovery() {
85 ScheduledFuture<?> epsonDiscoveryJob = this.epsonDiscoveryJob;
86 if (epsonDiscoveryJob != null) {
88 epsonDiscoveryJob.cancel(false);
89 this.epsonDiscoveryJob = null;
94 public void startScan() {
98 public void stopScan() {
101 private synchronized void discover() {
102 logger.debug("Discovery job is running");
103 MulticastListener epsonMulticastListener;
104 String local = "127.0.0.1";
107 String ip = networkAddressService.getPrimaryIpv4HostAddress();
108 epsonMulticastListener = new MulticastListener((ip != null ? ip : local));
109 } catch (SocketException se) {
110 logger.debug("Discovery job got Socket exception creating multicast socket: {}", se.getMessage());
112 } catch (IOException ioe) {
113 logger.debug("Discovery job got IO exception creating multicast socket: {}", ioe.getMessage());
118 boolean beaconReceived;
120 // Wait for a discovery beacon.
121 beaconReceived = epsonMulticastListener.waitForBeacon();
122 } catch (IOException ioe) {
123 logger.debug("Discovery job got exception waiting for beacon: {}", ioe.getMessage());
124 beaconReceived = false;
127 if (beaconReceived) {
128 // We got a discovery beacon. Process it as a potential new thing
129 Map<String, Object> properties = new HashMap<>();
130 String uid = epsonMulticastListener.getUID();
132 properties.put(THING_PROPERTY_HOST, epsonMulticastListener.getIPAddress());
133 properties.put(THING_PROPERTY_PORT, DEFAULT_PORT);
135 logger.trace("Projector with UID {} discovered at IP: {}", uid, epsonMulticastListener.getIPAddress());
137 ThingUID thingUid = new ThingUID(THING_TYPE_PROJECTOR_TCP, uid);
138 logger.trace("Creating epson projector discovery result for: {}, IP={}", uid,
139 epsonMulticastListener.getIPAddress());
140 thingDiscovered(DiscoveryResultBuilder.create(thingUid).withProperties(properties)
141 .withLabel("Epson Projector " + uid).withProperty(THING_PROPERTY_MAC, uid)
142 .withRepresentationProperty(THING_PROPERTY_MAC).build());
145 epsonMulticastListener.shutdown();
146 logger.debug("Discovery job is exiting");