Roborock binding for robot vacuum cleaners [5.0.0.0;5.1.0.0)

I can reproduce this behavior. It happens every time you create a vacuum thing, and change the suggested UID thing name to a custom one.

I am not on the marketplace version of the binding, but on the official 5.1.0 release version and I reproduced it with an saros 10R.

Hi Paul, All my channels are read or written. Even the routine mapping and the floor mapping. Thiis is the only channel which remains empty (NULL). I f I look in the trace logs, this is the one closest to what you describe:
org.openhab.binding.roborock.internal.RoborockVacuumHandler
Received MQTT message: {“t”:1768141230,“dps”:{“102”:“{“id”:20475,“result”:[[16,“8694029”,13],[17,“8694028”,6],[18,“8693296”,12],[19,“9693435”,12]]}”}}

You are right. When I change the name of the vacuum thing to the DUID, it is working. At least I get values for most of the channels. That’s however not the way I prefer to name my things. Did someone already create an issue on github for that?

[roborock] Set 'representation-property' correctly in things.xml to prevent items being rediscovered by psmedley · Pull Request #20028 · openhab/openhab-addons · GitHub will fix this once approved.

https://smedley.id.au/tmp/org.openhab.binding.roborock-5.2.0-SNAPSHOT.jar contains the latest fixes.

Let me check behaviour on my S7 Pure. Confirmed this is broken….. Working on a fix, it’s funky code so bear with me…

Edit: [roborock] Fix Room mapping channel by psmedley · Pull Request #20046 · openhab/openhab-addons · GitHub is the fix, URL in post previous to this has the fix.

1 Like

Hi,

my whole setup is very declarative (all in files,if possible no interaction with the UI). I configured the roborock integration like that:

Bridge roborock:account:account \[ email="<my_mail>.com", twofa=“123456” \] {
roborock:vacuum:QrevoS \[ refresh=5, duid=“<duid data>” \]
}

Unfortunately, it does not allow setting the twofa via file. In the UI it is then displayed as blank and sends another verification mail. I always try my files from a fresh installation. Anything I am missing?

It’t working via files, that’s what I did to. First create the Bridge with only the e-mail. When you get the mail add the “twofa” and it should become online (maybe you have to stop and start the thing via the UI for that). After that add the vacuum thing.

but it does not work stateless. I am not sure if this is a limitation of the roborock API or the implementation.

Scenario that does not work:

  1. enter email, leave 2FA-code blank.
  2. Enter received code in the thing.
  3. Move the thing file to a new/fresh openHab installation, taking over the 2FA-code.

The token file is stored in /var/lib/openhab/json-db (or something like that). Moving this file across as well as the things file should work provided the thing-id is kept the same.

1 Like

Hi!

perhaps a stupid question, but is the Q10 S5 also supported by the binding?

cheers

Andreas

Not a stupid question - the Q7 and Q10 series use different protocols to other vacuums. Support for this is planned (time permitting) once the Homie and/or python-roborock implementations are complete.

1 Like

Hi,

I‘m trying to build a Dashboard for cleaning different rooms of my house in different cleaning modes. I‘m thinking about some switches in my Main UI to configure what the robot has to clean, and finally send commands via „executeCommand“ to the robot.

As I figured out in this thread, there is a command called „app_segment_clean“ which tells the robot which rooms should be cleaned. I‘m looking for commands for changing the active map and for selecting the cleaning mode like „vac&mop“ or only „vac“.

Is there a documentation about the available commands or a tutorial? Or has maybe anyone figured out which commands I have to send e. g. for the following scenario:

  1. Switch to vacuum mode (no mopping)
  2. Change the Map to 2. floor
  3. Clean the segments 13 and 17.

Regards,

Boris

  1. is easy - thta’s what app_segment_clean and the corresponding channel actions#segment are for.

  2. might be possible using status#mop-mode - although there doesn’t seem to be an option for ‘none’ - I’ll look into that.

  3. I don’t think there is any current way without using executeCommand

You can turn off mop with water-box-mode
Item

Number                       VaccumingRobot_01_WaterBoxMode                 "Water Box Mode \[%.0f%%\]"                                 (VaccumingRobot_01)      \["Control", "Mode"\]             {channel="roborock:vacuum:6032cc6fc8:3UwVu2bllGDFVBoHA75Hwq:status#water-box-mode"}

