]> git.basschouten.com Git - openhab-addons.git/blob
72498744bca9b976839d30ea2f7d5c29cf2ab405
[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.epsonprojector.internal.discovery;
14
15 import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingConstants.*;
16
17 import java.io.IOException;
18 import java.net.SocketException;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.concurrent.ScheduledFuture;
23 import java.util.concurrent.TimeUnit;
24
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;
38
39 /**
40  * The {@link EpsonProjectoreDiscoveryService} class implements a service
41  * for discovering Epson projectors using the AMX Device Discovery protocol.
42  *
43  * @author Mark Hilbush - Initial contribution
44  * @author Michael Lobstein - Adapted for the Epson Projector binding
45  */
46 @NonNullByDefault
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;
51
52     // Discovery parameters
53     public static final boolean BACKGROUND_DISCOVERY_ENABLED = true;
54     public static final int BACKGROUND_DISCOVERY_DELAY_TIMEOUT_SEC = 10;
55
56     private NetworkAddressService networkAddressService;
57
58     private boolean terminate = false;
59
60     @Activate
61     public EpsonProjectorDiscoveryService(@Reference NetworkAddressService networkAddressService) {
62         super(SUPPORTED_THING_TYPES_UIDS, 0, BACKGROUND_DISCOVERY_ENABLED);
63         this.networkAddressService = networkAddressService;
64         epsonDiscoveryJob = null;
65         terminate = false;
66     }
67
68     @Override
69     public Set<ThingTypeUID> getSupportedThingTypes() {
70         return SUPPORTED_THING_TYPES_UIDS;
71     }
72
73     @Override
74     protected void startBackgroundDiscovery() {
75         if (epsonDiscoveryJob == null) {
76             terminate = false;
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,
79                     TimeUnit.SECONDS);
80         }
81     }
82
83     @Override
84     protected void stopBackgroundDiscovery() {
85         ScheduledFuture<?> epsonDiscoveryJob = this.epsonDiscoveryJob;
86         if (epsonDiscoveryJob != null) {
87             terminate = true;
88             epsonDiscoveryJob.cancel(false);
89             this.epsonDiscoveryJob = null;
90         }
91     }
92
93     @Override
94     public void startScan() {
95     }
96
97     @Override
98     public void stopScan() {
99     }
100
101     private synchronized void discover() {
102         logger.debug("Discovery job is running");
103         MulticastListener epsonMulticastListener;
104         String local = "127.0.0.1";
105
106         try {
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());
111             return;
112         } catch (IOException ioe) {
113             logger.debug("Discovery job got IO exception creating multicast socket: {}", ioe.getMessage());
114             return;
115         }
116
117         while (!terminate) {
118             boolean beaconReceived;
119             try {
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;
125             }
126
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();
131
132                 properties.put(THING_PROPERTY_HOST, epsonMulticastListener.getIPAddress());
133                 properties.put(THING_PROPERTY_PORT, DEFAULT_PORT);
134
135                 logger.trace("Projector with UID {} discovered at IP: {}", uid, epsonMulticastListener.getIPAddress());
136
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());
143             }
144         }
145         epsonMulticastListener.shutdown();
146         logger.debug("Discovery job is exiting");
147     }
148 }