From 7d2db9866236a16a4f8d9f3ebc3d43c30ea28baf Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 6 Jul 2021 19:42:42 +0200 Subject: [PATCH] [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 * Update bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoAbstractHandler.java Signed-off-by: Fabian Wolter Co-authored-by: Fabian Wolter --- .../org.openhab.binding.miio/README.base.md | 6 +- bundles/org.openhab.binding.miio/README.md | 6 +- .../openhab/binding/miio/internal/Utils.java | 13 ++ .../miio/internal/cloud/CloudConnector.java | 3 +- .../internal/discovery/MiIoDiscovery.java | 17 ++- .../discovery/MiIoDiscoveryParticipant.java | 142 ------------------ .../internal/handler/MiIoAbstractHandler.java | 47 +++--- .../transport/MiIoAsyncCommunication.java | 38 ++--- 8 files changed, 73 insertions(+), 199 deletions(-) delete mode 100644 bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/discovery/MiIoDiscoveryParticipant.java diff --git a/bundles/org.openhab.binding.miio/README.base.md b/bundles/org.openhab.binding.miio/README.base.md index dc998c7e7..ec6771736 100644 --- a/bundles/org.openhab.binding.miio/README.base.md +++ b/bundles/org.openhab.binding.miio/README.base.md @@ -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 diff --git a/bundles/org.openhab.binding.miio/README.md b/bundles/org.openhab.binding.miio/README.md index 13af3ae71..75b2dd26b 100644 --- a/bundles/org.openhab.binding.miio/README.md +++ b/bundles/org.openhab.binding.miio/README.md @@ -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 diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/Utils.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/Utils.java index 00d141f62..bb7ec557c 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/Utils.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/Utils.java @@ -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; + } } diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/cloud/CloudConnector.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/cloud/CloudConnector.java index a64dfae41..9e974d799 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/cloud/CloudConnector.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/cloud/CloudConnector.java @@ -208,10 +208,9 @@ public class CloudConnector { if (deviceListState != DeviceListState.AVAILABLE) { return null; } - String did = Long.toString(Long.parseUnsignedLong(id, 16)); List devicedata = new ArrayList<>(); for (CloudDeviceDTO deviceDetails : deviceList) { - if (deviceDetails.getDid().contentEquals(did)) { + if (deviceDetails.getDid().contentEquals(id)) { devicedata.add(deviceDetails); } } diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/discovery/MiIoDiscovery.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/discovery/MiIoDiscovery.java index 491766eec..66ddd15d5 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/discovery/MiIoDiscovery.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/discovery/MiIoDiscovery.java @@ -184,7 +184,7 @@ public class MiIoDiscovery extends AbstractDiscoveryService { if (cloudConnector.isConnected()) { List 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"); diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/discovery/MiIoDiscoveryParticipant.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/discovery/MiIoDiscoveryParticipant.java deleted file mode 100644 index cd9a8c645..000000000 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/discovery/MiIoDiscoveryParticipant.java +++ /dev/null @@ -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 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 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; - } -} diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoAbstractHandler.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoAbstractHandler.java index 21df3ea36..b14d6ddaa 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoAbstractHandler.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoAbstractHandler.java @@ -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(); } diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/transport/MiIoAsyncCommunication.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/transport/MiIoAsyncCommunication.java index f4ebe2ce2..bc0335865 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/transport/MiIoAsyncCommunication.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/transport/MiIoAsyncCommunication.java @@ -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 listeners = new CopyOnWriteArrayList<>(); @@ -85,7 +85,7 @@ public class MiIoAsyncCommunication { private ConcurrentLinkedQueue 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; }