| Switch | status#mop_forbidden_enable | Mop Forbidden |
| Switch | status#is_locating | Robot is locating |
| Number | actions#segment | Room Clean (enter room #) |
+| Switch | actions#collect_dust | Start collecting dust |
+| Switch | actions#clean_mop_start | Start mop wash |
+| Switch | actions#clean_mop_stop | Stop mop wash |
+| Number | status#mop_drying_time | Mop drying Time |
+| Switch | status#is_mop_drying | Mop cleaning active |
+| Number | status#dock_state_id | Dock status id |
+| String | status#dock_state | Dock status message |
Note: cleaning map is only available with cloud access.
| Switch | status#mop_forbidden_enable | Mop Forbidden |
| Switch | status#is_locating | Robot is locating |
| Number | actions#segment | Room Clean (enter room #) |
+| Switch | actions#collect_dust | Start collecting dust |
+| Switch | actions#clean_mop_start | Start mop wash |
+| Switch | actions#clean_mop_stop | Stop mop wash |
+| Number | status#mop_drying_time | Mop drying Time |
+| Switch | status#is_mop_drying | Mop cleaning active |
+| Number | status#dock_state_id | Dock status id |
+| String | status#dock_state | Dock status message |
Note: cleaning map is only available with cloud access.
public static final String CHANNEL_MAP_PRESENT = "status#map_present";
public static final String CHANNEL_STATE = "status#state";
public static final String CHANNEL_STATE_ID = "status#state_id";
+ public static final String CHANNEL_DOCK_STATE = "status#dock_state";
+ public static final String CHANNEL_DOCK_STATE_ID = "status#dock_state_id";
public static final String CHANNEL_CONTROL = "actions#control";
public static final String CHANNEL_COMMAND = "actions#commands";
public static final String CHANNEL_HISTORY_TOTALAREA = "history#total_clean_area";
public static final String CHANNEL_HISTORY_COUNT = "history#total_clean_count";
+ public static final String CHANNEL_MOP_TOTALDRYTIME = "status#mop_drying_time";
+
public static final String CHANNEL_HISTORY_START_TIME = "cleaning#last_clean_start_time";
public static final String CHANNEL_HISTORY_END_TIME = "cleaning#last_clean_end_time";
public static final String CHANNEL_HISTORY_AREA = "cleaning#last_clean_area";
GET_CUSTOMIZED_CLEAN_MODE("get_customize_clean_mode"),
GET_MULTI_MAP_LIST("get_multi_maps_list"),
GET_ROOM_MAPPING("get_room_mapping"),
+ SET_COLLECT_DUST("app_start_collect_dust"),
+ SET_CLEAN_MOP_START("app_start_wash"),
+ SET_CLEAN_MOP_STOP("app_stop_wash"),
// Gateway & child device commands
GET_ARMING("get_arming"),
import org.openhab.binding.miio.internal.cloud.HomeRoomDTO;
import org.openhab.binding.miio.internal.cloud.MiCloudException;
import org.openhab.binding.miio.internal.robot.ConsumablesType;
+import org.openhab.binding.miio.internal.robot.DockStatusType;
import org.openhab.binding.miio.internal.robot.FanModeType;
import org.openhab.binding.miio.internal.robot.HistoryRecordDTO;
import org.openhab.binding.miio.internal.robot.RRMapDraw;
private static final Gson GSON = new GsonBuilder().serializeNulls().create();
private final ChannelUID mapChannelUid;
- private static final Set<RobotCababilities> FEATURES_CHANNELS = Collections.unmodifiableSet(Stream
- .of(RobotCababilities.SEGMENT_STATUS, RobotCababilities.MAP_STATUS, RobotCababilities.LED_STATUS,
- RobotCababilities.CARPET_MODE, RobotCababilities.FW_FEATURES, RobotCababilities.ROOM_MAPPING,
- RobotCababilities.MULTI_MAP_LIST, RobotCababilities.CUSTOMIZE_CLEAN_MODE)
- .collect(Collectors.toSet()));
+ private static final Set<RobotCababilities> FEATURES_CHANNELS = Collections.unmodifiableSet(Stream.of(
+ RobotCababilities.SEGMENT_STATUS, RobotCababilities.MAP_STATUS, RobotCababilities.LED_STATUS,
+ RobotCababilities.CARPET_MODE, RobotCababilities.FW_FEATURES, RobotCababilities.ROOM_MAPPING,
+ RobotCababilities.MULTI_MAP_LIST, RobotCababilities.CUSTOMIZE_CLEAN_MODE, RobotCababilities.COLLECT_DUST,
+ RobotCababilities.CLEAN_MOP_START, RobotCababilities.CLEAN_MOP_STOP, RobotCababilities.MOP_DRYING,
+ RobotCababilities.MOP_DRYING_REMAINING_TIME, RobotCababilities.DOCK_STATE_ID).collect(Collectors.toSet()));
private ExpiringCache<String> status;
private ExpiringCache<String> consumables;
forceStatusUpdate();
return;
}
+
if (channelUID.getId().equals(RobotCababilities.WATERBOX_MODE.getChannel())) {
sendCommand(MiIoCommand.SET_WATERBOX_MODE, "[" + command.toString() + "]");
forceStatusUpdate();
sendCommand(MiIoCommand.CONSUMABLES_RESET, "[" + command.toString() + "]");
updateState(CHANNEL_CONSUMABLE_RESET, new StringType("none"));
}
+
+ if (channelUID.getId().equals(RobotCababilities.COLLECT_DUST.getChannel()) && !command.toString().isEmpty()
+ && !command.toString().contentEquals("-")) {
+ sendCommand(MiIoCommand.SET_COLLECT_DUST);
+ forceStatusUpdate();
+ return;
+ }
+
+ if (channelUID.getId().equals(RobotCababilities.CLEAN_MOP_START.getChannel()) && !command.toString().isEmpty()
+ && !command.toString().contentEquals("-")) {
+ sendCommand(MiIoCommand.SET_CLEAN_MOP_START);
+ forceStatusUpdate();
+ return;
+ }
+ if (channelUID.getId().equals(RobotCababilities.CLEAN_MOP_STOP.getChannel()) && !command.toString().isEmpty()
+ && !command.toString().contentEquals("-")) {
+ sendCommand(MiIoCommand.SET_CLEAN_MOP_STOP);
+ forceStatusUpdate();
+ return;
+ }
}
private void forceStatusUpdate() {
}
updateState(CHANNEL_VACUUM, vacuum);
}
+ if (this.deviceCapabilities.containsKey(RobotCababilities.DOCK_STATE_ID)) {
+ DockStatusType state = DockStatusType.getType(statusInfo.getDockErrorStatus().intValue());
+ updateState(CHANNEL_DOCK_STATE, new StringType(state.getDescription()));
+ updateState(CHANNEL_DOCK_STATE_ID, new DecimalType(state.getId()));
+ }
if (deviceCapabilities.containsKey(RobotCababilities.WATERBOX_MODE)) {
safeUpdateState(RobotCababilities.WATERBOX_MODE.getChannel(), statusInfo.getWaterBoxMode());
}
if (deviceCapabilities.containsKey(RobotCababilities.LOCATING)) {
safeUpdateState(RobotCababilities.LOCATING.getChannel(), statusInfo.getIsLocating());
}
+ if (deviceCapabilities.containsKey(RobotCababilities.CLEAN_MOP_START)) {
+ safeUpdateState(RobotCababilities.CLEAN_MOP_START.getChannel(), 0);
+ }
+ if (deviceCapabilities.containsKey(RobotCababilities.CLEAN_MOP_STOP)) {
+ safeUpdateState(RobotCababilities.CLEAN_MOP_STOP.getChannel(), 0);
+ }
+ if (deviceCapabilities.containsKey(RobotCababilities.COLLECT_DUST)) {
+ safeUpdateState(RobotCababilities.COLLECT_DUST.getChannel(), 0);
+ }
+ if (deviceCapabilities.containsKey(RobotCababilities.MOP_DRYING)) {
+ safeUpdateState(RobotCababilities.MOP_DRYING.getChannel(), statusInfo.getIsMopDryingActive());
+ }
+ if (deviceCapabilities.containsKey(RobotCababilities.MOP_DRYING_REMAINING_TIME)) {
+ updateState(CHANNEL_MOP_TOTALDRYTIME,
+ new QuantityType<>(TimeUnit.SECONDS.toMinutes(statusInfo.getMopDryTime()), Units.MINUTE));
+ }
return true;
}
case GET_FW_FEATURES:
case GET_CUSTOMIZED_CLEAN_MODE:
case GET_MULTI_MAP_LIST:
+
+ case SET_COLLECT_DUST:
+ case SET_CLEAN_MOP_START:
+ case SET_CLEAN_MOP_STOP:
+
for (RobotCababilities cmd : FEATURES_CHANNELS) {
if (response.getCommand().getCommand().contentEquals(cmd.getCommand())) {
updateState(cmd.getChannel(), new StringType(response.getResult().toString()));
--- /dev/null
+/**
+ * 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 org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * List of dockingstation status
+ *
+ * @author David Kumar - Initial contribution
+ */
+@NonNullByDefault
+public enum DockStatusType {
+ UNKNOWN(-1, "Unknown"),
+ OK(0, "OK"),
+ ERROR_SUCTION(34, "Suction Error"),
+ ERROR_FRESH_WATER_TANK(38, "Error fresh water tank"),
+ ERROR_FRESH_DIRTY_WATER_TANK(39, "Error dirty water tank"),
+ ERROR_DUST_CONTAINER(46, "Missing dust container/dust bag");
+
+ private final int id;
+ private final String description;
+
+ DockStatusType(int id, String description) {
+ this.id = id;
+ this.description = description;
+ }
+
+ public int getId() {
+ return this.id;
+ }
+
+ public static DockStatusType getType(int value) {
+ byte b;
+ int i;
+ DockStatusType[] arrayOfDockStatusType;
+ for (i = (arrayOfDockStatusType = values()).length, b = 0; b < i;) {
+ DockStatusType st = arrayOfDockStatusType[b];
+ if (st.getId() == value) {
+ return st;
+ }
+ b++;
+ }
+
+ return UNKNOWN;
+ }
+
+ public String getDescription() {
+ return this.description;
+ }
+
+ @Override
+ public String toString() {
+ return "Status " + Integer.toString(this.id) + ": " + this.description;
+ }
+}
ROOM_MAPPING("", "info#room_mapping", "miio:room_mapping", "get_room_mapping"),
MULTI_MAP_LIST("", "info#multi_maps_list", "miio:multi_maps_list", "get_multi_maps_list"),
CUSTOMIZE_CLEAN_MODE("", "info#customize_clean_mode", "miio:customize_clean_mode", "get_customize_clean_mode"),
- SEGMENT_CLEAN("", "actions#segment", "miio:segment", "");
+ SEGMENT_CLEAN("", "actions#segment", "miio:segment", ""),
+ COLLECT_DUST("auto_dust_collection", "actions#collect_dust", "miio:collect_dust", ""),
+ CLEAN_MOP_START("dry_status", "actions#clean_mop_start", "miio:clean_mop_start", ""),
+ CLEAN_MOP_STOP("dry_status", "actions#clean_mop_stop", "miio:clean_mop_stop", ""),
+ MOP_DRYING("dry_status", "status#is_mop_drying", "miio:is_mop_drying", ""),
+ MOP_DRYING_REMAINING_TIME("dry_status", "status#mop_drying_time", "miio:mop_drying_time", ""),
+ DOCK_STATE("dock_error_status", "status#dock_state", "miio:dock_state", ""),
+ DOCK_STATE_ID("dock_error_status", "status#dock_state_id", "miio:dock_state_id", "");
private final String statusFieldName;
private final String channel;
@SerializedName("mop_forbidden_enable")
@Expose
private Integer mopForbiddenEnable;
+ @SerializedName("dry_status")
+ @Expose
+ private Integer isMopDryingActive;
+ @SerializedName("rdt")
+ @Expose
+ private Long mopDryTime;
+ @SerializedName("dock_error_status")
+ @Expose
+ private Integer dockErrorStatus;
public final Integer getMsgVer() {
return msgVer;
public final Integer getMopForbiddenEnable() {
return mopForbiddenEnable;
}
+
+ public Integer getIsMopDryingActive() {
+ return isMopDryingActive;
+ }
+
+ public Long getMopDryTime() {
+ return mopDryTime;
+ }
+
+ public Integer getDockErrorStatus() {
+ return this.dockErrorStatus;
+ }
+
+ public void setDockErrorStatus(Integer dockErrorStatus) {
+ this.dockErrorStatus = dockErrorStatus;
+ }
}
addon.config.miio.cloudDiscoveryMode.description = Allow for discovery via the cloud. This may be used for devices that are not on the same network as OpenHAB server
addon.config.miio.cloudDiscoveryMode.option.disabled = Local discovery only (Default)
addon.config.miio.cloudDiscoveryMode.option.supportedOnly = Discover online supported devices from Xiaomi cloud
-addon.config.miio.cloudDiscoveryMode.option.all = Discover all online devices from Xiaomi cloud
+addon.config.miio.cloudDiscoveryMode.option.all = Discover all on & offline devices from Xiaomi cloud (advanced, see readme for usage)
addon.config.miio.country.label = Xiaomi server country
addon.config.miio.country.description = Xiaomi server country(s) (e.g. sg,de). Separate multiple servers with comma. Leave empty for all. See binding readme for country to server mapping
addon.config.miio.password.label = Xiaomi cloud password
# thing types
thing-type.miio.basic.label = Xiaomi Mi Basic Device
+thing-type.miio.gateway.label = Xiaomi Mi Gateway
thing-type.miio.generic.label = Xiaomi Mi Device
+thing-type.miio.lumi.label = Xiaomi Mi Lumi Device
thing-type.miio.unsupported.label = Unsupported Xiaomi Mi Device
thing-type.miio.vacuum.label = Xiaomi Robot Vacuum
# thing types config
-thing-type.config.miio.config.cloudServer.label = Xiaomi cloud Server (county code)
+thing-type.config.miio.config.cloudServer.label = Cloud Server Country Code
+thing-type.config.miio.config.cloudServer.description = Country code (2 characters) of the Xiaomi cloud server. See binding documentation for mapping of the country to cloud server
thing-type.config.miio.config.communication.label = Communication Method
thing-type.config.miio.config.communication.description = Determines how the binding communicates with this device
thing-type.config.miio.config.communication.option.direct = Direct (Default)
thing-type.config.miio.config.timeout.description = Timeout time in milliseconds
thing-type.config.miio.config.token.label = Token
thing-type.config.miio.config.token.description = Token for communication (in Hex)
+thing-type.config.miio.configGatewayDevices.cloudServer.label = Cloud Server Country Code
+thing-type.config.miio.configGatewayDevices.cloudServer.description = Country code (2 characters) of the Xiaomi cloud server. See binding documentation for mapping of the country to cloud server
+thing-type.config.miio.configGatewayDevices.deviceId.label = Device ID
+thing-type.config.miio.configGatewayDevices.deviceId.description = Device ID number for communication (in Hex)
+thing-type.config.miio.configGatewayDevices.model.label = Device Model String
+thing-type.config.miio.configGatewayDevices.model.description = Device model string, used to determine the subtype.
+thing-type.config.miio.configGatewayDevices.refreshInterval.label = Refresh Interval
+thing-type.config.miio.configGatewayDevices.refreshInterval.description = Refresh interval for refreshing the data in seconds. (0=disabled)
+thing-type.config.miio.configGatewayDevices.timeout.label = Timeout
+thing-type.config.miio.configGatewayDevices.timeout.description = Timeout time in milliseconds
# channel group types
channel-group-type.miio.actions.label = Action
channel-group-type.miio.basicactions.label = Actions
+channel-group-type.miio.basicactions.label = Actions
+channel-group-type.miio.basicactions.label = Actions
channel-group-type.miio.cleaning.label = Last Cleaning Details
channel-group-type.miio.consumables.label = Consumables
channel-group-type.miio.dnd.label = Do Not Disturb
channel-type.miio.bssid.label = BSSID
channel-type.miio.carpet_mode.label = Carpet Mode
channel-type.miio.clean_area.label = Cleaning Area
+channel-type.miio.clean_mop_start.label = Start Mop Wash
+channel-type.miio.clean_mop_start.description = Once the vacuum cleaner is back in place, you can start cleaning the mop
+channel-type.miio.clean_mop_stop.label = Stop Mop Wash
channel-type.miio.clean_time.label = Cleaning Time
+channel-type.miio.collect_dust.label = Start Collecting Dust
+channel-type.miio.collect_dust.description = Once the vacuum cleaner is back in place, you can start collecting the dust
channel-type.miio.color.label = Generic Color Channel
channel-type.miio.commands.label = Execute Command
channel-type.miio.consumable_reset.label = Reset Consumable
channel-type.miio.dnd_end.label = End Time DND
channel-type.miio.dnd_function.label = Do Not Disturb Functionality
channel-type.miio.dnd_start.label = Start Time DND
+channel-type.miio.dock_state.label = Dock State
+channel-type.miio.dock_state_id.label = Dock State ID
channel-type.miio.error_code.label = Error Code
channel-type.miio.error_id.label = Error ID
channel-type.miio.fan.label = Control Fan Level
channel-type.miio.image.label = Generic Image Channel
channel-type.miio.in_cleaning.label = In Cleaning
channel-type.miio.is_locating.label = Robot Locating
+channel-type.miio.is_mop_drying.label = Mop Cleaning Active
channel-type.miio.last_clean_area.label = Cleaning Area
channel-type.miio.last_clean_duration.label = Cleaning Duration
+channel-type.miio.last_clean_dustcollection_status.label = Dust Collection Status
channel-type.miio.last_clean_end_time.label = Cleaning End
channel-type.miio.last_clean_end_time.description = Last Cleaning End Time
channel-type.miio.last_clean_error.label = Error
channel-type.miio.last_clean_finish.label = Cleaning Finished
+channel-type.miio.last_clean_finish_reason.label = Cleaning Finished Reason
channel-type.miio.last_clean_record.label = Cleaning Record
channel-type.miio.last_clean_start_time.label = Cleaning Start
channel-type.miio.last_clean_start_time.description = Last Cleaning Start Time
channel-type.miio.map.label = Cleaning Map
channel-type.miio.map_present.label = Map Present
channel-type.miio.map_status.label = Map Status
+channel-type.miio.mop_drying_time.label = Mop Drying Time
channel-type.miio.mop_forbidden_enable.label = Mop Forbidden
channel-type.miio.msg_seq.label = Msg Seq
channel-type.miio.multi_maps_list.label = Multi Map List
channel-type.miio.string.label = Generic String Channel
channel-type.miio.switch.label = Generic Switch Channel
channel-type.miio.testcommands.label = (experimental) Create channels / test properties for unsupported devices (legacy protocol)
-channel-type.miio.testcommands.description = Execute test for all known properties to find channels supported by your device. This is for older /legacy devices, newer devices mostly use MIOT. Check your log, share your results.
+channel-type.miio.testcommands.description = Execute test for all known properties to find channels supported by your device. This is for older / legacy devices, newer devices mostly use MIOT. Check your log, share your results.
channel-type.miio.testmiot.label = (experimental) Create channels for new/unsupported devices (MIOT protocol)
channel-type.miio.testmiot.description = Create experimental support for MIOT protocol devices based on the online specification. Check your log, share your results.
channel-type.miio.total_clean_area.label = Total Cleaning Area
channel-type.miio.water_box_mode.label = Water Box Mode
channel-type.miio.water_box_status.label = Water Box State
-# Thing status descriptions
+# thing status descriptions
+
offline.config-error-ip = IP address required. Configure IP address
offline.config-error-token = Token required. Configure token
offline.config-error-cloud = Cloud communication requires defined deviceId in the config
<label>Robot Locating</label>
<state readOnly="true"/>
</channel-type>
+ <channel-type id="dock_state">
+ <item-type>String</item-type>
+ <label>Dock State</label>
+ <state readOnly="true"/>
+ </channel-type>
+ <channel-type id="dock_state_id">
+ <item-type>Number</item-type>
+ <label>Dock State ID</label>
+ <state readOnly="true"/>
+ </channel-type>
+ <channel-type id="mop_drying_time">
+ <item-type>Number:Time</item-type>
+ <label>Mop Drying Time</label>
+ <state pattern="%.0f %unit%" readOnly="true"/>
+ </channel-type>
+ <channel-type id="is_mop_drying">
+ <item-type>Switch</item-type>
+ <label>Mop Cleaning Active</label>
+ <state readOnly="true"/>
+ </channel-type>
+ <channel-type id="collect_dust">
+ <item-type>Switch</item-type>
+ <label>Start Collecting Dust</label>
+ <description>Once the vacuum cleaner is back in place, you can start collecting the dust</description>
+ </channel-type>
+ <channel-type id="clean_mop_start">
+ <item-type>Switch</item-type>
+ <label>Start Mop Wash</label>
+ <description>Once the vacuum cleaner is back in place, you can start cleaning the mop</description>
+ </channel-type>
+ <channel-type id="clean_mop_stop">
+ <item-type>Switch</item-type>
+ <label>Stop Mop Wash</label>
+ </channel-type>
<!-- Consumables channels -->
<channel-type id="main_brush_percent">