Xiaomi Robot Vacuum Binding

@marcel_verpaalen
I updated to the “alpha” binding this afternoon. Everything went swimmingly except for the Roborock S6.
Openhab 2.5.3 (with 2.5.4 Miio binding downloaded using the links in this thread).
The binding detects two things as expected, one with the suffix “with token”.
Adding that Thing, everything seems to work fine, the token is extracted and stored in the Thing. However, but it is recognized as “miio:unsupported”.
The same applies if I add the token to the other of the two things.
The vacuum is identified as: roborock.vacuum.s6
It has the firmware version: 3.5.4_1048

The vacuum was properly recognized using the 2.5.3 binding and manually adding the token.
Do you have any idea or advice what to try?

I may be my excessive cleaning in the last build… there were 2 entries for rockrobo.vacuum.s6 and I thought I had a duplicate with roborock.vacuum.s6 maybe some sort of firmware thing where the one is reported differently than the other. Anyway, I added it back again.

In the mean time, pls update your model to another vacuum like the s5 or add it as a miio:vacuum thing

Many thanks for the instant feedback.
/Daniel

Regarding fan -1 issue…
This is for the Roborock S5.
Is it worthwhile updating the binding? I’m still on 2.4. The fan used to work, so yeah it’s likely a vacuum firmware update has possibly changed the way the fan speed is reported.

Hi!

First, thanks for your work, works like a charm :slight_smile:

An unexpected feature (or bug?) I found: If I clean the cache of openhab via the CLI, the vacuum thing (not the binding!) always forgets the country code and then I get consequently a connection error. Took my quite a while to figure this out :wink: Is this intended and/or expected behaviour?

Best
Stefan

That is unexpected behavior…
Do you maybe have a mix of text & paperUI config? Was your vacuum offline when you did that?
(in the discovery I set the country only if the vacuum is online for that county)

Most likely the device was offline. The vacuum is actually not like always online, more sporadically, though commands work very well and items are updated rather reliably. The configuration of the binding and the things is done fully done through the paper ui, used the discovery, but the items are in text configs.

So I also try to get the map of the roborock s50 but I am not able to enter my cloud in the binding. I am not able to edit the binding anyway:

In the addons - bindings it says i am on binding version 2.5.3

Do I also need the smart home binding?
I installed OpenHab this week, so I expect I am on the latest version:

openHAB 2.5.3 Release Build

Kind regards,
Eric

@eric1905 you have the latest stable build.
This is very new and only in the 2.4-snapshots so indeed you don’t have it yet.

So how can I install the snapshot? I thought you mentioned that it is merged to the release branch so i expected that i should see it too.

Hi! I installed the latest snapshot. But when trying to obtain the token from the cloud, I’m getting this error. Not sure what causes it, can anybody steer me in the right direction?

