return cl.sendRPCCommand(device, country.trim().toLowerCase(), command.getCommandString());
}
+ public String sendCloudCommand(String urlPart, String country, String parameters) throws MiCloudException {
+ final @Nullable MiCloudConnector cl = this.cloudConnector;
+ if (cl == null || !isConnected()) {
+ throw new MiCloudException("Cannot execute request. Cloud service not available");
+ }
+ return cl.request(urlPart, country, parameters);
+ }
+
public @Nullable RawType getMap(String mapId, String country) throws MiCloudException {
logger.debug("Getting vacuum map {} from Xiaomi cloud server: '{}'", mapId, country);
String mapCountry;
public String getDeviceString(String country) {
String resp;
try {
- resp = request("/home/device_list", country, "{\"getVirtualModel\":false,\"getHuamiDevices\":0}");
+ resp = request("/home/device_list_page", country, "{\"getVirtualModel\":false,\"getHuamiDevices\":1}");
logger.trace("Get devices response: {}", resp);
if (resp.length() > 2) {
CloudUtil.saveDeviceInfoFile(resp, country, logger);
String url = urlPart.trim();
url = getApiUrl(country) + (url.startsWith("/app") ? url.substring(4) : url);
String response = request(url, params);
- logger.debug("Request to {} server {}. Response: {}", country, urlPart, response);
+ logger.debug("Request to '{}' server '{}'. Response: '{}'", country, urlPart, response);
return response;
}
}
loginFailedCounterCheck();
startClient();
- logger.debug("Send request: {} to {}", params.get("data"), url);
+ logger.debug("Send request to {} with data '{}'", url, params.get("data"));
Request request = httpClient.newRequest(url).timeout(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
request.agent(USERAGENT);
request.header("x-xiaomi-protocal-flag-cli", "PROTOCAL-HTTP2");
protected boolean handleCommandsChannels(ChannelUID channelUID, Command command) {
if (channelUID.getId().equals(CHANNEL_COMMAND)) {
- cmds.put(sendCommand(command.toString(), ""), command.toString());
+ cmds.put(sendCommand(command.toString()), channelUID.getId());
return true;
}
if (channelUID.getId().equals(CHANNEL_RPC)) {
- cmds.put(sendCommand(command.toString(), cloudServer), command.toString());
+ cmds.put(sendCommand(command.toString(), cloudServer), channelUID.getId());
return true;
}
return false;
break;
}
if (cmds.containsKey(response.getId())) {
- if (response.getCloudServer().isBlank()) {
- updateState(CHANNEL_COMMAND, new StringType(response.getResponse().toString()));
- } else {
- updateState(CHANNEL_RPC, new StringType(response.getResponse().toString()));
+ String channel = cmds.get(response.getId());
+ if (channel != null && (CHANNEL_COMMAND.contentEquals(channel) || CHANNEL_RPC.contentEquals(channel))) {
+ updateState(channel, new StringType(response.getResponse().toString()));
+ cmds.remove(response.getId());
}
- cmds.remove(response.getId());
}
} catch (Exception e) {
logger.debug("Error while handing message {}", response.getResponse(), e);
getThing().getUID());
continue;
}
- sendCommand(miChannel.getChannelCustomRefreshCommand());
+ String cmd = miChannel.getChannelCustomRefreshCommand();
+ if (!cmd.startsWith("/")) {
+ cmds.put(sendCommand(miChannel.getChannelCustomRefreshCommand()), miChannel.getChannel());
+ } else {
+ if (cloudServer.isBlank()) {
+ logger.debug("Cloudserver empty. Skipping refresh for {} channel '{}'", getThing().getUID(),
+ miChannel.getChannel());
+ } else {
+ cmds.put(sendCommand(cmd, cloudServer), miChannel.getChannel());
+ }
+ }
}
}
return null;
}
+ private @Nullable MiIoBasicChannel getCustomRefreshChannel(String channelName) {
+ for (MiIoBasicChannel refreshEntry : refreshListCustomCommands.values()) {
+ if (refreshEntry.getChannel().equals(channelName)) {
+ return refreshEntry;
+ }
+ }
+ logger.trace("Did not find channel for {} in {}", channelName, refreshList);
+ return null;
+ }
+
private void updatePropsFromJsonArray(MiIoSendCommand response) {
JsonArray res = response.getResult().getAsJsonArray();
JsonArray para = JsonParser.parseString(response.getCommandString()).getAsJsonObject().get("params")
}
break;
default:
- if (refreshListCustomCommands.containsKey(response.getMethod())) {
+ String channel = cmds.get(response.getId());
+ if (channel != null) {
logger.debug("Processing custom refresh command response for '{}' - {}", response.getMethod(),
response.getResult());
- final MiIoBasicChannel ch = refreshListCustomCommands.get(response.getMethod());
+ final MiIoBasicChannel ch = getCustomRefreshChannel(channel);
if (ch != null) {
if (response.getResult().isJsonArray()) {
JsonArray cmdResponse = response.getResult().getAsJsonArray();
updateChannel(ch, ch.getChannel(), new JsonPrimitive(response.getResult().toString()));
}
}
+ cmds.remove(response.getId());
}
break;
}
if (cmdId > MAX_ID) {
id.set(0);
}
- fullCommand.addProperty("id", cmdId);
- fullCommand.addProperty("method", command);
- fullCommand.add("params", JsonParser.parseString(params));
+ if (command.startsWith("{") && command.endsWith("}")) {
+ fullCommand = JsonParser.parseString(command).getAsJsonObject();
+ fullCommand.addProperty("id", cmdId);
+ if (!fullCommand.has("params") && !params.isBlank()) {
+ fullCommand.add("params", JsonParser.parseString(params));
+ }
+ } else {
+ fullCommand.addProperty("id", cmdId);
+ fullCommand.addProperty("method", command);
+ fullCommand.add("params", JsonParser.parseString(params));
+ }
MiIoSendCommand sendCmd = new MiIoSendCommand(cmdId, MiIoCommand.getCommand(command), fullCommand,
cloudServer);
concurrentLinkedQueue.add(sendCmd);
sendPing(ip);
}
return cmdId;
- } catch (JsonSyntaxException e) {
+ } catch (JsonSyntaxException | IllegalStateException e) {
logger.warn("Send command '{}' with parameters {} -> {} (Device: {}) gave error {}", command, params, ip,
deviceId, e.getMessage());
throw e;
if (miIoSendCommand.getCloudServer().isBlank()) {
decryptedResponse = sendCommand(miIoSendCommand.getCommandString(), token, ip, deviceId);
} else {
- decryptedResponse = cloudConnector.sendRPCCommand(Utils.getHexId(deviceId),
- miIoSendCommand.getCloudServer(), miIoSendCommand);
- logger.debug("Command {} send via cloudserver {}", miIoSendCommand.getCommandString(),
- miIoSendCommand.getCloudServer());
- updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
+ if (!miIoSendCommand.getMethod().startsWith("/")) {
+ decryptedResponse = cloudConnector.sendRPCCommand(Utils.getHexId(deviceId),
+ miIoSendCommand.getCloudServer(), miIoSendCommand);
+ logger.debug("Command {} send via cloudserver {}", miIoSendCommand.getCommandString(),
+ miIoSendCommand.getCloudServer());
+ updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
+ } else {
+ String data = miIoSendCommand.getParams().isJsonArray()
+ && miIoSendCommand.getParams().getAsJsonArray().size() > 0
+ ? miIoSendCommand.getParams().getAsJsonArray().get(0).toString()
+ : "";
+ logger.debug("Custom cloud request send to url '{}' with data '{}'", miIoSendCommand.getMethod(),
+ data);
+ decryptedResponse = cloudConnector.sendCloudCommand(miIoSendCommand.getMethod(),
+ miIoSendCommand.getCloudServer(), data);
+ miIoSendCommand.setResponse(JsonParser.parseString(decryptedResponse).getAsJsonObject());
+ return miIoSendCommand;
+ }
}
// hack due to avoid invalid json errors from some misbehaving device firmwares
decryptedResponse = decryptedResponse.replace(",,", ",");