diff --git a/bundles/org.openhab.binding.miio/README.base.md b/bundles/org.openhab.binding.miio/README.base.md index 88306fd08..8223a88c0 100644 --- a/bundles/org.openhab.binding.miio/README.base.md +++ b/bundles/org.openhab.binding.miio/README.base.md @@ -245,8 +245,20 @@ Image map "Cleaning Map" (gVacLast) {channel="miio:vacuum:034F0E45:cleaning#map" Note: cleaning map is only available with cloud access. -Additionally depending on the capabilities of your robot vacuum other channels may be enabled at runtime +There are several advanced channels, which may be useful in rules (e.g. for individual room cleaning etc) +In case your vacuum does not support one of these commands, it will show "unsupported_method" for string channels or no value for numeric channels. +| Type | Channel | Description | +|---------|-----------------------------------|----------------------------| +| Number | status#segment_status | Segment Status | +| Number | status#map_status | Map Box Status | +| Number | status#led_status | Led Box Status | +| String | info#carpet_mode | Carpet Mode details | +| String | info#fw_features | Firmware Features | +| String | info#room_mapping | Room Mapping details | +| String | info#multi_maps_list | Maps Listing details | + +Additionally depending on the capabilities of your robot vacuum other channels may be enabled at runtime | Type | Channel | Description | |---------|-----------------------------------|----------------------------| diff --git a/bundles/org.openhab.binding.miio/README.md b/bundles/org.openhab.binding.miio/README.md index 44218acc5..806207bbf 100644 --- a/bundles/org.openhab.binding.miio/README.md +++ b/bundles/org.openhab.binding.miio/README.md @@ -2663,7 +2663,7 @@ e.g. `openhab:send actionCommand 'upd_timer["1498595904821", "on"]'` would enabl |----------------------|----------------------|------------------------------------------|------------| | power | Switch | Power | | | brightness | Dimmer | Brightness | | -| ambientBrightness | Number | Ambient Brightness | | +| ambientBrightness | Dimmer | Ambient Brightness | | | delayoff | Number:Time | Shutdown Timer | | | colorTemperature | Number | Color Temperature | | | colorMode | Number | Color Mode | | @@ -2759,7 +2759,7 @@ e.g. `openhab:send actionCommand 'upd_timer["1498595904821", "on"]'` would enabl |----------------------|----------------------|------------------------------------------|------------| | power | Switch | Power | | | brightness | Dimmer | Brightness | | -| ambientBrightness | Number | Ambient Brightness | | +| ambientBrightness | Dimmer | Ambient Brightness | | | delayoff | Number:Time | Shutdown Timer | | | colorTemperature | Number | Color Temperature | | | colorMode | Number | Color Mode | | @@ -4543,8 +4543,20 @@ Image map "Cleaning Map" (gVacLast) {channel="miio:vacuum:034F0E45:cleaning#map" Note: cleaning map is only available with cloud access. -Additionally depending on the capabilities of your robot vacuum other channels may be enabled at runtime +There are several advanced channels, which may be useful in rules (e.g. for individual room cleaning etc) +In case your vacuum does not support one of these commands, it will show "unsupported_method" for string channels or no value for numeric channels. +| Type | Channel | Description | +|---------|-----------------------------------|----------------------------| +| Number | status#segment_status | Segment Status | +| Number | status#map_status | Map Box Status | +| Number | status#led_status | Led Box Status | +| String | info#carpet_mode | Carpet Mode details | +| String | info#fw_features | Firmware Features | +| String | info#room_mapping | Room Mapping details | +| String | info#multi_maps_list | Maps Listing details | + +Additionally depending on the capabilities of your robot vacuum other channels may be enabled at runtime | Type | Channel | Description | |---------|-----------------------------------|----------------------------| @@ -7155,7 +7167,7 @@ note: Autogenerated example. Replace the id (light) in the channel with your own Group G_light "Yeelight LED Ceiling Light" Switch power "Power" (G_light) {channel="miio:basic:light:power"} Dimmer brightness "Brightness" (G_light) {channel="miio:basic:light:brightness"} -Number ambientBrightness "Ambient Brightness" (G_light) {channel="miio:basic:light:ambientBrightness"} +Dimmer ambientBrightness "Ambient Brightness" (G_light) {channel="miio:basic:light:ambientBrightness"} Number:Time delayoff "Shutdown Timer" (G_light) {channel="miio:basic:light:delayoff"} Number colorTemperature "Color Temperature" (G_light) {channel="miio:basic:light:colorTemperature"} Number colorMode "Color Mode" (G_light) {channel="miio:basic:light:colorMode"} @@ -7272,7 +7284,7 @@ note: Autogenerated example. Replace the id (light) in the channel with your own Group G_light "Yeelight Crystal Pendant Lamp" Switch power "Power" (G_light) {channel="miio:basic:light:power"} Dimmer brightness "Brightness" (G_light) {channel="miio:basic:light:brightness"} -Number ambientBrightness "Ambient Brightness" (G_light) {channel="miio:basic:light:ambientBrightness"} +Dimmer ambientBrightness "Ambient Brightness" (G_light) {channel="miio:basic:light:ambientBrightness"} Number:Time delayoff "Shutdown Timer" (G_light) {channel="miio:basic:light:delayoff"} Number colorTemperature "Color Temperature" (G_light) {channel="miio:basic:light:colorTemperature"} Number colorMode "Color Mode" (G_light) {channel="miio:basic:light:colorMode"} diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/MiIoCommand.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/MiIoCommand.java index 447b51d1c..f16df318f 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/MiIoCommand.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/MiIoCommand.java @@ -86,6 +86,15 @@ public enum MiIoCommand { REMOTE_END("app_rc_end"), REMOTE_MOVE("app_rc_move"), + GET_MAP_STATUS("get_map_status"), + GET_SEGMENT_STATUS("get_segment_status"), + GET_LED_STATUS("get_led_status"), + GET_CARPET_MODE("get_carpet_mode"), + GET_FW_FEATURES("get_fw_features"), + GET_CUSTOMIZED_CLEAN_MODE("get_customize_clean_mode"), + GET_MULTI_MAP_LIST("get_multi_maps_list"), + GET_ROOM_MAPPING("get_room_mapping"), + UNKNOWN(""); private final String command; diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoVacuumHandler.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoVacuumHandler.java index 3b3eba803..30fe0fbe8 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoVacuumHandler.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoVacuumHandler.java @@ -22,10 +22,14 @@ import java.text.SimpleDateFormat; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.Collections; import java.util.Date; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.imageio.ImageIO; @@ -89,6 +93,12 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { private static final Gson GSON = new GsonBuilder().serializeNulls().create(); private final ChannelUID mapChannelUid; + private static final Set 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 ExpiringCache status; private ExpiringCache consumables; private ExpiringCache dnd; @@ -289,6 +299,7 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { safeUpdateState(CHANNEL_IN_CLEANING, statusInfo.getInCleaning()); safeUpdateState(CHANNEL_MAP_PRESENT, statusInfo.getMapPresent()); if (statusInfo.getState() != null) { + stateId = statusInfo.getState(); StatusType state = StatusType.getType(statusInfo.getState()); updateState(CHANNEL_STATE, new StringType(state.getDescription())); updateState(CHANNEL_STATE_ID, new DecimalType(statusInfo.getState())); @@ -464,6 +475,11 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { map.getValue(); } } + for (RobotCababilities cmd : FEATURES_CHANNELS) { + if (isLinked(cmd.getChannel())) { + sendCommand(cmd.getCommand()); + } + } } catch (Exception e) { logger.debug("Error while updating '{}': '{}", getThing().getUID().toString(), e.getLocalizedMessage()); } @@ -530,11 +546,54 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { } } break; + case GET_MAP_STATUS: + case GET_SEGMENT_STATUS: + case GET_LED_STATUS: + updateNumericChannel(response); + break; + case GET_CARPET_MODE: + case GET_FW_FEATURES: + case GET_CUSTOMIZED_CLEAN_MODE: + case GET_MULTI_MAP_LIST: + case GET_ROOM_MAPPING: + for (RobotCababilities cmd : FEATURES_CHANNELS) { + if (response.getCommand().getCommand().contentEquals(cmd.getCommand())) { + updateState(cmd.getChannel(), new StringType(response.getResult().toString())); + break; + } + } + break; default: break; } } + private void updateNumericChannel(MiIoSendCommand response) { + RobotCababilities capabilityChannel = null; + for (RobotCababilities cmd : FEATURES_CHANNELS) { + if (response.getCommand().getCommand().contentEquals(cmd.getCommand())) { + capabilityChannel = cmd; + break; + } + } + if (capabilityChannel != null) { + if (response.getResult().isJsonArray() && response.getResult().getAsJsonArray().get(0).isJsonPrimitive()) { + try { + Integer stat = response.getResult().getAsJsonArray().get(0).getAsInt(); + updateState(capabilityChannel.getChannel(), new DecimalType(stat)); + return; + } catch (ClassCastException | IllegalStateException e) { + logger.debug("Could not update numeric channel {} with '{}': {}", capabilityChannel.getChannel(), + response.getResult(), e.getMessage()); + } + } else { + logger.debug("Could not update numeric channel {} with '{}': Not in expected format", + capabilityChannel.getChannel(), response.getResult()); + } + updateState(capabilityChannel.getChannel(), UnDefType.UNDEF); + } + } + private void setCapabilities(JsonObject statusResponse) { for (RobotCababilities capability : RobotCababilities.values()) { if (statusResponse.has(capability.getStatusFieldName())) { diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RobotCababilities.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RobotCababilities.java index 2d8d5dc33..d30eca08c 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RobotCababilities.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RobotCababilities.java @@ -23,23 +23,33 @@ import org.openhab.core.thing.type.ChannelTypeUID; @NonNullByDefault public enum RobotCababilities { - WATERBOX_STATUS("water_box_status", "status#water_box_status", "miio:water_box_status"), - LOCKSTATUS("lock_status", "status#lock_status", "miio:lock_status"), - WATERBOX_MODE("water_box_mode", "status#water_box_mode", "miio:water_box_mode"), - WATERBOX_CARRIAGE("water_box_carriage_status", "status#water_box_carriage_status", - "miio:water_box_carriage_status"), - MOP_FORBIDDEN("mop_forbidden_enable", "status#mop_forbidden_enable", "miio:mop_forbidden_enable"), - LOCATING("is_locating", "status#is_locating", "miio:is_locating"), - SEGMENT_CLEAN("", "actions#segment", "miio:segment"); + WATERBOX_STATUS("water_box_status", "status#water_box_status", "miio:water_box_status", ""), + LOCKSTATUS("lock_status", "status#lock_status", "miio:lock_status", ""), + WATERBOX_MODE("water_box_mode", "status#water_box_mode", "miio:water_box_mode", ""), + WATERBOX_CARRIAGE("water_box_carriage_status", "status#water_box_carriage_status", "miio:water_box_carriage_status", + ""), + MOP_FORBIDDEN("mop_forbidden_enable", "status#mop_forbidden_enable", "miio:mop_forbidden_enable", ""), + LOCATING("is_locating", "status#is_locating", "miio:is_locating", ""), + SEGMENT_STATUS("", "status#segment_status", "miio:segment_status", "get_segment_status"), + MAP_STATUS("", "status#map_status", "miio:map_status", "get_map_status"), + LED_STATUS("", "status#led_status", "miio:led_status", "get_led_status"), + CARPET_MODE("", "info#carpet_mode", "miio:carpet_mode", "get_carpet_mode"), + FW_FEATURES("", "info#fw_features", "miio:fw_features", "get_fw_features"), + 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", ""); private final String statusFieldName; private final String channel; private final String channelType; + private final String command; - RobotCababilities(String statusKey, String channel, String channelType) { + RobotCababilities(String statusKey, String channel, String channelType, String command) { this.statusFieldName = statusKey; this.channel = channel; this.channelType = channelType; + this.command = command; } public String getStatusFieldName() { @@ -54,9 +64,14 @@ public enum RobotCababilities { return new ChannelTypeUID(channelType); } + public String getCommand() { + return command; + } + @Override public String toString() { - return String.format("Capability %s: status field name: '%s', channel: '%s', channeltype: '%s'.", this.name(), - statusFieldName, channel, channelType); + return String.format("Capability %s: status field name: '%s', channel: '%s', channeltype: '%s'%s%s.", + this.name(), statusFieldName, channel, channelType, command.isBlank() ? "" : ", custom command: ", + command); } } diff --git a/bundles/org.openhab.binding.miio/src/main/resources/OH-INF/thing/vacuumThing.xml b/bundles/org.openhab.binding.miio/src/main/resources/OH-INF/thing/vacuumThing.xml index caee93a44..c9e5e713e 100644 --- a/bundles/org.openhab.binding.miio/src/main/resources/OH-INF/thing/vacuumThing.xml +++ b/bundles/org.openhab.binding.miio/src/main/resources/OH-INF/thing/vacuumThing.xml @@ -15,6 +15,7 @@ + @@ -50,6 +51,9 @@ + + + @@ -95,6 +99,16 @@ + + + + + + + + + + @@ -152,6 +166,21 @@ + + Number + + + + + Number + + + + + Number + + + @@ -358,4 +387,29 @@ + + + + String + + + + + String + + + + + String + + + + + String + + + + String + +