2020-04-17 22:43:14.953 [DEBUG] [miio.internal.cloud.MiCloudConnector] - Xiaomi cloud login with userid #.###########
2020-04-17 22:43:14.955 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi Login step 1
2020-04-17 22:43:15.991 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi Login step 1 content response= &&&START&&&{"serviceParam":"{\"checkSafePhone\":false}","qs":"%3Fsid%3Dxiaomiio%26_json%3Dtrue","code":70016,"captchaUrl":null,"callback":"https://sts.api.io.mi.com/sts","location":"","_sign":"0psXfr43eNI0IX6q9Suk3qWbRqU=","desc":"登录验证失败","sid":"xiaomiio"}
2020-04-17 22:43:15.996 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi Login step 1 response = HttpContentResponse[HTTP/1.1 200 OK - 268 bytes]
2020-04-17 22:43:15.998 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi Login step 1 sign = 0psXfr43eNI0IX6q9Suk3qWbRqU=
2020-04-17 22:43:16.000 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi Login step 2
2020-04-17 22:43:16.298 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi login step 2 response = HttpContentResponse[HTTP/1.1 200 OK - 224 bytes]
2020-04-17 22:43:16.300 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi login step 2 content = &&&START&&&{"qs":"%3Fsid%3Dxiaomiio%26_json%3Dtrue","code":70016,"captchaUrl":null,"callback":"https://sts.api.io.mi.com/sts","location":"","_sign":"0psXfr43eNI0IX6q9Suk3qWbRqU=","desc":"登录验证失败","sid":"xiaomiio"}
2020-04-17 22:43:16.302 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi login ssecurity =
2020-04-17 22:43:16.304 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi login userId =
2020-04-17 22:43:16.306 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi login cUserId =
2020-04-17 22:43:16.308 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi login passToken =
2020-04-17 22:43:16.309 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi login location =
2020-04-17 22:43:16.311 [TRACE] [miio.internal.cloud.MiCloudConnector] - Xiaomi login code = 70016
2020-04-17 22:43:16.313 [TRACE] [miio.internal.cloud.MiCloudConnector] - Cookie dump for https://account.xiaomi.com/pass/serviceLoginAuth2
2020-04-17 22:43:16.315 [TRACE] [miio.internal.cloud.MiCloudConnector] - Cookie (.xiaomi.com) : sdkVersion --> accountsdk-18.8.15     (path: /. Removed: false)
2020-04-17 22:43:16.317 [TRACE] [miio.internal.cloud.MiCloudConnector] - Cookie (.xiaomi.com) : deviceId --> wwyzcz     (path: /. Removed: false)
2020-04-17 22:43:16.318 [TRACE] [miio.internal.cloud.MiCloudConnector] - Cookie (.xiaomi.com) : uLocale --> nl_NL     (path: /. Removed: false)
2020-04-17 22:43:16.320 [TRACE] [miio.internal.cloud.MiCloudConnector] - Cookie (account.xiaomi.com) : pass_ua --> web     (path: /. Removed: false)
2020-04-17 22:43:16.321 [INFO ] [miio.internal.cloud.MiCloudConnector] - Error logging on to Xiaomi cloud (0): Error getting logon location URL. Return code: 70016

The Chinese is logon failed. Mostly that is due to wrong userid/passwd
If not… dunno. The return code: 70016 or other codes for that matter are not known yet

1 Like

Thank you for a quick reply. I reverted to 2.5.3 and punched in token manually for now

Did some already tried to implement this?
thanks :slight_smile:

You r in luck…
This was merged yesterday into the snapshot version. It has support for the new protocol.
Also I made some tooling to easily implement next devices. My aim is to bring that piece into the unsupported device driver, so even newer devices can be automatically get full list of available channels

Actually I see it just made it into the 2.5.4 release!
Which for this binding is one of the biggest changes it has seen in one release.

  • Cloud support (experimental), easy tokens
  • Vacuum map
  • Conditional execution of command to support dimmers
  • Multiple actions linked to one channel
  • Support for more complex action command
  • Improve brightness channels for most yeelights and Phillips lights. NB: They became Dimmers items. This requires you to update your config!
  • Miot devices support, as this will be the next gen protocol many devices can be added soon
  • Many small improvement to improve general stability and connection issues
2 Likes

I have updated to 2.5.4
Now I can’t change brightness of my Xiaomi Desk Lamp. It always stays at 0.
Maybe channels names have changed? It looks like there is no any event even enabling DEBUG logging when I change brightness.
Ps.: It is now a Dimmer channel not a Number. I might have missed this…

I made it more explicit now in my message.
This will alow the folks using Alexa/Google Home to control it properly

Sorry if I’m going to far from the vacuum, but it is the same binding after all.

I changed mine to dimmer and it works but the slider seems very unresponsive. Say I put it at 100, it will jump back to like 22 while dimming to 100 etc… I don’t know if I’m doing something wrong but it’s way worse than before.

Again, e.g I slide it to e.g “100 %” and the lights dim to 100% but now the slider jumps to 37% and keeps indicating that my light dimmed to 100% is indeed at 37%.

