Xiaomi Robot Vacuum Binding

hi, i have a not binding related issue, i thing.

everything is working fine, including zone cleaning, as long as i use the android/iphone app or basic UI.
however via habpanel and the selection widget the rule is not getting triggered.

i have the feeling i’m missing something simple here :face_with_raised_eyebrow:

log when triggered via App or Basic UI

2018-05-14 18:21:08.585 [vent.ItemStateChangedEvent] - vacZoneCleaning changed from 0 to 1

2018-05-14 18:21:08.611 [ome.event.ItemCommandEvent] - Item 'actionCommand' received command app_zoned_clean[[22041,23089,26491,27289,1]]

via habpanel but no rule triggered

2018-05-14 18:25:12.453 [vent.ItemStateChangedEvent] - vacZoneCleaning changed from 0 to 1

selection widget

items

Group  gVac     "Xiaomi Robot Vacuum"      <vacuum>
Group  gVacStat "Status Details"           <status> (gVac)
Group  gVacCons "Consumables Usage"        <line-increase> (gVac)
Group  gVacDND  "Do Not Disturb Settings"  <moon> (gVac)
Group  gVacHist "Cleaning History"         <calendar> (gVac)
Group  gVacNetwork "Network Details"       <network> (gVac)

String actionControl  "Vacuum Control"     (gVac)	{channel="miio:vacuum:04EF787F:actions#control" }
Number actionFan      "Vacuum Fan"         (gVac)   {channel="miio:vacuum:04EF787F:actions#fan" }
String actionCommand  "Vacuum Command"          	{channel="miio:vacuum:04EF787F:actions#commands" }
Switch vacONOFF		  "Vacuum"	   (gVac)   [ "Switchable" ]   {channel="miio:vacuum:04EF787F:actions#vacuum" }
Number vacZoneCleaning "Cleaning Zone"     (gVac)

Number statusBat    		"Battery Level [%1.0f%%]" <battery>   (gVac,gVacStat) {channel="miio:vacuum:04EF787F:status#battery" }
Number statusArea    		"Cleaned Area [%1.0fm�]" <zoom>   (gVac,gVacStat) {channel="miio:vacuum:04EF787F:status#clean_area" }
Number statusTime    		"Cleaning Time [%1.0f']" <clock>   (gVac,gVacStat) {channel="miio:vacuum:04EF787F:status#clean_time" }
String statusError    		"Error [%s]"  <error>  (gVac,gVacStat) {channel="miio:vacuum:04EF787F:status#error_code" }
Number statusFanPow    		"Fan Power [%1.0f %%]"  <signal>   (gVacStat) {channel="miio:vacuum:04EF787F:status#fan_power" } 
Number statusClean    		"In Cleaning Status [%1.0f]"   <switch>  (gVacStat) {channel="miio:vacuum:04EF787F:status#in_cleaning" }
Switch statusDND    		"DND Activated"    (gVacStat) {channel="miio:vacuum:04EF787F:status#dnd_enabled" }
String statusStatus  		"Status [%s]"  <status>  (gVacStat) {channel="miio:vacuum:04EF787F:status#state"} 
String lastcleanstat        "Status last Cleaning"  (gVacStat)  {channel="miio:vacuum:04EF787F:cleaning#last_clean_finish"}

Number consumableMainT   	"Main Brush [%1.0f]"    (gVacCons) {channel="miio:vacuum:04EF787F:consumables#main_brush_time"}
Number consumableMainP    	"Main Brush [%1.0f%%]"    (gVacCons) {channel="miio:vacuum:04EF787F:consumables#main_brush_percent"}
Number consumableSideT    	"Side Brush [%1.0f]"    (gVacCons) {channel="miio:vacuum:04EF787F:consumables#side_brush_time"}
Number consumableSideP		"Side Brush [%1.0f%%]"    (gVacCons) {channel="miio:vacuum:04EF787F:consumables#side_brush_percent"}
Number consumableFilterT    "Filter Time[%1.0f]"    (gVacCons) {channel="miio:vacuum:04EF787F:consumables#filter_time" }
Number consumableFilterP    "Filter Time[%1.0f%%]"    (gVacCons) {channel="miio:vacuum:04EF787F:consumables#filter_percent" }
Number consumableSensorT    "Sensor [%1.0f]"    (gVacCons) {channel="miio:vacuum:04EF787F:consumables#sensor_dirt_time"}
Number consumableSensorP    "Sensor [%1.0f%%]"    (gVacCons) {channel="miio:vacuum:04EF787F:consumables#sensor_dirt_percent"}


