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