[miio] change deviceID to Xiaomi used string (#10951)

* [miio] change deviceID to Xiaomi used string

Change the deviceId from the current hexadecimal to the string used by
Xiaomi.
This is needed as we have some devices that have deviceIds that are
non-numeric, hence breaking the current logic.

Note: separately removing the upnp discovery as this has become
irrelevant with cloud discovery and devices supporting the udp regular
discovery.

Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com>

* Update bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoAbstractHandler.java

Signed-off-by: Fabian Wolter <github@fabian-wolter.de>

Co-authored-by: Fabian Wolter <github@fabian-wolter.de>
This commit is contained in:
Marcel 2021-07-06 19:42:42 +02:00 committed by GitHub
parent 89f2da140c
commit 7d2db98662
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 73 additions and 199 deletions

View File

@ -76,7 +76,7 @@ However, for devices that are unsupported, you may override the value and try to
|-----------------|---------|----------|---------------------------------------------------------------------|
| host | text | true | Device IP address |
| token | text | true | Token for communication (in Hex) |
| deviceId | text | true | Device ID number for communication (in Hex) |
| deviceId | text | true | Device Id (typically a number for normal devices) for communication |
| model | text | false | Device model string, used to determine the subtype |
| refreshInterval | integer | false | Refresh interval for refreshing the data in seconds. (0=disabled) |
| timeout | integer | false | Timeout time in milliseconds |
@ -86,11 +86,11 @@ Note: Suggest to use the cloud communication only for devices that require it. I
### Example Thing file
`Thing miio:basic:light "My Light" [ host="192.168.x.x", token="put here your token", deviceId="0326xxxx", model="philips.light.bulb", communication="direct" ]`
`Thing miio:basic:light "My Light" [ host="192.168.x.x", token="put here your token", deviceId="326xxxx", model="philips.light.bulb", communication="direct" ]`
or in case of unknown models include the model information of a similar device that is supported:
`Thing miio:vacuum:s50 "vacuum" @ "livingroom" [ host="192.168.15.20", token="xxxxxxx", deviceId=“0470DDAA”, model="roborock.vacuum.s4", communication="cloud"]`
`Thing miio:vacuum:s50 "vacuum" @ "livingroom" [ host="192.168.15.20", token="xxxxxxx", deviceId="326xxxx", model="roborock.vacuum.s4", communication="direct" ]`
# Advanced: Unsupported devices

View File

@ -76,7 +76,7 @@ However, for devices that are unsupported, you may override the value and try to
|-----------------|---------|----------|---------------------------------------------------------------------|
| host | text | true | Device IP address |
| token | text | true | Token for communication (in Hex) |
| deviceId | text | true | Device ID number for communication (in Hex) |
| deviceId | text | true | Device Id (typically a number for normal devices) for communication |
| model | text | false | Device model string, used to determine the subtype |
| refreshInterval | integer | false | Refresh interval for refreshing the data in seconds. (0=disabled) |
| timeout | integer | false | Timeout time in milliseconds |
@ -86,11 +86,11 @@ Note: Suggest to use the cloud communication only for devices that require it. I
### Example Thing file
`Thing miio:basic:light "My Light" [ host="192.168.x.x", token="put here your token", deviceId="0326xxxx", model="philips.light.bulb", communication="direct" ]`
`Thing miio:basic:light "My Light" [ host="192.168.x.x", token="put here your token", deviceId="326xxxx", model="philips.light.bulb", communication="direct" ]`
or in case of unknown models include the model information of a similar device that is supported:
`Thing miio:vacuum:s50 "vacuum" @ "livingroom" [ host="192.168.15.20", token="xxxxxxx", deviceId=“0470DDAA”, model="roborock.vacuum.s4", communication="cloud"]`
`Thing miio:vacuum:s50 "vacuum" @ "livingroom" [ host="192.168.15.20", token="xxxxxxx", deviceId="326xxxx", model="roborock.vacuum.s4", communication="direct" ]`
# Advanced: Unsupported devices

View File

@ -127,4 +127,17 @@ public final class Utils {
}
return value;
}
/**
* Formats the deviceId to a hex string if possible. Otherwise returns the id unmodified.
*
* @param did
* @return did
*/
public static String getHexId(String did) {
if (!did.isBlank() && !did.contains(".")) {
return toHEX(did);
}
return did;
}
}