Selection item=VaccumingRobot_01_WaterBoxMode label="Tryb mopa \[%.1f%%\]" icon="f7:drop" mappings=\[200="Off", 201="Weak", 202="Standard", 203="Strong", 204="Aggressive", 235="First vaccuum, then mop", 209="Smart"\] iconcolor=\["blue"\]

Although to be honest, I use flows for some preset modes. As for numbers, they might differ per robot - numbers above are for Saros 10.

I also use execute command instead of channel, so that I can also specify repeat count and clean order like this

            VaccumingRobot_01_ExecuteCommand.sendCommand("app_segment_clean,\[{\\"segments\\":\[" + zone_kitchen +"\],\\"repeat\\":" + VaccumingRobot_01_RepeatCount.state + ",\\"clean_order_mode\\":0}\]")

Thanks for reminding me - some of these vlaues are documented in:

I’m trying to figure out why my info#room-mapping channel is not being populated. In TRACE mode I can see the rooms in the JSON.

Maybe on an old version of the binding?

320 │ Active │  80 │ 5.1.0.202512211512    │ org.openhab.binding.roborock
    "rooms": [
      {
        "id": 16154798,
        "name": "Closet"
      },
      {
        "id": 16154788,
        "name": "Default"
      },
      {
        "id": 16154786,
        "name": "Laundry Room"
      },
      {
        "id": 16154775,
        "name": "Guest Bedroom"
      },
      {
        "id": 16154766,
        "name": "Mark Bathroom"
      },
      {
        "id": 16154765,
        "name": "Cathy Bathroom"
      },
      {
        "id": 16154762,
        "name": "Master Bedroom"
      },
      {
        "id": 16154760,
        "name": "Great Room"
      },
      {
        "id": 16154756,
        "name": "Kitchen"
      }
    ]

And, BTW, I also saw this exception in the log shortly after binding startup.

2026-02-22 13:13:07.884 [DEBUG] [enhab.binding.roborock.internal.util.ProtocolUtils] - Exception decrypting payload for protocol 102: Failed to decrypt data using AES/ECB/PKCS5Padding.
org.openhab.binding.roborock.internal.RoborockException: Failed to decrypt data using AES/ECB/PKCS5Padding.
        at org.openhab.binding.roborock.internal.util.ProtocolUtils.decrypt(ProtocolUtils.java:69) ~[?:?]
        at org.openhab.binding.roborock.internal.util.ProtocolUtils.handleDataProtocol(ProtocolUtils.java:219) ~[?:?]
        at org.openhab.binding.roborock.internal.util.ProtocolUtils.handleMessage(ProtocolUtils.java:258) ~[?:?]
        at org.openhab.binding.roborock.internal.RoborockVacuumHandler.handleMessage(RoborockVacuumHandler.java:435) ~[?:?]
        at org.openhab.binding.roborock.internal.RoborockAccountHandler.messageArrived(RoborockAccountHandler.java:405) ~[?:?]
        at org.eclipse.paho.client.mqttv3.internal.CommsCallback.deliverMessage(CommsCallback.java:519) ~[?:?]
        at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:417) ~[?:?]
        at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:214) ~[?:?]
        at java.lang.Thread.run(Thread.java:1583) [?:?]
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
        at com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:861) ~[?:?]
        at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:941) ~[?:?]
        at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:734) ~[?:?]
        at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446) ~[?:?]
        at javax.crypto.Cipher.doFinal(Cipher.java:2244) ~[?:?]
        at org.openhab.binding.roborock.internal.util.ProtocolUtils.decrypt(ProtocolUtils.java:66) ~[?:?]
        ... 8 more

I’ll pull the latest snapshot and check.

Edit: The latest snapshot resolved both issues. Sorry to bother you. :roll_eyes:

I was sort of meddling with Roborock binding recently and I was wondering @Paul_Smedley if you had any luck with local protocol? I kind of got something working already and I was wondering if I should try continue working on it (its good enough in current state for me) to polish to OH standard or if I should keep it as it is, till you got time to solve it properly. I mainly wanted to see, if I could perhaps increase refresh rate of map without rate limits and it seems, it is sort of possible in local mode - mainly due to having to call only one MQTT endpoint instead of 8.

I haven’t really investigate local protocol yet - I know what to do, but Java is kinda hard for me, so working out how to abstract the local vs mqtt commands hasn’t hit my priority list as yet.