// Basic device commands
GET_PROPERTY("get_prop"),
GET_PROPERTIES("get_properties"),
+ GET_DEVICE_PROPERTY_EXP("get_device_prop_exp"),
+ GET_DEVICE_PROPERTY("get_device_prop"),
GET_VALUE("get_value"),
SET_PROPERTIES("set_properties"),
SET_MODE_BASIC("set_mode"),
*/
package org.openhab.binding.miio.internal;
-import static org.openhab.core.library.unit.MetricPrefix.MILLI;
+import static org.openhab.core.library.unit.MetricPrefix.*;
import java.util.Arrays;
import java.util.HashMap;
CELSIUS(SIUnits.CELSIUS, "C", "celcius"),
FAHRENHEIT(ImperialUnits.FAHRENHEIT),
KELVIN(Units.KELVIN, "K"),
- PASCAL(SIUnits.PASCAL),
+ PASCAL(SIUnits.PASCAL, "pa"),
+ HPA(HECTO(SIUnits.PASCAL)),
SECOND(Units.SECOND, "seconds"),
MINUTE(Units.MINUTE, "minutes"),
HOUR(Units.HOUR, "hours"),
--- /dev/null
+/**
+ * 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;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Storing last id to to be able to reconnect better after binding restart
+ *
+ * @author Marcel Verpaalen - Initial contribution
+ */
+@NonNullByDefault
+public class SavedDeviceInfoDTO {
+
+ @SerializedName("lastId")
+ @Expose
+ private int lastId = 0;
+ @SerializedName("deviceId")
+ @Expose
+ private String deviceId;
+
+ public SavedDeviceInfoDTO(int lastId, String deviceId) {
+ super();
+ this.lastId = lastId;
+ this.deviceId = deviceId;
+ }
+
+ public int getLastId() {
+ return lastId;
+ }
+
+ public void setLastId(int lastId) {
+ this.lastId = lastId;
+ }
+
+ public String getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(String deviceId) {
+ this.deviceId = deviceId;
+ }
+}
*/
package org.openhab.binding.miio.internal;
+import static org.openhab.binding.miio.internal.MiIoBindingConstants.BINDING_USERDATA_PATH;
+
+import java.io.File;
+import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.NoSuchFileException;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.slf4j.Logger;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
}
}
+ /**
+ * Saves string to file in userdata folder
+ *
+ * @param filename
+ * @param string with content
+ * @param logger
+ */
+ public static void saveToFile(String filename, String data, Logger logger) {
+ File folder = new File(BINDING_USERDATA_PATH);
+ if (!folder.exists()) {
+ folder.mkdirs();
+ }
+ File dataFile = new File(folder, filename);
+ try (FileWriter writer = new FileWriter(dataFile)) {
+ writer.write(data);
+ logger.debug("Saved to {}", dataFile.getAbsolutePath());
+ } catch (IOException e) {
+ logger.debug("Failed to write file '{}': {}", dataFile.getName(), e.getMessage());
+ }
+ }
+
public static String minLengthString(String string, int length) {
return String.format("%-" + length + "s", string);
}
ONOFFBOOL("onoffbool"),
ONOFFBOOLSTRING("onoffboolstring"),
ONOFFNUMBER("onoffnumber"),
+ OPENCLOSENUMBER("openclosenumber"),
+ OPENCLOSE("openclose"),
STRING("string"),
CUSTOMSTRING("customstring"),
NUMBER("number"),
if (cl == null || !isConnected()) {
throw new MiCloudException("Cannot execute request. Cloud service not available");
}
- return cl.request(urlPart, country, parameters);
+ return cl.request(urlPart.startsWith("/") ? urlPart : "/" + urlPart, country, parameters);
}
public @Nullable RawType getMap(String mapId, String country) throws MiCloudException {
public String getDeviceString(String country) {
String resp;
try {
- resp = request("/home/device_list_page", country, "{\"getVirtualModel\":false,\"getHuamiDevices\":1}");
+ resp = request("/home/device_list_page", country, "{\"getVirtualModel\":true,\"getHuamiDevices\":1}");
logger.trace("Get devices response: {}", resp);
if (resp.length() > 2) {
CloudUtil.saveDeviceInfoFile(resp, country, logger);
import static org.openhab.binding.miio.internal.MiIoBindingConstants.*;
+import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.HashMap;
import org.openhab.binding.miio.internal.MiIoInfoDTO;
import org.openhab.binding.miio.internal.MiIoMessageListener;
import org.openhab.binding.miio.internal.MiIoSendCommand;
+import org.openhab.binding.miio.internal.SavedDeviceInfoDTO;
import org.openhab.binding.miio.internal.Utils;
import org.openhab.binding.miio.internal.basic.MiIoDatabaseWatchService;
import org.openhab.binding.miio.internal.cloud.CloudConnector;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
isIdentified = false;
deviceVariables.put(TIMESTAMP, Instant.now().getEpochSecond());
deviceVariables.put(PROPERTY_DID, configuration.deviceId);
+ try {
+ URL url = new File(BINDING_USERDATA_PATH, "info_" + getThing().getUID().getId() + ".json").toURI().toURL();
+ SavedDeviceInfoDTO lastIdInfo = GSON.fromJson(Utils.convertFileToJSON(url), SavedDeviceInfoDTO.class);
+ if (lastIdInfo != null) {
+ lastId = lastIdInfo.getLastId();
+ logger.debug("Last Id set to {} for {}", lastId, getThing().getUID());
+ }
+ } catch (JsonParseException | IOException | URISyntaxException e) {
+ logger.debug("Could not read last connection id for {} : {}", getThing().getUID(), e.getMessage());
+ }
+
miIoScheduler.schedule(this::initializeData, 1, TimeUnit.SECONDS);
int pollingPeriod = configuration.refreshInterval;
if (pollingPeriod > 0) {
this.miioCom = null;
}
miIoScheduler.shutdownNow();
+ logger.debug("Last Id saved for {}: {} -> {} ", getThing().getUID(), lastId,
+ GSON.toJson(new SavedDeviceInfoDTO(lastId,
+ (String) deviceVariables.getOrDefault(PROPERTY_DID, getThing().getUID().getId()))));
+ Utils.saveToFile("info_" + getThing().getUID().getId() + ".json", GSON.toJson(new SavedDeviceInfoDTO(lastId,
+ (String) deviceVariables.getOrDefault(PROPERTY_DID, getThing().getUID().getId()))), logger);
}
protected int sendCommand(MiIoCommand command) {
/**
* This is used to execute arbitrary commands by sending to the commands channel. Command parameters to be added
- * between
- * [] brackets. This to allow for unimplemented commands to be executed (e.g. get detailed historical cleaning
- * records)
+ * between [] brackets. This to allow for unimplemented commands to be executed
*
* @param commandString command to be executed
* @param cloud server to be used or empty string for direct sending to the device
- * @return vacuum response
+ * @return message id
*/
protected int sendCommand(String commandString, String cloudServer) {
String command = commandString.trim();
return 0;
}
- String getCloudServer() {
+ public String getCloudServer() {
// This can be improved in the future with additional / more advanced options like e.g. directFirst which would
// use direct communications and in case of failures fall back to cloud communication. For now we keep it
// simple and only have the option for cloud or direct.