diff --git a/bundles/org.openhab.binding.miio/README.base.md b/bundles/org.openhab.binding.miio/README.base.md index dc998c7e7722..ec6771736d59 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 13af3ae7186b..75b2dd26b6f0 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 00d141f628b4..bb7ec557cce7 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 static String fromHEX(String value) { } 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 a64dfae41a9d..9e974d799144 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 List getDevicesList() { 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 491766eec324..66ddd15d51c1 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 @@ private void cloudDiscovery() { 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 @@ private void cloudDiscovery() { 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 @@ private void discovered(String ip, byte[] response) { 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 @@ private void discovered(String ip, byte[] response) { 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 @@ private void discovered(String ip, byte[] response) { } 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 cd9a8c6457ea..000000000000 --- 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 21df3ea3625e..b14d6ddaa1e4 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 @@ protected void disconnected(@Nullable String message) { } @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 @@ protected void disconnected(@Nullable String message) { 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 @@ protected void disconnected(@Nullable String message) { 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 @@ private void updateDeviceIdConfig(String deviceId) { 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 void onStatusUpdated(ThingStatus status, ThingStatusDetail statusDetail) @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 f4ebe2ce2739..bc0335865e21 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 int queueCommand(String command, String params, String cloudServer) // 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 int queueCommand(String command, String params, String cloudServer) 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 @@ MiIoSendCommand sendMiIoSendCommand(MiIoSendCommand miIoSendCommand) { 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 @@ MiIoSendCommand sendMiIoSendCommand(MiIoSendCommand miIoSendCommand) { 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 void run() { } } - 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 @@ private String sendCommand(String command, byte[] token, String ip, byte[] devic 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 @@ private String sendCommand(String command, byte[] token, String ip, byte[] devic } 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 int getTimeDelta() { return timeDelta; } - public byte[] getDeviceId() { + public String getDeviceId() { return deviceId; } - public void setDeviceId(byte[] deviceId) { + public void setDeviceId(String deviceId) { this.deviceId = deviceId; }