2 * Copyright (c) 2010-2020 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
14 package org.openhab.binding.gree.internal.discovery;
16 import static org.openhab.binding.gree.internal.GreeBindingConstants.*;
18 import java.net.DatagramSocket;
19 import java.net.SocketException;
20 import java.util.HashMap;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.gree.internal.GreeException;
26 import org.openhab.binding.gree.internal.GreeTranslationProvider;
27 import org.openhab.binding.gree.internal.handler.GreeAirDevice;
28 import org.openhab.core.config.discovery.AbstractDiscoveryService;
29 import org.openhab.core.config.discovery.DiscoveryResult;
30 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
31 import org.openhab.core.config.discovery.DiscoveryService;
32 import org.openhab.core.net.NetworkAddressService;
33 import org.openhab.core.thing.Thing;
34 import org.openhab.core.thing.ThingUID;
35 import org.osgi.service.component.annotations.Activate;
36 import org.osgi.service.component.annotations.Component;
37 import org.osgi.service.component.annotations.Modified;
38 import org.osgi.service.component.annotations.Reference;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * {@link GreeDiscoveryService} implements the device discovery service. UDP broadtcast ius used to find the devices on
46 * @author Markus Michels - Initial contribution
50 @Component(service = DiscoveryService.class, configurationPid = "discovery.gree")
51 public class GreeDiscoveryService extends AbstractDiscoveryService {
52 private static final int TIMEOUT_SEC = 10;
53 private final Logger logger = LoggerFactory.getLogger(GreeDiscoveryService.class);
54 private final GreeDeviceFinder deviceFinder;
55 private final GreeTranslationProvider messages;
56 private final String broadcastAddress;
59 public GreeDiscoveryService(@Reference GreeDeviceFinder deviceFinder,
60 @Reference NetworkAddressService networkAddressService,
61 @Reference GreeTranslationProvider translationProvider, @Nullable Map<String, Object> configProperties) {
62 super(SUPPORTED_THING_TYPES_UIDS, TIMEOUT_SEC);
63 this.messages = translationProvider;
64 this.deviceFinder = deviceFinder;
65 String ip = networkAddressService.getConfiguredBroadcastAddress();
66 broadcastAddress = ip != null ? ip : "";
67 activate(configProperties);
72 protected void modified(@Nullable Map<String, Object> configProperties) {
73 super.modified(configProperties);
77 protected void startBackgroundDiscovery() {
78 // It's very unusual that a new unit gets installed frequently so we run the discovery once when the binding is
79 // started, but not frequently
80 scheduler.execute(this::startScan);
84 protected void stopBackgroundDiscovery() {
89 protected void startScan() {
90 try (DatagramSocket clientSocket = new DatagramSocket()) {
91 deviceFinder.scan(clientSocket, broadcastAddress, true);
93 int count = deviceFinder.getScannedDeviceCount();
94 logger.debug("{}", messages.get("discovery.result", count));
96 logger.debug("Adding uinits to Inbox");
97 createResult(deviceFinder.getDevices());
99 } catch (GreeException e) {
100 logger.info("Discovery: {}", messages.get("discovery.exception", e.getMessageString()));
101 } catch (SocketException | RuntimeException e) {
102 logger.warn("Discovery: {}", messages.get("discovery.exception", "RuntimeException"), e);
106 public void createResult(Map<String, GreeAirDevice> deviceList) {
107 for (GreeAirDevice device : deviceList.values()) {
108 String ipAddress = device.getAddress().getHostAddress();
109 logger.debug("{}", messages.get("discovery.newunit", device.getName(), ipAddress, device.getId()));
110 Map<String, Object> properties = new HashMap<>();
111 properties.put(Thing.PROPERTY_VENDOR, device.getVendor());
112 properties.put(Thing.PROPERTY_MODEL_ID, device.getModel());
113 properties.put(Thing.PROPERTY_MAC_ADDRESS, device.getId());
114 properties.put(PROPERTY_IP, ipAddress);
115 properties.put(PROPERTY_BROADCAST, broadcastAddress);
116 ThingUID thingUID = new ThingUID(THING_TYPE_GREEAIRCON, device.getId());
117 DiscoveryResult result = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
118 .withRepresentationProperty(Thing.PROPERTY_MAC_ADDRESS).withLabel(device.getName()).build();
119 thingDiscovered(result);
124 public void deactivate() {
125 removeOlderResults(getTimestampOfLastScan());