Switch dndFunction   "DND Function" <moon>   (gVacDND) {channel="miio:vacuum:04EF787F:dnd#dnd_function"}
String dndStart   "DND Start Time [%s]" <clock>   (gVacDND) {channel="miio:vacuum:04EF787F:dnd#dnd_start"}
String dndEnd   "DND End Time [%s]"   <clock-on>  (gVacDND) {channel="miio:vacuum:04EF787F:dnd#dnd_end"}

Number historyArea    "Total Cleaned Area [%1.0fm�]" <zoom>    (gVacHist) {channel="miio:vacuum:04EF787F:history#total_clean_area"}
Number historyTime    "Total Clean Time [%1.0f']"   <clock>     (gVacHist) {channel="miio:vacuum:04EF787F:history#total_clean_time"}
Number historyCount    "Total # Cleanings [%1.0f]"  <office>  (gVacHist) {channel="miio:vacuum:04EF787F:history#total_clean_count"}

String  miNetSSID    "Network SSID [%s]"  <network>  (gVac,gVacNetwork) {channel="miio:vacuum:04EF787F:network#ssid" }
String  miNetBSSID    "Network BSSID [%s]"  <network>  (gVac,gVacNetwork) {channel="miio:vacuum:04EF787F:network#bssid" }
Number  miNetRSSI    "Network RSSI [%1.0f]"  <network>  (gVac,gVacNetwork) {channel="miio:vacuum:04EF787F:network#rssi" }
Number  miNetLife    "Uptime [%1.0f]"  <clock>  (gVac,gVacNetwork) {channel="miio:vacuum:04EF787F:network#life" }

sitemap

Frame label="Others" {	
	Group item=gVac {
		Switch item=actionControl mappings=[pause="Pause",spot="Spot", dock="Dock"]
 		Switch item=actionFan mappings=[38="Silent", 60="Normal", 77="Power",90="Full", -1="Custom"]
		Selection	item=vacZoneCleaning mappings=[9="All", 1="Master Bedroom", 2="Master Bathroom", 3="Liams Room", 4="Guest Bathroom", 5="Guest Room", 6="Kitchen", 7="Living/Dining", 8="Toilette/Entrance"]
		Default item=statusBat 
		Default item=statusArea 
		Default item=statusTime 
		Group  item=gVacStat
		Group  item=gVacCons
		Group  item=gVacDND
		Group  item=gVacHist
		Group  item=gVacNetwork
	}

rule

rule "Zone Cleaning"
 when
    Item vacZoneCleaning changed
 then
  switch (vacZoneCleaning.state) {
    case 1: {
        sendCommand(actionCommand,"app_zoned_clean[[22041,23089,26491,27289,1]]")
          }
    case 2: {
        sendCommand(actionCommand,"app_zoned_clean[[22394,27149,24744,29549,1]]")
        }
    case 3: {
        sendCommand(actionCommand,"app_zoned_clean[[18620,22211,22020,26361,1]]")
        }
    case 4: {
        sendCommand(actionCommand,"app_zoned_clean[[19404,27529,21154,29829,1]]")
        }
    case 5: {
        sendCommand(actionCommand,"app_zoned_clean[[14968,22644,18568,26344,1]]")
        }
    case 6: {
        sendCommand(actionCommand,"app_zoned_clean[[12130,28000,18130,30900,1]]")
        }
    case 7: {
        sendCommand(actionCommand,"app_zoned_clean[[7473,23801,14873,28101,1]]")
        }
    case 8: {
        sendCommand(actionCommand,"app_zoned_clean[[8856,28234,11956,30900,1]]")
        }
    case 9: {
        sendCommand(actionCommand,"app_zoned_clean[[7662,22054,26712,30804,1]]")
        }
  }
  end

rule "change status"
    when
        Item statusStatus changed to Charging
    then 
        vacZoneCleaning.postUpdate(0)
end

Hi there,

I’m getting this error. Can anybody please shed some light? I’ve retrieved the token via the MiToolKit and have entered it in, yet PaperUI still says OFFLINE _CONFIGURATIONERROR.

2018-05-15 18:08:42.616 [ERROR] [ome.core.thing.link.ThingLinkManager] - Exception occurred while informing handler: null
java.lang.NullPointerException: null
	at org.openhab.binding.miio.handler.MiIoVacuumHandler.skipUpdate(MiIoVacuumHandler.java:275) ~[?:?]
	at org.openhab.binding.miio.handler.MiIoVacuumHandler.updateData(MiIoVacuumHandler.java:285) ~[?:?]
	at org.openhab.binding.miio.handler.MiIoVacuumHandler.handleCommand(MiIoVacuumHandler.java:71) ~[?:?]
	at org.eclipse.smarthome.core.thing.binding.BaseThingHandler.channelLinked(BaseThingHandler.java:243) ~[?:?]
	at org.eclipse.smarthome.core.thing.link.ThingLinkManager.lambda$0(ThingLinkManager.java:290) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:?]
	at java.util.concurrent.FutureTask.run(Unknown Source) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:?]
	at java.lang.Thread.run(Unknown Source) [?:?]