08:31:25.780 [INFO ] [smarthome.event.ItemCommandEvent     ] - Item 'yeelight_stripe_brightness' received command 100.0
08:31:25.785 [DEBUG] [iio.internal.handler.MiIoBasicHandler] - Locating action for channel brightness: 100.0
08:31:25.786 [DEBUG] [iio.internal.handler.MiIoBasicHandler] - Conditional command set_bright[] not send, condition BrightnessExisting not met
08:31:25.786 [DEBUG] [iio.internal.handler.MiIoBasicHandler] - Sending command set_power["on"]
08:31:25.787 [DEBUG] [rnal.transport.MiIoAsyncCommunication] - Command added to Queue {"id":189,"method":"set_power","params":["on"]} -> 192.168.1.235 (Device: 07C2B5E2 token: 1DA92716XXXXXXXXXXXXXXXX2F929621 Queue: 1)
08:31:25.787 [DEBUG] [iio.internal.handler.MiIoBasicHandler] - Periodic update for 'miio:generic:07C2B5E2' (miio:basic)
08:31:25.788 [DEBUG] [rnal.transport.MiIoAsyncCommunication] - Command added to Queue {"id":190,"method":"get_prop","params":["power","bright","delayoff","ct","color_mode"]} -> 192.168.1.235 (Device: 07C2B5E2 token: 1DA92716XXXXXXXXXXXXXXXX2F929621 Queue: 2)
08:31:25.788 [DEBUG] [rnal.transport.MiIoAsyncCommunication] - Command added to Queue {"id":191,"method":"get_prop","params":["rgb","name"]} -> 192.168.1.235 (Device: 07C2B5E2 token: 1DA92716XXXXXXXXXXXXXXXX2F929621 Queue: 3)
08:31:25.789 [INFO ] [arthome.event.ItemStatePredictedEvent] - yeelight_stripe_brightness predicted to become 100.0
08:31:25.794 [INFO ] [smarthome.event.ItemStateChangedEvent] - yeelight_stripe_brightness changed from 37 to 100.0
08:31:25.889 [DEBUG] [.internal.handler.MiIoAbstractHandler] - Received response for 07C2B5E2 type: SET_POWER, result: ["ok"], fullresponse: {"result":["ok"],"id":189}
08:31:25.892 [DEBUG] [.internal.handler.MiIoAbstractHandler] - Received response for 07C2B5E2 type: GET_PROPERTY, result: ["on","37","0","5000","1"], fullresponse: {"result":["on","37","0","5000","1"],"id":190}
08:31:25.897 [INFO ] [smarthome.event.ItemStateChangedEvent] - yeelight_stripe_brightness changed from 100.0 to 37

Also, a side note to anyone who might know more than me, why isn’t the dimmer channel on the “Color” item used for brightness? Why do we need a separate dimmer for that?

Hi,

I updated to openhab 2.5.4 and now my xiaomi vaccum is not working anymore.
I tried to re-add the thing but it ist not working.

i always get following error in the log:

2020-04-20 09:50:16.014 [me.event.InboxRemovedEvent] - Discovery Result with UID ‘miio:vacuum:03DA6494’ has been removed.
2020-04-20 09:50:16.047 [hingStatusInfoChangedEvent] - ‘miio:vacuum:03DA6494’ changed from UNINITIALIZED to UNINITIALIZED (HANDLER_REGISTERING_ERROR)

