diff --git a/bundles/org.openhab.binding.androiddebugbridge/README.md b/bundles/org.openhab.binding.androiddebugbridge/README.md
index e8cd54748..1d7b85980 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/README.md
+++ b/bundles/org.openhab.binding.androiddebugbridge/README.md
@@ -60,11 +60,13 @@ This is a sample of the mediaStateJSONConfig thing configuration:
`[{"name": "com.amazon.tv.launcher", "mode": "idle"},{"name": "org.jellyfin.androidtv", "mode": "wake_lock", "wakeLockPlayStates": [2,3]},{"name": "com.amazon.firetv.youtube", "mode": "wake_lock", "wakeLockPlayStates": [2]}]`
## Record/Send input events
+
As the execution of key events takes a while, you can use input events as an alternative way to control your device.
They are pretty device specific, so you should use the record-input and recorded-input channels to store/send those events.
An example of what you can do:
+
* You can send the command `UP` to the `record-input` channel the binding will then capture the events you send through your remote for the defined recordDuration config for the thing, so press once the UP key on your remote and wait a while.
* Now that you have recorded your input, you can send the `UP` command to the `recorded-input` event and it will send the recorded event to the android device.
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/feature/feature.xml b/bundles/org.openhab.binding.androiddebugbridge/src/main/feature/feature.xml
index 6a2e829c1..8f0e3bdff 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/src/main/feature/feature.xml
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/feature/feature.xml
@@ -4,6 +4,7 @@
openhab-runtime-base
+ openhab-transport-mdns
mvn:org.openhab.addons.bundles/org.openhab.binding.androiddebugbridge/${project.version}
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeBindingConstants.java b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeBindingConstants.java
index 0d5cec59e..c831e123a 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeBindingConstants.java
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeBindingConstants.java
@@ -12,7 +12,6 @@
*/
package org.openhab.binding.androiddebugbridge.internal;
-import java.util.Collections;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -32,7 +31,7 @@ public class AndroidDebugBridgeBindingConstants {
// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_ANDROID_DEVICE = new ThingTypeUID(BINDING_ID, "android");
- public static final Set SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_ANDROID_DEVICE);
+ public static final Set SUPPORTED_THING_TYPES = Set.of(THING_TYPE_ANDROID_DEVICE);
// List of all Channel ids
public static final String KEY_EVENT_CHANNEL = "key-event";
public static final String TEXT_CHANNEL = "text";
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDevice.java b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDevice.java
index 33baa264c..0fbba7202 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDevice.java
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDevice.java
@@ -25,7 +25,11 @@ import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
-import java.util.concurrent.*;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -88,7 +92,7 @@ public class AndroidDebugBridgeDevice {
private @Nullable AdbConnection connection;
private @Nullable Future commandFuture;
- AndroidDebugBridgeDevice(ScheduledExecutorService scheduler) {
+ public AndroidDebugBridgeDevice(ScheduledExecutorService scheduler) {
this.scheduler = scheduler;
}
@@ -260,10 +264,12 @@ public class AndroidDebugBridgeDevice {
try {
return Integer.parseInt(lockResp.replace("\n", "").split("=")[1].trim());
} catch (NumberFormatException e) {
- logger.debug("Unable to parse device wake lock: {}", e.getMessage());
+ String message = String.format("Unable to parse device wake-lock '%s'", lockResp);
+ logger.debug("{}: {}", message, e.getMessage());
+ throw new AndroidDebugBridgeDeviceReadException(message);
}
}
- throw new AndroidDebugBridgeDeviceReadException("Unable to read wake lock");
+ throw new AndroidDebugBridgeDeviceReadException(String.format("Unable to read wake-lock '%s'", lockResp));
}
private void setVolume(int stream, int volume)
@@ -291,11 +297,16 @@ public class AndroidDebugBridgeDevice {
return getDeviceProp("ro.serialno");
}
+ public String getMacAddress() throws AndroidDebugBridgeDeviceException, InterruptedException,
+ AndroidDebugBridgeDeviceReadException, TimeoutException, ExecutionException {
+ return getDeviceProp("ro.boot.wifimacaddr").toLowerCase();
+ }
+
private String getDeviceProp(String name) throws AndroidDebugBridgeDeviceException, InterruptedException,
AndroidDebugBridgeDeviceReadException, TimeoutException, ExecutionException {
var propValue = runAdbShell("getprop", name, "&&", "sleep", "0.3").replace("\n", "").replace("\r", "");
if (propValue.length() == 0) {
- throw new AndroidDebugBridgeDeviceReadException("Unable to get device property");
+ throw new AndroidDebugBridgeDeviceReadException(String.format("Unable to get device property '%s'", name));
}
return propValue;
}
@@ -382,7 +393,7 @@ public class AndroidDebugBridgeDevice {
sock.connect(new InetSocketAddress(ip, port), (int) TimeUnit.SECONDS.toMillis(15));
} catch (IOException e) {
logger.debug("Error connecting to {}: [{}] {}", ip, e.getClass().getName(), e.getMessage());
- if (e.getMessage().equals("Socket closed")) {
+ if ("Socket closed".equals(e.getMessage())) {
// Connection aborted by us
throw new InterruptedException();
}
@@ -415,14 +426,12 @@ public class AndroidDebugBridgeDevice {
var byteArrayOutputStream = new ByteArrayOutputStream();
String cmd = String.join(" ", args);
logger.debug("{} - shell:{}", ip, cmd);
- try {
- AdbStream stream = adb.open("shell:" + cmd);
+ try (AdbStream stream = adb.open("shell:" + cmd)) {
do {
byteArrayOutputStream.writeBytes(stream.read());
} while (!stream.isClosed());
} catch (IOException e) {
- String message = e.getMessage();
- if (message != null && !message.equals("Stream closed")) {
+ if (!"Stream closed".equals(e.getMessage())) {
throw e;
}
}
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDeviceException.java b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDeviceException.java
index 3eac1023a..24a690014 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDeviceException.java
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDeviceException.java
@@ -13,6 +13,7 @@
package org.openhab.binding.androiddebugbridge.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.androiddebugbridge.internal.discovery.AndroidDebugBridgeDiscoveryService;
/**
* The {@link AndroidDebugBridgeDiscoveryService} discover Android ADB Instances in the network.
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDeviceReadException.java b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDeviceReadException.java
index 7915cb650..0ff22e25c 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDeviceReadException.java
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDeviceReadException.java
@@ -13,6 +13,7 @@
package org.openhab.binding.androiddebugbridge.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.androiddebugbridge.internal.discovery.AndroidDebugBridgeDiscoveryService;
/**
* The {@link AndroidDebugBridgeDiscoveryService} discover Android ADB Instances in the network.
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeHandler.java b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeHandler.java
index 12199ecc7..2728f98c7 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeHandler.java
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeHandler.java
@@ -16,6 +16,7 @@ import static org.openhab.binding.androiddebugbridge.internal.AndroidDebugBridge
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -78,10 +79,7 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
- var currentConfig = config;
- if (currentConfig == null) {
- return;
- }
+ AndroidDebugBridgeConfiguration currentConfig = config;
try {
if (!adbConnection.isConnected()) {
// try reconnect
@@ -305,7 +303,7 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
@Override
public void initialize() {
- var currentConfig = getConfigAs(AndroidDebugBridgeConfiguration.class);
+ AndroidDebugBridgeConfiguration currentConfig = getConfigAs(AndroidDebugBridgeConfiguration.class);
config = currentConfig;
var mediaStateJSONConfig = currentConfig.mediaStateJSONConfig;
if (mediaStateJSONConfig != null && !mediaStateJSONConfig.isEmpty()) {
@@ -340,14 +338,12 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
}
public void checkConnection() {
- var currentConfig = config;
- if (currentConfig == null) {
- return;
- }
+ AndroidDebugBridgeConfiguration currentConfig = config;
try {
logger.debug("Refresh device {} status", currentConfig.ip);
if (adbConnection.isConnected()) {
updateStatus(ThingStatus.ONLINE);
+ refreshProperties();
refreshStatus();
} else {
try {
@@ -361,17 +357,39 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
}
if (adbConnection.isConnected()) {
updateStatus(ThingStatus.ONLINE);
+ refreshProperties();
refreshStatus();
}
}
} catch (InterruptedException ignored) {
- } catch (AndroidDebugBridgeDeviceException | ExecutionException e) {
+ } catch (AndroidDebugBridgeDeviceException | AndroidDebugBridgeDeviceReadException | ExecutionException e) {
logger.debug("Connection checker error: {}", e.getMessage());
adbConnection.disconnect();
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
}
}
+ private void refreshProperties() throws InterruptedException, AndroidDebugBridgeDeviceException,
+ AndroidDebugBridgeDeviceReadException, ExecutionException {
+ // Add some information about the device
+ try {
+ Map editProperties = editProperties();
+ editProperties.put(Thing.PROPERTY_SERIAL_NUMBER, adbConnection.getSerialNo());
+ editProperties.put(Thing.PROPERTY_MODEL_ID, adbConnection.getModel());
+ editProperties.put(Thing.PROPERTY_FIRMWARE_VERSION, adbConnection.getAndroidVersion());
+ editProperties.put(Thing.PROPERTY_VENDOR, adbConnection.getBrand());
+ try {
+ editProperties.put(Thing.PROPERTY_MAC_ADDRESS, adbConnection.getMacAddress());
+ } catch (AndroidDebugBridgeDeviceReadException e) {
+ logger.debug("Refresh properties error: {}", e.getMessage());
+ }
+ updateProperties(editProperties);
+ } catch (TimeoutException e) {
+ logger.debug("Refresh properties error: Timeout");
+ return;
+ }
+ }
+
private void refreshStatus() throws InterruptedException, AndroidDebugBridgeDeviceException, ExecutionException {
boolean awakeState;
boolean prevDeviceAwake = deviceAwake;
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDiscoveryService.java b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/discovery/AndroidDebugBridgeDiscoveryService.java
similarity index 77%
rename from bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDiscoveryService.java
rename to bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/discovery/AndroidDebugBridgeDiscoveryService.java
index 669a7b675..a64975f5c 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/AndroidDebugBridgeDiscoveryService.java
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/discovery/AndroidDebugBridgeDiscoveryService.java
@@ -10,7 +10,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.openhab.binding.androiddebugbridge.internal;
+package org.openhab.binding.androiddebugbridge.internal.discovery;
import static org.openhab.binding.androiddebugbridge.internal.AndroidDebugBridgeBindingConstants.*;
@@ -22,7 +22,6 @@ import java.net.SocketException;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
-import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
@@ -31,6 +30,10 @@ import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.androiddebugbridge.internal.AndroidDebugBridgeBindingConfiguration;
+import org.openhab.binding.androiddebugbridge.internal.AndroidDebugBridgeDevice;
+import org.openhab.binding.androiddebugbridge.internal.AndroidDebugBridgeDeviceException;
+import org.openhab.binding.androiddebugbridge.internal.AndroidDebugBridgeDeviceReadException;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
import org.openhab.core.config.discovery.DiscoveryService;
@@ -52,6 +55,7 @@ import org.slf4j.LoggerFactory;
@NonNullByDefault
@Component(service = DiscoveryService.class, configurationPid = "discovery.androiddebugbridge")
public class AndroidDebugBridgeDiscoveryService extends AbstractDiscoveryService {
+
static final int TIMEOUT_MS = 60000;
private static final long DISCOVERY_RESULT_TTL_SEC = 300;
public static final String LOCAL_INTERFACE_IP = "127.0.0.1";
@@ -61,7 +65,7 @@ public class AndroidDebugBridgeDiscoveryService extends AbstractDiscoveryService
private boolean discoveryRunning = false;
@Activate
- public AndroidDebugBridgeDiscoveryService(@Reference ConfigurationAdmin admin) {
+ public AndroidDebugBridgeDiscoveryService(final @Reference ConfigurationAdmin admin) {
super(SUPPORTED_THING_TYPES, TIMEOUT_MS, false);
this.admin = admin;
}
@@ -102,7 +106,8 @@ public class AndroidDebugBridgeDiscoveryService extends AbstractDiscoveryService
int retries = 0;
while (retries < MAX_RETRIES) {
try {
- discoverWithADB(currentIp, configuration.discoveryPort);
+ discoverWithADB(currentIp, configuration.discoveryPort,
+ new String(netint.getHardwareAddress()).toLowerCase());
} catch (AndroidDebugBridgeDeviceReadException | TimeoutException e) {
retries++;
if (retries < MAX_RETRIES) {
@@ -126,8 +131,9 @@ public class AndroidDebugBridgeDiscoveryService extends AbstractDiscoveryService
}
}
- private void discoverWithADB(String ip, int port) throws InterruptedException, AndroidDebugBridgeDeviceException,
- AndroidDebugBridgeDeviceReadException, TimeoutException, ExecutionException {
+ private void discoverWithADB(String ip, int port, String macAddress)
+ throws InterruptedException, AndroidDebugBridgeDeviceException, AndroidDebugBridgeDeviceReadException,
+ TimeoutException, ExecutionException {
var device = new AndroidDebugBridgeDevice(scheduler);
device.configure(ip, port, 10, 0);
try {
@@ -137,8 +143,8 @@ public class AndroidDebugBridgeDiscoveryService extends AbstractDiscoveryService
String model = device.getModel();
String androidVersion = device.getAndroidVersion();
String brand = device.getBrand();
- logger.debug("discovered: {} - {} - {} - {}", model, serialNo, androidVersion, brand);
- onDiscoverResult(serialNo, ip, port, model, androidVersion, brand);
+ logger.debug("discovered: {} - {} - {} - {} - {}", model, serialNo, androidVersion, brand, macAddress);
+ onDiscoverResult(serialNo, ip, port, model, androidVersion, brand, macAddress);
} finally {
device.disconnect();
}
@@ -152,17 +158,23 @@ public class AndroidDebugBridgeDiscoveryService extends AbstractDiscoveryService
}
private void onDiscoverResult(String serialNo, String ip, int port, String model, String androidVersion,
- String brand) {
- Map properties = new HashMap<>();
- properties.put(Thing.PROPERTY_SERIAL_NUMBER, serialNo);
- properties.put(PARAMETER_IP, ip);
- properties.put(PARAMETER_PORT, port);
- properties.put(Thing.PROPERTY_MODEL_ID, model);
- properties.put(Thing.PROPERTY_VENDOR, brand);
- properties.put(Thing.PROPERTY_FIRMWARE_VERSION, androidVersion);
- thingDiscovered(DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_ANDROID_DEVICE, serialNo))
- .withTTL(DISCOVERY_RESULT_TTL_SEC).withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER)
- .withProperties(properties).withLabel(String.format("%s (%s)", model, serialNo)).build());
+ String brand, String macAddress) {
+ String friendlyName = String.format("%s (%s)", model, ip);
+ thingDiscovered(
+ DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_ANDROID_DEVICE, macAddress.replaceAll(":", ""))) //
+ .withProperties(Map.of( //
+ PARAMETER_IP, ip, //
+ PARAMETER_PORT, port, //
+ Thing.PROPERTY_MAC_ADDRESS, macAddress, //
+ Thing.PROPERTY_SERIAL_NUMBER, serialNo, //
+ Thing.PROPERTY_MODEL_ID, model, //
+ Thing.PROPERTY_VENDOR, brand, //
+ Thing.PROPERTY_FIRMWARE_VERSION, androidVersion //
+ )) //
+ .withLabel(friendlyName) //
+ .withRepresentationProperty(Thing.PROPERTY_MAC_ADDRESS) //
+ .withTTL(DISCOVERY_RESULT_TTL_SEC) //
+ .build());
}
private @Nullable AndroidDebugBridgeBindingConfiguration getConfig() {
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/discovery/FireTVStickMDNSDiscoveryParticipant.java b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/discovery/FireTVStickMDNSDiscoveryParticipant.java
new file mode 100644
index 000000000..e14f4beb4
--- /dev/null
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/java/org/openhab/binding/androiddebugbridge/internal/discovery/FireTVStickMDNSDiscoveryParticipant.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.androiddebugbridge.internal.discovery;
+
+import static org.openhab.binding.androiddebugbridge.internal.AndroidDebugBridgeBindingConstants.*;
+
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jmdns.ServiceInfo;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.config.discovery.DiscoveryResult;
+import org.openhab.core.config.discovery.DiscoveryResultBuilder;
+import org.openhab.core.config.discovery.DiscoveryService;
+import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
+import org.openhab.core.config.discovery.mdns.internal.MDNSDiscoveryService;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.ThingUID;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Modified;
+
+/**
+ * The {@link FireTVStickMDNSDiscoveryParticipant} is responsible for discovering new and removed Fire TV Stick. It uses
+ * the central {@link MDNSDiscoveryService}.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+@Component(configurationPid = "discovery.androiddebugbridge")
+@NonNullByDefault
+public class FireTVStickMDNSDiscoveryParticipant implements MDNSDiscoveryParticipant {
+
+ private static final String SERVICE_TYPE = "_amzn-wplay._tcp.local.";
+ private static final String MDNS_PROPERTY_NAME = "n";
+ private static final String MDNS_PROPERTY_MAC_ADDRESS = "c";
+
+ private boolean isAutoDiscoveryEnabled = true;
+
+ @Activate
+ protected void activate(ComponentContext componentContext) {
+ activateOrModifyService(componentContext);
+ }
+
+ @Modified
+ protected void modified(ComponentContext componentContext) {
+ activateOrModifyService(componentContext);
+ }
+
+ private void activateOrModifyService(ComponentContext componentContext) {
+ Dictionary properties = componentContext.getProperties();
+ String autoDiscoveryPropertyValue = (String) properties
+ .get(DiscoveryService.CONFIG_PROPERTY_BACKGROUND_DISCOVERY);
+ if (autoDiscoveryPropertyValue != null && !autoDiscoveryPropertyValue.isBlank()) {
+ isAutoDiscoveryEnabled = Boolean.valueOf(autoDiscoveryPropertyValue);
+ }
+ }
+
+ @Override
+ public Set getSupportedThingTypeUIDs() {
+ return SUPPORTED_THING_TYPES;
+ }
+
+ @Override
+ public String getServiceType() {
+ return SERVICE_TYPE;
+ }
+
+ @Override
+ public @Nullable DiscoveryResult createResult(ServiceInfo service) {
+ if (isAutoDiscoveryEnabled) {
+ ThingUID uid = getThingUID(service);
+ if (uid != null) {
+ String ip = service.getHostAddresses()[0];
+ String macAddress = service.getPropertyString(MDNS_PROPERTY_MAC_ADDRESS);
+ String friendlyName = String.format("%s (%s)", service.getPropertyString(MDNS_PROPERTY_NAME), ip);
+ return DiscoveryResultBuilder.create(uid) //
+ .withProperties(Map.of( //
+ PARAMETER_IP, ip, //
+ Thing.PROPERTY_MAC_ADDRESS, macAddress.toLowerCase())) //
+ .withLabel(friendlyName) //
+ .withRepresentationProperty(Thing.PROPERTY_MAC_ADDRESS) //
+ .build();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public @Nullable ThingUID getThingUID(ServiceInfo service) {
+ String macAddress = service.getPropertyString(MDNS_PROPERTY_MAC_ADDRESS);
+ if (macAddress != null && !macAddress.isBlank()) {
+ return new ThingUID(THING_TYPE_ANDROID_DEVICE, macAddress.replaceAll(":", "").toLowerCase());
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.androiddebugbridge/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.androiddebugbridge/src/main/resources/OH-INF/thing/thing-types.xml
index df8d9a26d..94fc30c38 100644
--- a/bundles/org.openhab.binding.androiddebugbridge/src/main/resources/OH-INF/thing/thing-types.xml
+++ b/bundles/org.openhab.binding.androiddebugbridge/src/main/resources/OH-INF/thing/thing-types.xml
@@ -25,7 +25,7 @@
- serial
+ macAddress
network-address