View File

@ -208,10 +208,9 @@ public class CloudConnector {
if (deviceListState != DeviceListState.AVAILABLE) {
return null;
}
String did = Long.toString(Long.parseUnsignedLong(id, 16));
List<CloudDeviceDTO> devicedata = new ArrayList<>();
for (CloudDeviceDTO deviceDetails : deviceList) {
if (deviceDetails.getDid().contentEquals(did)) {
if (deviceDetails.getDid().contentEquals(id)) {
devicedata.add(deviceDetails);
}
}

View File

@ -184,7 +184,7 @@ public class MiIoDiscovery extends AbstractDiscoveryService {
if (cloudConnector.isConnected()) {
List<CloudDeviceDTO> dv = cloudConnector.getDevicesList();
for (CloudDeviceDTO device : dv) {
String id = Utils.toHEX(device.getDid());
String id = device.getDid();
if (cloudDiscoveryMode.contentEquals(SUPPORTED)) {
if (MiIoDevices.getType(device.getModel()).getThingType().equals(THING_TYPE_UNSUPPORTED)) {
logger.warn("Discovered from cloud, but ignored because not supported: {} {}", id, device);
@ -194,7 +194,7 @@ public class MiIoDiscovery extends AbstractDiscoveryService {
logger.debug("Discovered from cloud: {} {}", id, device);
cloudDevices.put(id, device.getLocalip());
String token = device.getToken();
String label = device.getName() + " " + id + " (" + device.getDid() + ")";
String label = device.getName() + " " + id + " (" + Utils.getHexId(id) + ")";
String country = device.getServer();
boolean isOnline = device.getIsOnline();
String ip = device.getLocalip();
@ -210,8 +210,9 @@ public class MiIoDiscovery extends AbstractDiscoveryService {
logger.trace("Discovery responses from : {}:{}", ip, Utils.getSpacedHex(response));
Message msg = new Message(response);
String token = Utils.getHex(msg.getChecksum());
String id = Utils.getHex(msg.getDeviceId());
String label = "Xiaomi Mi Device " + id + " (" + Utils.fromHEX(id) + ")";
String hexId = Utils.getHex(msg.getDeviceId());
String id = Utils.fromHEX(hexId);
String label = "Xiaomi Mi Device " + id + " (" + Utils.getHexId(id) + ")";
String country = "";
boolean isOnline = false;
if (ip.equals(cloudDevices.get(id))) {
@ -224,7 +225,7 @@ public class MiIoDiscovery extends AbstractDiscoveryService {
if (cloudInfo != null) {
logger.debug("Cloud Info: {}", cloudInfo);
token = cloudInfo.getToken();
label = cloudInfo.getName() + " " + id + " (" + Utils.fromHEX(id) + ")";
label = cloudInfo.getName() + " " + id + " (" + Utils.getHexId(id) + ")";
country = cloudInfo.getServer();
isOnline = cloudInfo.getIsOnline();
}
@ -233,17 +234,17 @@ public class MiIoDiscovery extends AbstractDiscoveryService {
}
private void submitDiscovery(String ip, String token, String id, String label, String country, boolean isOnline) {
ThingUID uid = new ThingUID(THING_TYPE_MIIO, id.replace(".", "_"));
ThingUID uid = new ThingUID(THING_TYPE_MIIO, Utils.getHexId(id).replace(".", "_"));
DiscoveryResultBuilder dr = DiscoveryResultBuilder.create(uid).withProperty(PROPERTY_HOST_IP, ip)
.withProperty(PROPERTY_DID, id);
if (IGNORED_TOKENS.contains(token)) {
logger.debug("Discovered Mi Device {} ({}) at {} as {}", id, Utils.fromHEX(id), ip, uid);
logger.debug("Discovered Mi Device {} ({}) at {} as {}", id, Utils.getHexId(id), ip, uid);
logger.debug(
"No token discovered for device {}. For options how to get the token, check the binding readme.",
id);
dr = dr.withRepresentationProperty(PROPERTY_DID).withLabel(label);
} else {
logger.debug("Discovered Mi Device {} ({}) at {} as {} with token {}", id, Utils.fromHEX(id), ip, uid,
logger.debug("Discovered Mi Device {} ({}) at {} as {} with token {}", id, Utils.getHexId(id), ip, uid,
token);
dr = dr.withProperty(PROPERTY_TOKEN, token).withRepresentationProperty(PROPERTY_DID)
.withLabel(label + " with token");

View File

@ -1,142 +0,0 @@
/**
* Copyright (c) 2010-2021 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.miio.internal.discovery;
import static org.openhab.binding.miio.internal.MiIoBindingConstants.*;
import java.net.InetAddress;
import java.util.HashMap;
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.binding.miio.internal.MiIoDevices;
import org.openhab.binding.miio.internal.cloud.CloudConnector;
import org.openhab.binding.miio.internal.cloud.CloudDeviceDTO;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Discovers Mi IO devices announced by mDNS
*
* @author Marcel Verpaalen - Initial contribution
*
*/
@NonNullByDefault
@Component(service = MDNSDiscoveryParticipant.class)
public class MiIoDiscoveryParticipant implements MDNSDiscoveryParticipant {
private final CloudConnector cloudConnector;
private Logger logger = LoggerFactory.getLogger(MiIoDiscoveryParticipant.class);
@Activate
public MiIoDiscoveryParticipant(@Reference CloudConnector cloudConnector) {
this.cloudConnector = cloudConnector;
logger.debug("Start Xiaomi Mi IO mDNS discovery");
}
@Override
public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
return (NONGENERIC_THING_TYPES_UIDS);
}
@Override
public String getServiceType() {
return "_miio._udp.local.";
}
@Override
public @Nullable ThingUID getThingUID(@Nullable ServiceInfo service) {
if (service == null) {
return null;
}
logger.trace("ServiceInfo: {}", service);
String id[] = service.getName().split("_miio");
if (id.length != 2) {
logger.trace("mDNS Could not identify Type / Device Id from '{}'", service.getName());
return null;
}
long did;
try {
did = Long.parseUnsignedLong(id[1]);
} catch (Exception e) {
logger.trace("mDNS Could not identify Device ID from '{}'", id[1]);
return null;
}
ThingTypeUID thingType = MiIoDevices.getType(id[0].replaceAll("-", ".")).getThingType();
String uidName = String.format("%08X", did);
logger.debug("mDNS {} identified as thingtype {} with did {} ({})", id[0], thingType, uidName, did);
return new ThingUID(thingType, uidName);
}
private @Nullable InetAddress getIpAddress(ServiceInfo service) {
InetAddress address = null;
for (InetAddress addr : service.getInet4Addresses()) {
return addr;
}
// Fallback for Inet6addresses
for (InetAddress addr : service.getInet6Addresses()) {
return addr;
}
return address;
}
@Override
public @Nullable DiscoveryResult createResult(ServiceInfo service) {
DiscoveryResult result = null;
ThingUID uid = getThingUID(service);
if (uid != null) {
Map<String, Object> properties = new HashMap<>(2);
// remove the domain from the name
InetAddress ip = getIpAddress(service);
if (ip == null) {
logger.debug("Mi IO mDNS Discovery could not determine ip address from service info: {}", service);
return null;
}
String inetAddress = ip.toString().substring(1); // trim leading slash
String id = uid.getId();
String label = "Xiaomi Mi Device " + id + " (" + Long.parseUnsignedLong(id, 16) + ") " + service.getName();
if (cloudConnector.isConnected()) {
cloudConnector.getDevicesList();
CloudDeviceDTO cloudInfo = cloudConnector.getDeviceInfo(id);
if (cloudInfo != null) {
logger.debug("Cloud Info: {}", cloudInfo);
properties.put(PROPERTY_TOKEN, cloudInfo.getToken());
label = label + " with token";
String country = cloudInfo.getServer();
if (!country.isEmpty() && cloudInfo.getIsOnline()) {
properties.put(PROPERTY_CLOUDSERVER, country);
}
}
}
properties.put(PROPERTY_HOST_IP, inetAddress);
properties.put(PROPERTY_DID, id);
result = DiscoveryResultBuilder.create(uid).withProperties(properties)
.withRepresentationProperty(PROPERTY_DID).withLabel(label).build();
logger.debug("Mi IO mDNS Discovery found {} with address '{}:{}' name '{}'", uid, inetAddress,
service.getPort(), label);
}
return result;
}
}

View File

@ -351,16 +351,21 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
}
@Nullable
String deviceId = configuration.deviceId;
if (deviceId.length() == 8 && deviceId.matches("^.*[a-zA-Z]+.*$")) {
logger.warn(
"As per openHAB version 3.2 the deviceId is no longer a string with hexadecimals, instead it is a string with the numeric respresentation of the deviceId. If you continue seeing this message, update deviceId in your thing configuration");
deviceId = "";
}
try {
if (deviceId.length() == 8 && tokenCheckPass(configuration.token)) {
final MiIoAsyncCommunication miioCom = new MiIoAsyncCommunication(configuration.host, token,
Utils.hexStringToByteArray(deviceId), lastId, configuration.timeout, cloudConnector);
if (!deviceId.isBlank() && tokenCheckPass(configuration.token)) {
final MiIoAsyncCommunication miioCom = new MiIoAsyncCommunication(configuration.host, token, deviceId,
lastId, configuration.timeout, cloudConnector);
if (getCloudServer().isBlank()) {
logger.debug("Ping Mi device {} at {}", deviceId, configuration.host);
logger.debug("Ping Mi deviceId '{}' at {}", deviceId, configuration.host);
Message miIoResponse = miioCom.sendPing(configuration.host);
if (miIoResponse != null) {
logger.debug("Ping response from device {} at {}. Time stamp: {}, OH time {}, delta {}",
Utils.getHex(miIoResponse.getDeviceId()), configuration.host,
logger.debug("Ping response from deviceId '{}' at {}. Time stamp: {}, OH time {}, delta {}",
Utils.fromHEX(Utils.getHex(miIoResponse.getDeviceId())), configuration.host,
miIoResponse.getTimestamp(), LocalDateTime.now(), miioCom.getTimeDelta());
miioCom.registerListener(this);
this.miioCom = miioCom;
@ -374,20 +379,17 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
return miioCom;
}
} else {
logger.debug("No device ID defined. Retrieving Mi device ID");
final MiIoAsyncCommunication miioCom = new MiIoAsyncCommunication(configuration.host, token,
new byte[0], lastId, configuration.timeout, cloudConnector);
logger.debug("No deviceId defined. Retrieving Mi deviceId");
final MiIoAsyncCommunication miioCom = new MiIoAsyncCommunication(configuration.host, token, "", lastId,
configuration.timeout, cloudConnector);
Message miIoResponse = miioCom.sendPing(configuration.host);
if (miIoResponse != null) {
logger.debug("Ping response from device {} at {}. Time stamp: {}, OH time {}, delta {}",
Utils.getHex(miIoResponse.getDeviceId()), configuration.host, miIoResponse.getTimestamp(),
LocalDateTime.now(), miioCom.getTimeDelta());
deviceId = Utils.getHex(miIoResponse.getDeviceId());
logger.debug("Ping response from device {} at {}. Time stamp: {}, OH time {}, delta {}", deviceId,
configuration.host, miIoResponse.getTimestamp(), LocalDateTime.now(),
deviceId = Utils.fromHEX(Utils.getHex(miIoResponse.getDeviceId()));
logger.debug("Ping response from deviceId '{}' at {}. Time stamp: {}, OH time {}, delta {}",
deviceId, configuration.host, miIoResponse.getTimestamp(), LocalDateTime.now(),
miioCom.getTimeDelta());
miioCom.setDeviceId(miIoResponse.getDeviceId());
logger.debug("Using retrieved Mi device ID: {}", deviceId);
miioCom.setDeviceId(deviceId);
logger.debug("Using retrieved Mi deviceId: {}", deviceId);
updateDeviceIdConfig(deviceId);
miioCom.registerListener(this);
this.miioCom = miioCom;
@ -396,7 +398,7 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
miioCom.close();
}
}
logger.debug("Ping response from device {} at {} FAILED", configuration.deviceId, configuration.host);
logger.debug("Ping response from deviceId '{}' at {} FAILED", configuration.deviceId, configuration.host);
disconnectedNoResponse();
return null;
} catch (IOException e) {
@ -413,7 +415,7 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
config.put(PROPERTY_DID, deviceId);
updateConfiguration(config);
} else {
logger.debug("Could not update config with device ID: {}", deviceId);
logger.debug("Could not update config with deviceId: {}", deviceId);
}
}
@ -529,10 +531,11 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
@Override
public void onMessageReceived(MiIoSendCommand response) {
logger.debug("Received response for {} type: {}, result: {}, fullresponse: {}", getThing().getUID().getId(),
response.getCommand(), response.getResult(), response.getResponse());
logger.debug("Received response for device {} type: {}, result: {}, fullresponse: {}",
getThing().getUID().getId(), response.getCommand(), response.getResult(), response.getResponse());
if (response.isError()) {
logger.debug("Error received: {}", response.getResponse().get("error"));
logger.debug("Error received for command '{}': {}.", response.getCommandString(),
response.getResponse().get("error"));
if (MiIoCommand.MIIO_INFO.equals(response.getCommand())) {
network.invalidateValue();
}

View File

@ -65,7 +65,7 @@ public class MiIoAsyncCommunication {
private final String ip;
private final byte[] token;
private byte[] deviceId;
private String deviceId;
private @Nullable DatagramSocket socket;
private List<MiIoMessageListener> listeners = new CopyOnWriteArrayList<>();
@ -85,7 +85,7 @@ public class MiIoAsyncCommunication {
private ConcurrentLinkedQueue<MiIoSendCommand> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
public MiIoAsyncCommunication(String ip, byte[] token, byte[] did, int id, int timeout,
public MiIoAsyncCommunication(String ip, byte[] token, String did, int id, int timeout,
CloudConnector cloudConnector) {
this.ip = ip;
this.token = token;
@ -156,7 +156,7 @@ public class MiIoAsyncCommunication {
// Obfuscate part of the token to allow sharing of the logfiles
String tokenText = Utils.obfuscateToken(Utils.getHex(token));
logger.debug("Command added to Queue {} -> {} (Device: {} token: {} Queue: {}).{}{}",
fullCommand.toString(), ip, Utils.getHex(deviceId), tokenText, concurrentLinkedQueue.size(),
fullCommand.toString(), ip, deviceId, tokenText, concurrentLinkedQueue.size(),
cloudServer.isBlank() ? "" : " Send via cloudserver: ", cloudServer);
}
if (needPing && cloudServer.isBlank()) {
@ -165,7 +165,7 @@ public class MiIoAsyncCommunication {
return cmdId;
} catch (JsonSyntaxException e) {
logger.warn("Send command '{}' with parameters {} -> {} (Device: {}) gave error {}", command, params, ip,
Utils.getHex(deviceId), e.getMessage());
deviceId, e.getMessage());
throw e;
}
}
@ -177,7 +177,7 @@ public class MiIoAsyncCommunication {
if (miIoSendCommand.getCloudServer().isBlank()) {
decryptedResponse = sendCommand(miIoSendCommand.getCommandString(), token, ip, deviceId);
} else {
decryptedResponse = cloudConnector.sendRPCCommand(Utils.getHex(deviceId),
decryptedResponse = cloudConnector.sendRPCCommand(Utils.getHexId(deviceId),
miIoSendCommand.getCloudServer(), miIoSendCommand);
logger.debug("Command {} send via cloudserver {}", miIoSendCommand.getCommandString(),
miIoSendCommand.getCloudServer());
@ -216,16 +216,15 @@ public class MiIoAsyncCommunication {
logger.debug("{}: {}", errorMsg, decryptedResponse);
} catch (MiIoCryptoException | IOException e) {
logger.debug("Send command '{}' -> {} (Device: {}) gave error {}", miIoSendCommand.getCommandString(), ip,
Utils.getHex(deviceId), e.getMessage());
deviceId, e.getMessage());
errorMsg = e.getMessage();
} catch (JsonSyntaxException e) {
logger.warn("Could not parse '{}' <- {} (Device: {}) gave error {}", decryptedResponse,
miIoSendCommand.getCommandString(), Utils.getHex(deviceId), e.getMessage());
miIoSendCommand.getCommandString(), deviceId, e.getMessage());
errorMsg = "Received message is invalid JSON";
} catch (MiCloudException e) {
logger.debug("Send command '{}' -> cloudserver '{}' (Device: {}) gave error {}",
miIoSendCommand.getCommandString(), miIoSendCommand.getCloudServer(), Utils.getHex(deviceId),
e.getMessage());
miIoSendCommand.getCommandString(), miIoSendCommand.getCloudServer(), deviceId, e.getMessage());
errorMsg = e.getMessage();
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
}
@ -288,22 +287,23 @@ public class MiIoAsyncCommunication {
}
}
private String sendCommand(String command, byte[] token, String ip, byte[] deviceId)
private String sendCommand(String command, byte[] token, String ip, String deviceId)
throws MiIoCryptoException, IOException {
byte[] sendMsg = new byte[0];
if (!command.isBlank()) {
byte[] encr;
encr = MiIoCrypto.encrypt(command.getBytes(StandardCharsets.UTF_8), token);
timeStamp = (int) Instant.now().getEpochSecond();
sendMsg = Message.createMsgData(encr, token, deviceId, timeStamp + timeDelta);
sendMsg = Message.createMsgData(encr, token, Utils.hexStringToByteArray(Utils.getHexId(deviceId)),
timeStamp + timeDelta);
}
Message miIoResponseMsg = sendData(sendMsg, ip);
if (miIoResponseMsg == null) {
if (logger.isTraceEnabled()) {
logger.trace("No response from device {} at {} for command {}.\r\n{}", Utils.getHex(deviceId), ip,
command, (new Message(sendMsg)).toSting());
logger.trace("No response from device {} at {} for command {}.\r\n{}", deviceId, ip, command,
(new Message(sendMsg)).toSting());
} else {
logger.debug("No response from device {} at {} for command {}.", Utils.getHex(deviceId), ip, command);
logger.debug("No response from device {} at {} for command {}.", deviceId, ip, command);
}
errorCounter++;
if (errorCounter > MAX_ERRORS) {
@ -330,7 +330,7 @@ public class MiIoAsyncCommunication {
public @Nullable Message sendPing(String ip) throws IOException {
for (int i = 0; i < 3; i++) {
logger.debug("Sending Ping {} ({})", Utils.getHex(deviceId), ip);
logger.debug("Sending Ping to device '{}' ({})", deviceId, ip);
Message resp = sendData(MiIoBindingConstants.DISCOVER_STRING, ip);
if (resp != null) {
pingSuccess();
@ -342,14 +342,14 @@ public class MiIoAsyncCommunication {
}
private void pingFail() {
logger.debug("Ping {} ({}) failed", Utils.getHex(deviceId), ip);
logger.debug("Ping to device '{}' ({}) failed", deviceId, ip);
connected = false;
status = ThingStatusDetail.COMMUNICATION_ERROR;
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
}
private void pingSuccess() {
logger.debug("Ping {} ({}) success", Utils.getHex(deviceId), ip);
logger.debug("Ping to device '{}' ({}) success", deviceId, ip);
if (!connected) {
connected = true;
status = ThingStatusDetail.NONE;
@ -476,11 +476,11 @@ public class MiIoAsyncCommunication {
return timeDelta;
}
public byte[] getDeviceId() {
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(byte[] deviceId) {
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}