2020-04-20 09:50:16.041 [WARN ] [.core.thing.binding.BaseThingHandler] - Handler MiIoVacuumHandler of thing miio:vacuum:03DA6494 tried updating channel consumables#consumable_reset although the handler was already disposed.
2020-04-20 09:50:16.047 [ERROR] [core.thing.internal.ThingManagerImpl] - Exception occurred while calling thing handler factory ‘org.openhab.binding.miio.internal.MiIoHandlerFactory@2e7d4b8b’: null
java.lang.NullPointerException: null
at org.openhab.binding.miio.internal.handler.MiIoAbstractHandler.tokenCheckPass(MiIoAbstractHandler.java:134) ~[?:?]
at org.openhab.binding.miio.internal.handler.MiIoAbstractHandler.getConnection(MiIoAbstractHandler.java:288) ~[?:?]
at org.openhab.binding.miio.internal.handler.MiIoVacuumHandler.initializeData(MiIoVacuumHandler.java:407) ~[?:?]
at org.openhab.binding.miio.internal.handler.MiIoVacuumHandler.(MiIoVacuumHandler.java:95) ~[?:?]
at org.openhab.binding.miio.internal.MiIoHandlerFactory.createHandler(MiIoHandlerFactory.java:91) ~[?:?]
at org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory.registerHandler(BaseThingHandlerFactory.java:126) ~[bundleFile:?]
at org.eclipse.smarthome.core.thing.internal.ThingManagerImpl.doRegisterHandler(ThingManagerImpl.java:587) [bundleFile:?]
at org.eclipse.smarthome.core.thing.internal.ThingManagerImpl.registerHandler(ThingManagerImpl.java:564) [bundleFile:?]
at org.eclipse.smarthome.core.thing.internal.ThingManagerImpl.registerAndInitializeHandler(ThingManagerImpl.java:1056) [bundleFile:?]
at org.eclipse.smarthome.core.thing.internal.ThingManagerImpl.thingAdded(ThingManagerImpl.java:445) [bundleFile:?]
at org.eclipse.smarthome.core.thing.internal.ThingRegistryImpl.notifyTrackers(ThingRegistryImpl.java:211) [bundleFile:?]
at org.eclipse.smarthome.core.thing.internal.ThingRegistryImpl.notifyListenersAboutAddedElement(ThingRegistryImpl.java:131) [bundleFile:?]
at org.eclipse.smarthome.core.thing.internal.ThingRegistryImpl.notifyListenersAboutAddedElement(ThingRegistryImpl.java:1) [bundleFile:?]
at org.eclipse.smarthome.core.common.registry.AbstractRegistry.added(AbstractRegistry.java:157) [bundleFile:?]
at org.eclipse.smarthome.core.common.registry.AbstractRegistry.added(AbstractRegistry.java:1) [bundleFile:?]
at org.eclipse.smarthome.core.common.registry.AbstractProvider.notifyListeners(AbstractProvider.java:56) [bundleFile:?]
at org.eclipse.smarthome.core.common.registry.AbstractProvider.notifyListeners(AbstractProvider.java:75) [bundleFile:?]
at org.eclipse.smarthome.core.common.registry.AbstractProvider.notifyListenersAboutAddedElement(AbstractProvider.java:79) [bundleFile:?]
at org.eclipse.smarthome.core.common.registry.AbstractManagedProvider.add(AbstractManagedProvider.java:64) [bundleFile:?]
at org.eclipse.smarthome.core.common.registry.AbstractRegistry.add(AbstractRegistry.java:325) [bundleFile:?]
at org.eclipse.smarthome.config.discovery.internal.PersistentInbox.addThingSafely(PersistentInbox.java:630) [bundleFile:?]
at org.eclipse.smarthome.config.discovery.internal.PersistentInbox.approve(PersistentInbox.java:203) [bundleFile:?]
at org.eclipse.smarthome.io.rest.core.internal.discovery.InboxResource.approve(InboxResource.java:104) [bundleFile:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_252]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_252]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_252]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_252]
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) [bundleFile:?]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) [bundleFile:?]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) [bundleFile:?]
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) [bundleFile:?]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) [bundleFile:?]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) [bundleFile:?]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) [bundleFile:?]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) [bundleFile:?]
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) [bundleFile:?]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [bundleFile:?]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [bundleFile:?]
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [bundleFile:?]
at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [bundleFile:?]
at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [bundleFile:?]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [bundleFile:?]
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) [bundleFile:?]
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) [bundleFile:?]
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) [bundleFile:?]
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) [bundleFile:?]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) [bundleFile:?]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) [bundleFile:?]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) [bundleFile:?]
at com.eclipsesource.jaxrs.publisher.internal.ServletContainerBridge.service(ServletContainerBridge.java:76) [bundleFile:?]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:852) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:544) [bundleFile:9.4.20.v20190813]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) [bundleFile:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:536) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1581) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1307) [bundleFile:9.4.20.v20190813]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:293) [bundleFile:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:482) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1549) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1204) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [bundleFile:9.4.20.v20190813]
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80) [bundleFile:?]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.Server.handle(Server.java:494) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:374) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:268) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:367) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:782) [bundleFile:9.4.20.v20190813]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:918) [bundleFile:9.4.20.v20190813]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_252]

I already tried to remove thing → uninstall binding → stop openhab → clean chache → start openhab → reinstall binding, add Thing

But at the moment i add the robot vacuum thing, i will get this error…