[androiddebugbridge] Added mDNS discovery for Fire TV Stick (#11881)
* Added mDNS discovery for Fire TV Stick Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
committed by
GitHub
parent
39ee01687f
commit
58ff256288
@@ -4,6 +4,7 @@
|
||||
|
||||
<feature name="openhab-binding-androiddebugbridge" description="Android Debug Bridge Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<feature>openhab-transport-mdns</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.androiddebugbridge/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
|
||||
@@ -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<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_ANDROID_DEVICE);
|
||||
public static final Set<ThingTypeUID> 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";
|
||||
|
||||
@@ -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<String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<String, String> 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;
|
||||
|
||||
@@ -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<String, Object> 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() {
|
||||
@@ -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<String, @Nullable Object> 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<ThingTypeUID> 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;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
<channel id="shutdown" typeId="shutdown-channel"/>
|
||||
<channel id="awake-state" typeId="awake-state-channel"/>
|
||||
</channels>
|
||||
<representation-property>serial</representation-property>
|
||||
<representation-property>macAddress</representation-property>
|
||||
<config-description>
|
||||
<parameter name="ip" type="text" required="true">
|
||||
<context>network-address</context>
|
||||
|
||||
Reference in New Issue
Block a user