2018-05-15 18:08:42.679 [WARN ] [nal.transport.MiIoAsyncCommunication] - Error while polling/sending message
java.lang.NullPointerException: null
	at java.security.MessageDigest.update(Unknown Source) [?:?]
	at java.security.MessageDigest.digest(Unknown Source) [?:?]
	at org.openhab.binding.miio.internal.MiIoCrypto.md5(MiIoCrypto.java:34) [218:org.openhab.binding.miio:2.3.0.201803300959]
	at org.openhab.binding.miio.internal.MiIoCrypto.encrypt(MiIoCrypto.java:67) [218:org.openhab.binding.miio:2.3.0.201803300959]
	at org.openhab.binding.miio.internal.transport.MiIoAsyncCommunication.sendCommand(MiIoAsyncCommunication.java:231) [218:org.openhab.binding.miio:2.3.0.201803300959]
	at org.openhab.binding.miio.internal.transport.MiIoAsyncCommunication.sendMiIoSendCommand(MiIoAsyncCommunication.java:154) [218:org.openhab.binding.miio:2.3.0.201803300959]
	at org.openhab.binding.miio.internal.transport.MiIoAsyncCommunication$MessageSenderThread.run(MiIoAsyncCommunication.java:206) [218:org.openhab.binding.miio:2.3.0.201803300959]

Same error, My vaccum is online when agree the token but after seconds go to offline

solved it. amended the rule slightly as below and everything is OK now.

rule "Zone Cleaning"
 when
    Item vacZoneCleaning received command
 then
  switch (receivedCommand.toString) {
    case "1": {
        sendCommand(actionCommand,"app_zoned_clean[[22041,23089,26491,27289,1]]")
          }
    case "2": {
        sendCommand(actionCommand,"app_zoned_clean[[22394,27149,24744,29549,1]]")
        }
    case "3": {
        sendCommand(actionCommand,"app_zoned_clean[[18620,22211,22020,26361,1]]")
        }
    case "4": {
        sendCommand(actionCommand,"app_zoned_clean[[19404,27529,21154,29829,1]]")
        }
    case "5": {
        sendCommand(actionCommand,"app_zoned_clean[[14968,22644,18568,26344,1]]")
        }
    case "6": {
        sendCommand(actionCommand,"app_zoned_clean[[12130,28000,18130,30900,1]]")
        }
    case "7": {
        sendCommand(actionCommand,"app_zoned_clean[[7473,23801,14873,28101,1]]")
        }
    case "8": {
        sendCommand(actionCommand,"app_zoned_clean[[8856,28234,11956,30900,1]]")
        }
    case "9": {
        sendCommand(actionCommand,"app_zoned_clean[[7662,22054,26712,30804,1]]")
        }
  }
  end

rule "change status"
    when
        Item statusStatus changed to Charging
    then 
        vacZoneCleaning.postUpdate(0)
end

2 Likes

@sonyxperiageek this looks more a generic openhab issue you have there (handler seems not to be loaded).

I would suggest to un-install the binding, restart openhab, and re-install the binding.

