rand256 / valetudo

Valetudo RE - experimental vacuum software, cloud free
Apache License 2.0
667 stars 73 forks source link

Feature Request: Port "no mop zones" from Hypfer/Valetudo #332

Closed theorician closed 3 years ago

theorician commented 3 years ago

Hi,

Hypfer/Valetudo recently introduced no-mop-zones as a further forbidden zone class. Can you port this commit? It'd be a really useful feature to have.

Thanks for a great fork!

rand256 commented 3 years ago

No mop zones are not supported under S5 series of roborock vacuums, this is the only reason they are not there in RE.

theorician commented 3 years ago

@rand256 Ahh, it's an S5 Max and up exclusive? That's too bad.

Is there a functional workaround we can use on an S5 using RE?

I saw that it's possible to save and restore forbidden zones. I'm a software engineer myself so I'm fine getting my hands dirty - is there an API in RE that I can call to query/create/delete forbidden zones either via MQTT or something RESTful? That way I could easily create a Home Assistant automation flow to programmatically generate the "no mop" zones when mopping and remove them when not mopping.

Thanks again for the work you're doing.

rand256 commented 3 years ago

Yes, this feature is currently only implemented in so-called Gen3 devices.

You can open forbidden markers configuration page in the Web UI and check which data is being PUT into /api/persistent_data when you save changes - this is the way to overwrite all the forbidden zones and virtual walls set in the device. Unfortunately there's no way to query currently active forbidden zones - that information is compressed into the mapdata and needs to be parsed separately, which is done in the UI but has no API available.

theorician commented 3 years ago

@rand256 Thanks for that. Sorry for not replying sooner - I only just got round to it now. Works a treat.

For posterity:

  1. When at the valetudo forbidden zone creator, open up the browser's Inspector tool and go to the Network tab.
  2. Set your forbidden zones up the way you want them and hit save
  3. Check your Network tab for a PUT request to /api/persistent_data. Copy the request body.

An empty request body (no forbidden zones or virtual walls) looks like this in cURL:

curl 'http://MY_VACUUM_URL/api/persistent_data' \
   -X PUT  -H 'Content-Type: application/json' \
   --data '{"virtual_walls":[],"forbidden_zones":[]}'

though it looks like mop mode was ported across, so it'll look a bit different with the next release. Not having tested it, I expect it'll look something like:

curl 'http://MY_VACUUM_URL/api/persistent_data' \
   -X PUT  -H 'Content-Type: application/json' \
   --data '{"virtual_walls":[],"forbidden_zones":[],"forbidden_mop_zones":[]}'

(note the extra parameter forbidden_mop_zones at the end.)

  1. Make copies of the request body for all the different zone configurations you want. Your PUT request will entirely overwrite all the existing virtual walls and mop zones.
  2. You can now script these cURL requests as you wish. I set up a REST command in Home Assistant which sets my forbidden zones the way I want them. My config below:
rest_command:
  vacuum_forbidden_zones:
    url: http://MY_VACUUM_URL/api/persistent_data
    method: PUT
    content_type: 'application/json'
    payload: '{"virtual_walls":[],"forbidden_zones":{{ forbidden_zones }}}'

script:
  vacuum_full_clean:
    alias: Full Clean
    sequence:
      - service: rest_command.vacuum_forbidden_zones
        data:
          forbidden_zones: '[]'
  vacuum_quick_clean:
    alias: Quick Clean
    sequence:
      - service: rest_command.vacuum_forbidden_zones
        data:
          forbidden_zones: '[[22744,20560,26751,20565,26764,21495,22726,21478],[23087,30237,26577,30248,26562,31905,23112,31930],[25025,28429,26700,28429,26710,29496,25025,29496],[17641,29452,19474,29440,19463,33140,17630,33140]]'
  vacuum_mop_mode:
    alias: Mop Mode
    sequence:
      - service: rest_command.vacuum_forbidden_zones
        data:
          forbidden_zones: '[[23779,20678,27306,20706,27279,25036,23779,25036],[23083,28639,26583,28639,26583,32139,23083,32139]]'

Obviously you'll need to replace the forbidden zone payload with your own. And as I said previously, you might need to add the empty forbidden_mop_zones parameter into the rest_command definition.

I hope that helps a few other people stuck on an S5 that want "no-mop zones."