[miio] new gen vacuums cleaning map and rooms (#15675)
* Room Mapping from cloud * New history record Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com>
This commit is contained in:
parent
09501d59c4
commit
b7ff168b18
@ -100,6 +100,8 @@ public final class MiIoBindingConstants {
|
|||||||
public static final String CHANNEL_HISTORY_DURATION = "cleaning#last_clean_duration";
|
public static final String CHANNEL_HISTORY_DURATION = "cleaning#last_clean_duration";
|
||||||
public static final String CHANNEL_HISTORY_ERROR = "cleaning#last_clean_error";
|
public static final String CHANNEL_HISTORY_ERROR = "cleaning#last_clean_error";
|
||||||
public static final String CHANNEL_HISTORY_FINISH = "cleaning#last_clean_finish";
|
public static final String CHANNEL_HISTORY_FINISH = "cleaning#last_clean_finish";
|
||||||
|
public static final String CHANNEL_HISTORY_FINISHREASON = "cleaning#last_clean_finish_reason";
|
||||||
|
public static final String CHANNEL_HISTORY_DUSTCOLLECTION = "cleaning#last_clean_dustcollection_status";
|
||||||
public static final String CHANNEL_HISTORY_RECORD = "cleaning#last_clean_record";
|
public static final String CHANNEL_HISTORY_RECORD = "cleaning#last_clean_record";
|
||||||
public static final String CHANNEL_VACUUM_MAP = "cleaning#map";
|
public static final String CHANNEL_VACUUM_MAP = "cleaning#map";
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,11 @@ import static org.openhab.binding.miio.internal.MiIoBindingConstants.BINDING_ID;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
@ -33,7 +36,11 @@ import org.osgi.service.component.annotations.Reference;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link CloudConnector} is responsible for connecting OH to the Xiaomi cloud communication.
|
* The {@link CloudConnector} is responsible for connecting OH to the Xiaomi cloud communication.
|
||||||
@ -46,14 +53,15 @@ public class CloudConnector {
|
|||||||
|
|
||||||
private static final long CACHE_EXPIRY = TimeUnit.SECONDS.toMillis(60);
|
private static final long CACHE_EXPIRY = TimeUnit.SECONDS.toMillis(60);
|
||||||
|
|
||||||
private enum DeviceListState {
|
private enum CloudListState {
|
||||||
FAILED,
|
FAILED,
|
||||||
STARTING,
|
STARTING,
|
||||||
REFRESHING,
|
REFRESHING,
|
||||||
AVAILABLE,
|
AVAILABLE,
|
||||||
}
|
}
|
||||||
|
|
||||||
private volatile DeviceListState deviceListState = DeviceListState.STARTING;
|
private volatile CloudListState deviceListState = CloudListState.STARTING;
|
||||||
|
private volatile CloudListState homeListState = CloudListState.STARTING;
|
||||||
|
|
||||||
private String username = "";
|
private String username = "";
|
||||||
private String password = "";
|
private String password = "";
|
||||||
@ -64,19 +72,22 @@ public class CloudConnector {
|
|||||||
private @Nullable MiCloudConnector cloudConnector;
|
private @Nullable MiCloudConnector cloudConnector;
|
||||||
private final Logger logger = LoggerFactory.getLogger(CloudConnector.class);
|
private final Logger logger = LoggerFactory.getLogger(CloudConnector.class);
|
||||||
|
|
||||||
|
private ConcurrentHashMap<@NonNull String, @NonNull HomeListDTO> homeLists = new ConcurrentHashMap<>();
|
||||||
|
private static final Gson GSON = new GsonBuilder().serializeNulls().create();
|
||||||
|
|
||||||
private ExpiringCache<Boolean> logonCache = new ExpiringCache<Boolean>(CACHE_EXPIRY, () -> {
|
private ExpiringCache<Boolean> logonCache = new ExpiringCache<Boolean>(CACHE_EXPIRY, () -> {
|
||||||
return logon();
|
return logon();
|
||||||
});
|
});
|
||||||
|
|
||||||
private ExpiringCache<String> refreshDeviceList = new ExpiringCache<String>(CACHE_EXPIRY, () -> {
|
private ExpiringCache<String> refreshDeviceList = new ExpiringCache<String>(CACHE_EXPIRY, () -> {
|
||||||
if (deviceListState == DeviceListState.FAILED && !isConnected()) {
|
if (deviceListState == CloudListState.FAILED && !isConnected()) {
|
||||||
return ("Could not connect to Xiaomi cloud");
|
return ("Could not connect to Xiaomi cloud");
|
||||||
}
|
}
|
||||||
final @Nullable MiCloudConnector cl = this.cloudConnector;
|
final @Nullable MiCloudConnector cl = this.cloudConnector;
|
||||||
if (cl == null) {
|
if (cl == null) {
|
||||||
return ("Could not connect to Xiaomi cloud");
|
return ("Could not connect to Xiaomi cloud");
|
||||||
}
|
}
|
||||||
deviceListState = DeviceListState.REFRESHING;
|
deviceListState = CloudListState.REFRESHING;
|
||||||
deviceList.clear();
|
deviceList.clear();
|
||||||
for (String server : country.split(",")) {
|
for (String server : country.split(",")) {
|
||||||
try {
|
try {
|
||||||
@ -85,10 +96,48 @@ public class CloudConnector {
|
|||||||
logger.debug("Parsing error getting devices: {}", e.getMessage());
|
logger.debug("Parsing error getting devices: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deviceListState = DeviceListState.AVAILABLE;
|
deviceListState = CloudListState.AVAILABLE;
|
||||||
return "done";// deviceList;
|
return "done";// deviceList;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private ExpiringCache<String> refreshHomeList = new ExpiringCache<String>(CACHE_EXPIRY, () -> {
|
||||||
|
if (homeListState == CloudListState.FAILED && !isConnected()) {
|
||||||
|
return ("Could not connect to Xiaomi cloud");
|
||||||
|
}
|
||||||
|
final @Nullable MiCloudConnector cl = this.cloudConnector;
|
||||||
|
if (cl == null) {
|
||||||
|
return ("Could not connect to Xiaomi cloud");
|
||||||
|
}
|
||||||
|
boolean isStarting = homeListState == CloudListState.STARTING;
|
||||||
|
homeListState = CloudListState.REFRESHING;
|
||||||
|
for (String server : country.split(",")) {
|
||||||
|
try {
|
||||||
|
updateHomeList(server);
|
||||||
|
} catch (JsonParseException e) {
|
||||||
|
logger.debug("Parsing error getting home details: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
homeListState = CloudListState.AVAILABLE;
|
||||||
|
if (isStarting) {
|
||||||
|
printHomesandRooms();
|
||||||
|
}
|
||||||
|
return "done";// deviceList;
|
||||||
|
});
|
||||||
|
|
||||||
|
private void printHomesandRooms() {
|
||||||
|
for (Entry<String, HomeListDTO> countryHome : homeLists.entrySet()) {
|
||||||
|
String server = countryHome.getKey();
|
||||||
|
final HomeListDTO homelist = countryHome.getValue();
|
||||||
|
for (HomeDTO home : homelist.getHomelist()) {
|
||||||
|
logger.debug("Server: {}, Home id: {}, Name {}", server, home.getId(), home.getName());
|
||||||
|
for (HomeRoomDTO room : home.getRoomlist()) {
|
||||||
|
logger.debug("Server: {}, Home id: {}, Room id: {}, Name {}", server, home.getId(), room.getId(),
|
||||||
|
room.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
public CloudConnector(@Reference HttpClientFactory httpClientFactory) {
|
public CloudConnector(@Reference HttpClientFactory httpClientFactory) {
|
||||||
this.httpClient = httpClientFactory.createHttpClient(BINDING_ID);
|
this.httpClient = httpClientFactory.createHttpClient(BINDING_ID);
|
||||||
@ -119,7 +168,7 @@ public class CloudConnector {
|
|||||||
if (c != null && c.booleanValue()) {
|
if (c != null && c.booleanValue()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
deviceListState = DeviceListState.FAILED;
|
deviceListState = CloudListState.FAILED;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +188,21 @@ public class CloudConnector {
|
|||||||
return cl.request(urlPart.startsWith("/") ? urlPart : "/" + urlPart, country, parameters);
|
return cl.request(urlPart.startsWith("/") ? urlPart : "/" + urlPart, country, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateHomeList(String country) {
|
||||||
|
final @Nullable MiCloudConnector cl = this.cloudConnector;
|
||||||
|
if (isConnected() && cl != null) {
|
||||||
|
try {
|
||||||
|
JsonObject homelistInfo = cl.getHomeList(country.trim().toLowerCase());
|
||||||
|
final HomeListDTO homelist = GSON.fromJson(homelistInfo, HomeListDTO.class);
|
||||||
|
if (homelist != null && homelist.getHomelist() != null && homelist.getHomelist().size() > 0) {
|
||||||
|
homeLists.put(country, homelist);
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
logger.debug("Home List / Room info could not be updated for server '{}': {}", country, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable RawType getMap(String mapId, String country) throws MiCloudException {
|
public @Nullable RawType getMap(String mapId, String country) throws MiCloudException {
|
||||||
logger.debug("Getting vacuum map {} from Xiaomi cloud server: '{}'", mapId, country);
|
logger.debug("Getting vacuum map {} from Xiaomi cloud server: '{}'", mapId, country);
|
||||||
String mapCountry;
|
String mapCountry;
|
||||||
@ -203,11 +267,11 @@ public class CloudConnector {
|
|||||||
if (connected) {
|
if (connected) {
|
||||||
getDevicesList();
|
getDevicesList();
|
||||||
} else {
|
} else {
|
||||||
deviceListState = DeviceListState.FAILED;
|
deviceListState = CloudListState.FAILED;
|
||||||
}
|
}
|
||||||
} catch (MiCloudException e) {
|
} catch (MiCloudException e) {
|
||||||
connected = false;
|
connected = false;
|
||||||
deviceListState = DeviceListState.FAILED;
|
deviceListState = CloudListState.FAILED;
|
||||||
logger.debug("Xiaomi cloud login failed: {}", e.getMessage());
|
logger.debug("Xiaomi cloud login failed: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
return connected;
|
return connected;
|
||||||
@ -220,7 +284,7 @@ public class CloudConnector {
|
|||||||
|
|
||||||
public @Nullable CloudDeviceDTO getDeviceInfo(String id) {
|
public @Nullable CloudDeviceDTO getDeviceInfo(String id) {
|
||||||
getDevicesList();
|
getDevicesList();
|
||||||
if (deviceListState != DeviceListState.AVAILABLE) {
|
if (deviceListState != CloudListState.AVAILABLE) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
List<CloudDeviceDTO> devicedata = new ArrayList<>();
|
List<CloudDeviceDTO> devicedata = new ArrayList<>();
|
||||||
@ -243,4 +307,61 @@ public class CloudConnector {
|
|||||||
}
|
}
|
||||||
return devicedata.get(0);
|
return devicedata.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HomeListDTO getHomeList(String server) {
|
||||||
|
refreshHomeList.getValue();
|
||||||
|
return homeLists.getOrDefault(server, new HomeListDTO());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrentHashMap<String, HomeListDTO> getHomeLists() {
|
||||||
|
refreshHomeList.getValue();
|
||||||
|
return homeLists;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the room from the cloud given the room Id and country server
|
||||||
|
*
|
||||||
|
* @param room id
|
||||||
|
* @param country
|
||||||
|
* @return room
|
||||||
|
*/
|
||||||
|
|
||||||
|
public @Nullable HomeRoomDTO getRoom(String id, String country) {
|
||||||
|
@Nullable
|
||||||
|
HomeListDTO homeList = homeLists.getOrDefault(country, new HomeListDTO());
|
||||||
|
if (homeList.getHomelist() != null) {
|
||||||
|
for (HomeDTO home : homeList.getHomelist()) {
|
||||||
|
for (HomeRoomDTO room : home.getRoomlist()) {
|
||||||
|
if (room.getId().contentEquals(id)) {
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the room from the cloud given the room Id
|
||||||
|
*
|
||||||
|
* @param room id
|
||||||
|
* @return room
|
||||||
|
*/
|
||||||
|
public @Nullable HomeRoomDTO getRoom(String id) {
|
||||||
|
return getRoom(id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable HomeRoomDTO getRoom(String id, boolean retry) {
|
||||||
|
for (Entry<String, HomeListDTO> countryHome : homeLists.entrySet()) {
|
||||||
|
HomeRoomDTO room = getRoom(id, countryHome.getKey());
|
||||||
|
if (room != null) {
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (retry) {
|
||||||
|
refreshHomeList.getValue();
|
||||||
|
return getRoom(id, false);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,269 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.cloud;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO class wraps the home json structure
|
||||||
|
*
|
||||||
|
* @author Marcel Verpaalen - Initial contribution
|
||||||
|
*/
|
||||||
|
public class HomeDTO {
|
||||||
|
|
||||||
|
@SerializedName("id")
|
||||||
|
@Expose
|
||||||
|
private String id;
|
||||||
|
@SerializedName("name")
|
||||||
|
@Expose
|
||||||
|
private String name;
|
||||||
|
@SerializedName("bssid")
|
||||||
|
@Expose
|
||||||
|
private String bssid;
|
||||||
|
@SerializedName("dids")
|
||||||
|
@Expose
|
||||||
|
private List<String> dids;
|
||||||
|
@SerializedName("temp_dids")
|
||||||
|
@Expose
|
||||||
|
private Object tempDids;
|
||||||
|
@SerializedName("icon")
|
||||||
|
@Expose
|
||||||
|
private String icon;
|
||||||
|
@SerializedName("shareflag")
|
||||||
|
@Expose
|
||||||
|
private Integer shareflag;
|
||||||
|
@SerializedName("permit_level")
|
||||||
|
@Expose
|
||||||
|
private Integer permitLevel;
|
||||||
|
@SerializedName("status")
|
||||||
|
@Expose
|
||||||
|
private Integer status;
|
||||||
|
@SerializedName("background")
|
||||||
|
@Expose
|
||||||
|
private String background;
|
||||||
|
@SerializedName("smart_room_background")
|
||||||
|
@Expose
|
||||||
|
private String smartRoomBackground;
|
||||||
|
@SerializedName("longitude")
|
||||||
|
@Expose
|
||||||
|
private Integer longitude;
|
||||||
|
@SerializedName("latitude")
|
||||||
|
@Expose
|
||||||
|
private Integer latitude;
|
||||||
|
@SerializedName("city_id")
|
||||||
|
@Expose
|
||||||
|
private Integer cityId;
|
||||||
|
@SerializedName("address")
|
||||||
|
@Expose
|
||||||
|
private String address;
|
||||||
|
@SerializedName("create_time")
|
||||||
|
@Expose
|
||||||
|
private Integer createTime;
|
||||||
|
@SerializedName("roomlist")
|
||||||
|
@Expose
|
||||||
|
private List<HomeRoomDTO> roomlist;
|
||||||
|
@SerializedName("uid")
|
||||||
|
@Expose
|
||||||
|
private Integer uid;
|
||||||
|
@SerializedName("appear_home_list")
|
||||||
|
@Expose
|
||||||
|
private Object appearHomeList;
|
||||||
|
@SerializedName("popup_flag")
|
||||||
|
@Expose
|
||||||
|
private Integer popupFlag;
|
||||||
|
@SerializedName("popup_time_stamp")
|
||||||
|
@Expose
|
||||||
|
private Integer popupTimeStamp;
|
||||||
|
@SerializedName("car_did")
|
||||||
|
@Expose
|
||||||
|
private String carDid;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBssid() {
|
||||||
|
return bssid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBssid(String bssid) {
|
||||||
|
this.bssid = bssid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getDids() {
|
||||||
|
return dids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDids(List<String> dids) {
|
||||||
|
this.dids = dids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getTempDids() {
|
||||||
|
return tempDids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTempDids(Object tempDids) {
|
||||||
|
this.tempDids = tempDids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIcon(String icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getShareflag() {
|
||||||
|
return shareflag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShareflag(Integer shareflag) {
|
||||||
|
this.shareflag = shareflag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPermitLevel() {
|
||||||
|
return permitLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermitLevel(Integer permitLevel) {
|
||||||
|
this.permitLevel = permitLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Integer status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBackground() {
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackground(String background) {
|
||||||
|
this.background = background;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmartRoomBackground() {
|
||||||
|
return smartRoomBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmartRoomBackground(String smartRoomBackground) {
|
||||||
|
this.smartRoomBackground = smartRoomBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getLongitude() {
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLongitude(Integer longitude) {
|
||||||
|
this.longitude = longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getLatitude() {
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLatitude(Integer latitude) {
|
||||||
|
this.latitude = latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCityId() {
|
||||||
|
return cityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCityId(Integer cityId) {
|
||||||
|
this.cityId = cityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Integer createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HomeRoomDTO> getRoomlist() {
|
||||||
|
return roomlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoomlist(List<HomeRoomDTO> roomlist) {
|
||||||
|
this.roomlist = roomlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getUid() {
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUid(Integer uid) {
|
||||||
|
this.uid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getAppearHomeList() {
|
||||||
|
return appearHomeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppearHomeList(Object appearHomeList) {
|
||||||
|
this.appearHomeList = appearHomeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPopupFlag() {
|
||||||
|
return popupFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPopupFlag(Integer popupFlag) {
|
||||||
|
this.popupFlag = popupFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPopupTimeStamp() {
|
||||||
|
return popupTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPopupTimeStamp(Integer popupTimeStamp) {
|
||||||
|
this.popupTimeStamp = popupTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCarDid() {
|
||||||
|
return carDid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCarDid(String carDid) {
|
||||||
|
this.carDid = carDid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.cloud;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO class wraps the home json structure
|
||||||
|
*
|
||||||
|
* @author Marcel Verpaalen - Initial contribution
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class HomeListDTO {
|
||||||
|
|
||||||
|
@SerializedName("homelist")
|
||||||
|
@Expose
|
||||||
|
private List<HomeDTO> homelist;
|
||||||
|
@SerializedName("has_more")
|
||||||
|
@Expose
|
||||||
|
private Boolean hasMore;
|
||||||
|
@SerializedName("max_id")
|
||||||
|
@Expose
|
||||||
|
private String maxId;
|
||||||
|
|
||||||
|
public List<HomeDTO> getHomelist() {
|
||||||
|
return homelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHomelist(List<HomeDTO> homelist) {
|
||||||
|
this.homelist = homelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getHasMore() {
|
||||||
|
return hasMore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasMore(Boolean hasMore) {
|
||||||
|
this.hasMore = hasMore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMaxId() {
|
||||||
|
return maxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxId(String maxId) {
|
||||||
|
this.maxId = maxId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.cloud;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO class wraps the home json structure
|
||||||
|
*
|
||||||
|
* @author Marcel Verpaalen - Initial contribution
|
||||||
|
*/
|
||||||
|
public class HomeRoomDTO {
|
||||||
|
|
||||||
|
@SerializedName("id")
|
||||||
|
@Expose
|
||||||
|
private String id;
|
||||||
|
@SerializedName("name")
|
||||||
|
@Expose
|
||||||
|
private String name;
|
||||||
|
@SerializedName("bssid")
|
||||||
|
@Expose
|
||||||
|
private String bssid;
|
||||||
|
@SerializedName("parentid")
|
||||||
|
@Expose
|
||||||
|
private String parentid;
|
||||||
|
@SerializedName("dids")
|
||||||
|
@Expose
|
||||||
|
private List<String> dids;
|
||||||
|
@SerializedName("icon")
|
||||||
|
@Expose
|
||||||
|
private String icon;
|
||||||
|
@SerializedName("background")
|
||||||
|
@Expose
|
||||||
|
private String background;
|
||||||
|
@SerializedName("shareflag")
|
||||||
|
@Expose
|
||||||
|
private Integer shareflag;
|
||||||
|
@SerializedName("create_time")
|
||||||
|
@Expose
|
||||||
|
private Integer createTime;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBssid() {
|
||||||
|
return bssid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBssid(String bssid) {
|
||||||
|
this.bssid = bssid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParentid() {
|
||||||
|
return parentid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentid(String parentid) {
|
||||||
|
this.parentid = parentid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getDids() {
|
||||||
|
return dids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDids(List<String> dids) {
|
||||||
|
this.dids = dids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIcon(String icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBackground() {
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackground(String background) {
|
||||||
|
this.background = background;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getShareflag() {
|
||||||
|
return shareflag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShareflag(Integer shareflag) {
|
||||||
|
this.shareflag = shareflag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Integer createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -201,6 +201,25 @@ public class MiCloudConnector {
|
|||||||
return request("/home/rpc/" + id, country, command);
|
return request("/home/rpc/" + id, country, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JsonObject getHomeList(String country) {
|
||||||
|
String response = "";
|
||||||
|
try {
|
||||||
|
response = request("/homeroom/gethome", country,
|
||||||
|
"{\"fg\":false,\"fetch_share\":true,\"fetch_share_dev\":true,\"limit\":300,\"app_ver\":7,\"fetch_cariot\":true}");
|
||||||
|
logger.trace("gethome response: {}", response);
|
||||||
|
final JsonElement resp = JsonParser.parseString(response);
|
||||||
|
if (resp.isJsonObject() && resp.getAsJsonObject().has("result")) {
|
||||||
|
return resp.getAsJsonObject().get("result").getAsJsonObject();
|
||||||
|
}
|
||||||
|
} catch (JsonParseException e) {
|
||||||
|
logger.info("{} error while parsing rooms: '{}'", e.getMessage(), response);
|
||||||
|
} catch (MiCloudException e) {
|
||||||
|
logger.info("{}", e.getMessage());
|
||||||
|
loginFailedCounter++;
|
||||||
|
}
|
||||||
|
return new JsonObject();
|
||||||
|
}
|
||||||
|
|
||||||
public List<CloudDeviceDTO> getDevices(String country) {
|
public List<CloudDeviceDTO> getDevices(String country) {
|
||||||
final String response = getDeviceString(country);
|
final String response = getDeviceString(country);
|
||||||
List<CloudDeviceDTO> devicesList = new ArrayList<>();
|
List<CloudDeviceDTO> devicesList = new ArrayList<>();
|
||||||
|
|||||||
@ -18,6 +18,8 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
@ -41,9 +43,11 @@ import org.openhab.binding.miio.internal.MiIoSendCommand;
|
|||||||
import org.openhab.binding.miio.internal.basic.MiIoDatabaseWatchService;
|
import org.openhab.binding.miio.internal.basic.MiIoDatabaseWatchService;
|
||||||
import org.openhab.binding.miio.internal.cloud.CloudConnector;
|
import org.openhab.binding.miio.internal.cloud.CloudConnector;
|
||||||
import org.openhab.binding.miio.internal.cloud.CloudUtil;
|
import org.openhab.binding.miio.internal.cloud.CloudUtil;
|
||||||
|
import org.openhab.binding.miio.internal.cloud.HomeRoomDTO;
|
||||||
import org.openhab.binding.miio.internal.cloud.MiCloudException;
|
import org.openhab.binding.miio.internal.cloud.MiCloudException;
|
||||||
import org.openhab.binding.miio.internal.robot.ConsumablesType;
|
import org.openhab.binding.miio.internal.robot.ConsumablesType;
|
||||||
import org.openhab.binding.miio.internal.robot.FanModeType;
|
import org.openhab.binding.miio.internal.robot.FanModeType;
|
||||||
|
import org.openhab.binding.miio.internal.robot.HistoryRecordDTO;
|
||||||
import org.openhab.binding.miio.internal.robot.RRMapDraw;
|
import org.openhab.binding.miio.internal.robot.RRMapDraw;
|
||||||
import org.openhab.binding.miio.internal.robot.RRMapDrawOptions;
|
import org.openhab.binding.miio.internal.robot.RRMapDrawOptions;
|
||||||
import org.openhab.binding.miio.internal.robot.RobotCababilities;
|
import org.openhab.binding.miio.internal.robot.RobotCababilities;
|
||||||
@ -80,6 +84,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -445,31 +450,113 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateHistoryRecord(JsonArray historyData) {
|
private void updateHistoryRecordLegacy(JsonArray historyData) {
|
||||||
ZonedDateTime startTime = ZonedDateTime.ofInstant(Instant.ofEpochSecond(historyData.get(0).getAsLong()),
|
HistoryRecordDTO historyRecord = new HistoryRecordDTO();
|
||||||
ZoneId.systemDefault());
|
for (int i = 0; i < historyData.size(); ++i) {
|
||||||
ZonedDateTime endTime = ZonedDateTime.ofInstant(Instant.ofEpochSecond(historyData.get(1).getAsLong()),
|
try {
|
||||||
ZoneId.systemDefault());
|
BigInteger value = historyData.get(i).getAsBigInteger();
|
||||||
long duration = TimeUnit.SECONDS.toMinutes(historyData.get(2).getAsLong());
|
switch (i) {
|
||||||
double area = historyData.get(3).getAsDouble() / 1000000D;
|
case 0:
|
||||||
int error = historyData.get(4).getAsInt();
|
historyRecord.setStart(ZonedDateTime
|
||||||
int finished = historyData.get(5).getAsInt();
|
.ofInstant(Instant.ofEpochSecond(value.longValue()), ZoneId.systemDefault())
|
||||||
|
.toString());
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
historyRecord.setStart(ZonedDateTime
|
||||||
|
.ofInstant(Instant.ofEpochSecond(value.longValue()), ZoneId.systemDefault())
|
||||||
|
.toString());
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
historyRecord.setDuration(value.intValue());
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
historyRecord.setArea(new BigDecimal(value).divide(BigDecimal.valueOf(1000000)));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
historyRecord.setError(value.intValue());
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
historyRecord.setFinished(value.intValue());
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
historyRecord.setStartType(value.intValue());
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
historyRecord.setCleanType(value.intValue());
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
historyRecord.setFinishReason(value.intValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (ClassCastException | NumberFormatException | IllegalStateException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateHistoryRecord(historyRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHistoryRecord(HistoryRecordDTO historyRecordDTO) {
|
||||||
JsonObject historyRecord = new JsonObject();
|
JsonObject historyRecord = new JsonObject();
|
||||||
historyRecord.addProperty("start", startTime.toString());
|
if (historyRecordDTO.getStart() != null) {
|
||||||
historyRecord.addProperty("end", endTime.toString());
|
historyRecord.addProperty("start", historyRecordDTO.getStart().split("\\+")[0]);
|
||||||
|
updateState(CHANNEL_HISTORY_START_TIME, new DateTimeType(historyRecordDTO.getStart().split("\\+")[0]));
|
||||||
|
}
|
||||||
|
if (historyRecordDTO.getEnd() != null) {
|
||||||
|
historyRecord.addProperty("end", historyRecordDTO.getEnd().split("\\+")[0]);
|
||||||
|
updateState(CHANNEL_HISTORY_END_TIME, new DateTimeType(historyRecordDTO.getEnd().split("\\+")[0]));
|
||||||
|
}
|
||||||
|
if (historyRecordDTO.getDuration() != null) {
|
||||||
|
long duration = TimeUnit.SECONDS.toMinutes(historyRecordDTO.getDuration().longValue());
|
||||||
historyRecord.addProperty("duration", duration);
|
historyRecord.addProperty("duration", duration);
|
||||||
historyRecord.addProperty("area", area);
|
|
||||||
historyRecord.addProperty("error", error);
|
|
||||||
historyRecord.addProperty("finished", finished);
|
|
||||||
updateState(CHANNEL_HISTORY_START_TIME, new DateTimeType(startTime));
|
|
||||||
updateState(CHANNEL_HISTORY_END_TIME, new DateTimeType(endTime));
|
|
||||||
updateState(CHANNEL_HISTORY_DURATION, new QuantityType<>(duration, Units.MINUTE));
|
updateState(CHANNEL_HISTORY_DURATION, new QuantityType<>(duration, Units.MINUTE));
|
||||||
updateState(CHANNEL_HISTORY_AREA, new QuantityType<>(area, SIUnits.SQUARE_METRE));
|
}
|
||||||
updateState(CHANNEL_HISTORY_ERROR, new DecimalType(error));
|
if (historyRecordDTO.getArea() != null) {
|
||||||
updateState(CHANNEL_HISTORY_FINISH, new DecimalType(finished));
|
historyRecord.addProperty("area", historyRecordDTO.getArea());
|
||||||
|
updateState(CHANNEL_HISTORY_AREA, new QuantityType<>(historyRecordDTO.getArea(), SIUnits.SQUARE_METRE));
|
||||||
|
}
|
||||||
|
if (historyRecordDTO.getError() != null) {
|
||||||
|
historyRecord.addProperty("error", historyRecordDTO.getError());
|
||||||
|
updateState(CHANNEL_HISTORY_ERROR, new DecimalType(historyRecordDTO.getError()));
|
||||||
|
}
|
||||||
|
if (historyRecordDTO.getFinished() != null) {
|
||||||
|
historyRecord.addProperty("finished", historyRecordDTO.getFinished());
|
||||||
|
updateState(CHANNEL_HISTORY_FINISH, new DecimalType(historyRecordDTO.getFinished()));
|
||||||
|
}
|
||||||
|
if (historyRecordDTO.getFinishReason() != null) {
|
||||||
|
historyRecord.addProperty("finish_reason", historyRecordDTO.getFinishReason());
|
||||||
|
updateState(CHANNEL_HISTORY_FINISHREASON, new DecimalType(historyRecordDTO.getFinishReason()));
|
||||||
|
}
|
||||||
|
if (historyRecordDTO.getDustCollectionStatus() != null) {
|
||||||
|
historyRecord.addProperty("dust_collection_status", historyRecordDTO.getDustCollectionStatus());
|
||||||
|
updateState(CHANNEL_HISTORY_DUSTCOLLECTION, new DecimalType(historyRecordDTO.getDustCollectionStatus()));
|
||||||
|
}
|
||||||
updateState(CHANNEL_HISTORY_RECORD, new StringType(historyRecord.toString()));
|
updateState(CHANNEL_HISTORY_RECORD, new StringType(historyRecord.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateRoomMapping(MiIoSendCommand response) {
|
||||||
|
for (RobotCababilities cmd : FEATURES_CHANNELS) {
|
||||||
|
if (response.getCommand().getCommand().contentEquals(cmd.getCommand())) {
|
||||||
|
if (response.getResult().isJsonArray()) {
|
||||||
|
JsonArray rooms = response.getResult().getAsJsonArray();
|
||||||
|
JsonArray mappedRoom = new JsonArray();
|
||||||
|
for (JsonElement roomE : rooms) {
|
||||||
|
JsonArray room = roomE.getAsJsonArray();
|
||||||
|
HomeRoomDTO name = cloudConnector.getRoom(room.get(1).getAsString());
|
||||||
|
if (name != null && name.getName() != null) {
|
||||||
|
room.add(name.getName());
|
||||||
|
} else {
|
||||||
|
room.add("not found");
|
||||||
|
}
|
||||||
|
mappedRoom.add(room);
|
||||||
|
}
|
||||||
|
updateState(cmd.getChannel(), new StringType(mappedRoom.toString()));
|
||||||
|
} else {
|
||||||
|
updateState(cmd.getChannel(), new StringType(response.getResult().toString()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean skipUpdate() {
|
protected boolean skipUpdate() {
|
||||||
if (!hasConnection()) {
|
if (!hasConnection()) {
|
||||||
@ -525,6 +612,7 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||||||
this.mapDrawOptions = RRMapDrawOptions
|
this.mapDrawOptions = RRMapDrawOptions
|
||||||
.getOptionsFromFile(BINDING_USERDATA_PATH + File.separator + "mapConfig.json", logger);
|
.getOptionsFromFile(BINDING_USERDATA_PATH + File.separator + "mapConfig.json", logger);
|
||||||
updateState(RobotCababilities.SEGMENT_CLEAN.getChannel(), new StringType("-"));
|
updateState(RobotCababilities.SEGMENT_CLEAN.getChannel(), new StringType("-"));
|
||||||
|
cloudConnector.getHomeLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -570,7 +658,13 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||||||
case CLEAN_RECORD_GET:
|
case CLEAN_RECORD_GET:
|
||||||
if (response.getResult().isJsonArray() && response.getResult().getAsJsonArray().size() > 0
|
if (response.getResult().isJsonArray() && response.getResult().getAsJsonArray().size() > 0
|
||||||
&& response.getResult().getAsJsonArray().get(0).isJsonArray()) {
|
&& response.getResult().getAsJsonArray().get(0).isJsonArray()) {
|
||||||
updateHistoryRecord(response.getResult().getAsJsonArray().get(0).getAsJsonArray());
|
updateHistoryRecordLegacy(response.getResult().getAsJsonArray().get(0).getAsJsonArray());
|
||||||
|
} else if (response.getResult().isJsonObject()) {
|
||||||
|
final HistoryRecordDTO historyRecordDTO = GSON.fromJson(response.getResult().getAsJsonObject(),
|
||||||
|
HistoryRecordDTO.class);
|
||||||
|
if (historyRecordDTO != null) {
|
||||||
|
updateHistoryRecord(historyRecordDTO);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Could not extract cleaning history record from: {}", response);
|
logger.debug("Could not extract cleaning history record from: {}", response);
|
||||||
}
|
}
|
||||||
@ -589,11 +683,13 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||||||
case GET_LED_STATUS:
|
case GET_LED_STATUS:
|
||||||
updateNumericChannel(response);
|
updateNumericChannel(response);
|
||||||
break;
|
break;
|
||||||
|
case GET_ROOM_MAPPING:
|
||||||
|
updateRoomMapping(response);
|
||||||
|
break;
|
||||||
case GET_CARPET_MODE:
|
case GET_CARPET_MODE:
|
||||||
case GET_FW_FEATURES:
|
case GET_FW_FEATURES:
|
||||||
case GET_CUSTOMIZED_CLEAN_MODE:
|
case GET_CUSTOMIZED_CLEAN_MODE:
|
||||||
case GET_MULTI_MAP_LIST:
|
case GET_MULTI_MAP_LIST:
|
||||||
case GET_ROOM_MAPPING:
|
|
||||||
for (RobotCababilities cmd : FEATURES_CHANNELS) {
|
for (RobotCababilities cmd : FEATURES_CHANNELS) {
|
||||||
if (response.getCommand().getCommand().contentEquals(cmd.getCommand())) {
|
if (response.getCommand().getCommand().contentEquals(cmd.getCommand())) {
|
||||||
updateState(cmd.getChannel(), new StringType(response.getResult().toString()));
|
updateState(cmd.getChannel(), new StringType(response.getResult().toString()));
|
||||||
|
|||||||
@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.robot;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DTO class wraps the history record message json structure
|
||||||
|
*
|
||||||
|
* @author Marcel Verpaalen - Initial contribution
|
||||||
|
*/
|
||||||
|
public class HistoryRecordDTO {
|
||||||
|
|
||||||
|
@SerializedName("start")
|
||||||
|
@Expose
|
||||||
|
private String start;
|
||||||
|
@SerializedName("end")
|
||||||
|
@Expose
|
||||||
|
private String end;
|
||||||
|
@SerializedName("duration")
|
||||||
|
@Expose
|
||||||
|
private Integer duration;
|
||||||
|
@SerializedName("area")
|
||||||
|
@Expose
|
||||||
|
private BigDecimal area;
|
||||||
|
@SerializedName("clean_time")
|
||||||
|
@Expose
|
||||||
|
private Integer cleanTime;
|
||||||
|
@SerializedName("error")
|
||||||
|
@Expose
|
||||||
|
private Integer error;
|
||||||
|
@SerializedName("finished")
|
||||||
|
@Expose
|
||||||
|
private Integer finished;
|
||||||
|
@SerializedName("start_type")
|
||||||
|
@Expose
|
||||||
|
private Integer startType;
|
||||||
|
@SerializedName("clean_type")
|
||||||
|
@Expose
|
||||||
|
private Integer cleanType;
|
||||||
|
@SerializedName("finish_reason")
|
||||||
|
@Expose
|
||||||
|
private Integer finishReason;
|
||||||
|
@SerializedName("dust_collection_status")
|
||||||
|
@Expose
|
||||||
|
private Integer dustCollectionStatus;
|
||||||
|
|
||||||
|
public final String getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setStart(String start) {
|
||||||
|
this.start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getEnd() {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setEnd(String end) {
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Integer getDuration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setDuration(Integer duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final BigDecimal getArea() {
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setArea(BigDecimal area) {
|
||||||
|
this.area = area;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Integer getCleanTime() {
|
||||||
|
return cleanTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setCleanTime(Integer cleanTime) {
|
||||||
|
this.cleanTime = cleanTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Integer getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setError(Integer error) {
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Integer getFinished() {
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setFinished(Integer finished) {
|
||||||
|
this.finished = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Integer getStartType() {
|
||||||
|
return startType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setStartType(Integer startType) {
|
||||||
|
this.startType = startType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Integer getCleanType() {
|
||||||
|
return cleanType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setCleanType(Integer cleanType) {
|
||||||
|
this.cleanType = cleanType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Integer getFinishReason() {
|
||||||
|
return finishReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setFinishReason(Integer finishReason) {
|
||||||
|
this.finishReason = finishReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Integer getDustCollectionStatus() {
|
||||||
|
return dustCollectionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setDustCollectionStatus(Integer dustCollectionStatus) {
|
||||||
|
this.dustCollectionStatus = dustCollectionStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -87,6 +87,8 @@
|
|||||||
<channel id="last_clean_duration" typeId="last_clean_duration"/>
|
<channel id="last_clean_duration" typeId="last_clean_duration"/>
|
||||||
<channel id="last_clean_error" typeId="last_clean_error"/>
|
<channel id="last_clean_error" typeId="last_clean_error"/>
|
||||||
<channel id="last_clean_finish" typeId="last_clean_finish"/>
|
<channel id="last_clean_finish" typeId="last_clean_finish"/>
|
||||||
|
<channel id="last_clean_finish_reason" typeId="last_clean_finish_reason"/>
|
||||||
|
<channel id="last_clean_dustcollection_status" typeId="last_clean_dustcollection_status"/>
|
||||||
<channel id="last_clean_record" typeId="last_clean_record"/>
|
<channel id="last_clean_record" typeId="last_clean_record"/>
|
||||||
<channel id="map" typeId="map"/>
|
<channel id="map" typeId="map"/>
|
||||||
</channels>
|
</channels>
|
||||||
@ -377,6 +379,16 @@
|
|||||||
<label>Cleaning Finished</label>
|
<label>Cleaning Finished</label>
|
||||||
<state readOnly="true"/>
|
<state readOnly="true"/>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
<channel-type id="last_clean_finish_reason">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Cleaning Finished Reason</label>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="last_clean_dustcollection_status">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Dust Collection Status</label>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
<channel-type id="last_clean_record" advanced="true">
|
<channel-type id="last_clean_record" advanced="true">
|
||||||
<item-type>String</item-type>
|
<item-type>String</item-type>
|
||||||
<label>Cleaning Record</label>
|
<label>Cleaning Record</label>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user