This is the typical pattern when the token is actually wrong… the first online is when the binding can ping the vacuum (meaning the IP is correct etc). The following few second changing to offline means that messages are not passing correctly / can’t be decoded. (=typically a token issue)

Just did that to no avail unfortunately. In PaperUI I only need to make sure the IP address is correct, as well as enter in the token right? Everything else I can leave blank or default?

@marcel_verpaalen Is this somehow a way to get the timers for scheduled cleanings? Or it is the same as the map, stored in the cloud?
Is it a better idea to write rules for scheduled cleanings in openhab? I would like to send warning on Telegram few hours before the cleaning starts…

Yes, that how it worked for me. Just needed to get the token from my phone.

The scheduled cleaning as far as I know is don eon the device itself. You need to send a ‘cron’ - like command to the device to schedule this. The binding itself does not provide a way to set it, but you can use the command channel to send the command.

See for the commands here: look for the timer commands

Indeed the alternative would be to schedule it with openhab, it is the same cron-style scheduling… hence it does not differ very much. Maybe it will allow easier connection with telegram though.

Thanks for your answer, I think get_timer is what I’m looking for!

Sorry, one more question: I have the latest firmware so now I can use the zoned_clean command… However where I can get the coordinates? How can I measure or get coordinates in my home to specific places?

Hmmm unless my token is wrong. But I extracted it direct from MiToolKit and I only have one XiaoMi product in the house which is the vacuum.

As far as I can remember, if you read the data with MiToolKit, it will give you back in response a bunch of data, mainly seperated with spaces… Maybe have a look at, if you copied some whitespace into the token key… (mainly beginning and end, where it is not so obvious…)

When does the token change? an update of the app or software ?.
Before it worked without problems, perhaps the token has changed.
I have to review it.

Is this working in the latest MI Home App? IOS or Android?

I was unable to get the coordinates on iOS and Android as well…
On Android I have not the latest Mi Home app (the last where I was able to extract the token from…)

Ps.: If you read back, you’ll find that this work only in the Flole app.
However, I was unable to use this, because when I try to log in, it says that unknown error occured…
Maybe it’s because if I want to login in Mi Home, it needs a captcha, not just my password?

Hello,

i have a question about a Zone Cleaning Rule:

my rule is this and it works:

rule "RobotVacCleanBedroom"
when
	Item RobotVacCleanBedroom changed to ON
then

{
        sendCommand(actionCommand,"app_zoned_clean[[29057,15786,32307,19986,1]]")
        Thread::sleep(2000)
        EchoStube_Speak.sendCommand("Reiniung Schlafzimmer gestartet")
        RobotVacCleanBedroom.sendCommand(OFF)

 
}

I want add "when statusStatus to Returning Dock echo EchoStube_Speak.sendCommand(“Reiniung Küche abgeschlossen”)

it try this but this doesent work, maybe someone can help me.

   rule "RobotVacCleanBedroom"
when
	Item RobotVacCleanBedroom changed to ON
then

{
        sendCommand(actionCommand,"app_zoned_clean[[29057,15786,32307,19986,1]]")
        Thread::sleep(2000)
        EchoStube_Speak.sendCommand("Reiniung Schlafzimmer gestartet")
        RobotVacCleanBedroom.sendCommand(OFF)
     if (statusStatus.state=="Returning Dock") {
        EchoStube_Speak.sendCommand("Reiniung Abgeschlossen, kehre zum Dock zurück")
        }
 
}

I don’t know what is this statusStatus item, but if it is the actionCommand item in your Robot Vacuum (where you can start cleaning, dock, etc…) it’s because it returns not ‘Returning Dock’, but simply dock

Like this:

Switch item=actionControl mappings=[vacuum="Vacuum", pause="Pause",spot="Spot", dock="Dock"]

Also I forgot to mention, but this will never get executed (the if clause). Because this rule will run once when you press the button to clean the Bedroom. It won’t finish immediately and it will never say send this command to EchoTube

You need to create another, seperate rule for that
Anyway where did you get the coordinates?

Thanks

Use the https://xiaomi.flole.de/ (Flole App) choose Area Cleaning → expand an area → hold the go button for 2 secs. and you have the coordinates in your clipboard.

2 Likes

And how did you set it up? When I want to login to my Xiaomi account I get unknown error.