Hypfer / Valetudo

Cloud replacement for vacuum robots enabling local-only operation
https://valetudo.cloud
Apache License 2.0
6.38k stars 388 forks source link

Zone Cleanups not working after upgrade to 2021.05.0 and error messages #952

Closed chofstede closed 3 years ago

chofstede commented 3 years ago

Describe the bug

Updated to Valetudo 2021.05.0 on a v1 mii robot. Now Zone-Cleanups does not work anymore. And I get constant errors in the log: [2021-05-27T09:09:48.867Z] [WARN] Failed to parse uploaded map [2021-05-27T09:09:50.857Z] [WARN] Failed to parse uploaded map [2021-05-27T09:10:46.599Z] [WARN] Failed to parse uploaded map ...

To Reproduce

Update from Valeduto 2021.03.0 to 2021.04.0 and then 2021.05.0. Try Zoned-Cleanups

Screenshots

valetudo1

Vacuum Model

Xiaomi V1

Valetudo Version

2021.05.0

Expected behavior

Zone Cleanups should work

chofstede commented 3 years ago

Did a factory-reset and reinstalled Valetudo 2021.05.0 cleanly. Still cannot use Zone Cleanups.

Seafo commented 3 years ago

I can confirm the issue.

charliesz commented 3 years ago

I'm on 2021.04 and have the same warning in the logs since last nightly reboot: Failed to parse uploaded map.

Kaan88 commented 3 years ago

Apparently this is going to be fixed in the new UI. They shouldn't have made a new release with this regression in my opinion.

Hypfer commented 3 years ago

They shouldn't have made a new release with this regression in my opinion.

https://github.com/Hypfer/Valetudo/blob/master/docs/index.md#expectation-management

Also, just overall a bad bug report since "Zone cleanups not working" certainly is not the case.

What isn't working is the Zoned cleanup of Zone Presets via the multiple-choice zone preset selection on the homepage. You can still draw zones onto the map or use MQTT or the REST API to call single presets.

Calling multiple presets at once has been removed since that didn't make sense conceptually. It's gone. Think of that UI button as commented-out/invisible.

In any case I'm left wondering why people expect me to care when they certainly can't be bothered to create concise bug reports. "Things don't work. I want thing to work." is something you can only get away with when interacting with commercial product support because they're literally paid to deal with that.

chofstede commented 3 years ago

Hello Hypfer,

It was not my intention to cause any inconvinience. I just notices that the button in the UI does not work anymore and wanted to report this. If my bug report was not living up to the standards, I apologize for that.

I didn't know, there are alternative ways to achieve a zone-cleanup. I will investigate into that.

Big big thanks for your absolutely great work. I really appreciate it.

best regards,

Chris

Hypfer commented 3 years ago

They shouldn't have made a new release with this regression in my opinion.

I'd like to explain this a bit more.

First of all, it wouldn't make sense to do any changes whatsover to the current UI to accomodate for changes in the backend API since the new UI is right around the corner actually existing and just waiting for testing and some mindless settings to be implemented.

Then of course it's a regression that only impacts not the whole feature but rather one convenient way to call the robot to clean a predefined zone and the whole fact that zones aren't that important for robots apart from the roborock v1 since segments pretty much solve not all but certainly 80% or more of the use-cases previously covered by zones.

Furthermore, considering that there were major issues in the MQTT feature which affected all models and not just the crappy v1 that no one in their right mind should buy since at least late 2019, there was definitely a need to get something out which solves attempts to solve these issues.

Anyways, there's no update reminder in Valetudo for a reason. I'm not forcing you to update if everything works just fine for your setup. My intention is of course to have stable releases because stuff breaking unexpectedly is annoying, however that's not a hard guarantee and more of a best-effort thing which might not always be the case.

This would be of course handled a bit differently if going back to 2021.04.0 for the time being was hard to do due to config file changes but since that's not the case with 2021.05.0, I'd argue that everyone who really needs this feature can just roll back and wait another month.

chofstede commented 3 years ago

Hello,

I found out a convenient way to start zone-cleanups in 2021.05.0 (I am stuck with a Xiaomi v1 and use those to avoid loosing the map on every cleanup).

Just publish a message to the MQTT topic "valetudo/robot/ZoneCleaningCapability/start/set" with a json payload that consists of an array of zone ids and the robot will happily start cleaning the zone :)

Example for MQTT-Explorer:

Topic: valetudo/robot/ZoneCleaningCapability/start/set
Payload (Type: json): ["eb191a38-2a14-4892-8873-0fc301d37073"]

Example for Home-Assistant Script:

cleanup:
  alias: Clean the living room
  sequence:
  - service: mqtt.publish
    data:
      topic: valetudo/robot/ZoneCleaningCapability/start/set
      payload: "[\"eb191a38-2a14-4892-8873-0fc301d37073\"]"
  mode: single

@Hypfer Thank you very much for you explanations and your great work. I will close this issue now.

best regards,

Christian

OzGav commented 3 years ago

For others searching for an answer to this problem. MQTT didn't work for me but since 2021.06.0 there are rest commands available. See here; https://github.com/Hypfer/Valetudo/discussions/968

I have got this working by adding to configuration.yaml

rest_command:
  vacuum_kitchen:
    url: 'http://192.168.1.195/api/v2/robot/capabilities/ZoneCleaningCapability/presets/fb3e756b-7f29-47c1-98fc-caa64a9bdb85'
    method: put
    headers:
      accept: "*/*"
    content_type: "application/json"
    payload: '{"action": "clean"}'

then you can call this in an automation or script or whatever. The preset ID fb3e756b-7f29-47c1-98fc-caa64a9bdb85 can be found in the Valetudo UI by going to edit the zone and then pressing the i in the circle in the bottom right.

forast3r commented 2 years ago

Hello,

I found out a convenient way to start zone-cleanups in 2021.05.0 (I am stuck with a Xiaomi v1 and use those to avoid loosing the map on every cleanup).

Just publish a message to the MQTT topic "valetudo/robot/ZoneCleaningCapability/start/set" with a json payload that consists of an array of zone ids and the robot will happily start cleaning the zone :)

Example for MQTT-Explorer:

Topic: valetudo/robot/ZoneCleaningCapability/start/set
Payload (Type: json): ["eb191a38-2a14-4892-8873-0fc301d37073"]

Example for Home-Assistant Script:

cleanup:
  alias: Clean the living room
  sequence:
  - service: mqtt.publish
    data:
      topic: valetudo/robot/ZoneCleaningCapability/start/set
      payload: "[\"eb191a38-2a14-4892-8873-0fc301d37073\"]"
  mode: single

@Hypfer Thank you very much for you explanations and your great work. I will close this issue now.

best regards,

Christian

Hi, just upgraded from old 2021.4 to 2021.12 and discovered that my old but still working v1 has lost the ability to clean multiple zones. Is this method still working? Did some quick'n dirty tests both from HA and from MQTT explorer but the robot does not recognize the zones: When I send this payload to prefix/robotname/ZoneCleaningCapability/start/set: [ "6dc0285c-373e-4392-8cd7-ee4894e79db4", "484e49ab-60c9-4b1e-a264-bb74af0e1ae9" ] I get: Error MQTT: Error while handling valetudo/r2d2/ZoneCleaningCapability/start/set { payload: '["6dc0285c-373e-4392-8cd7-ee4894e79db4","484e49ab-60c9-4b1e-a264-bb74af0e1ae9"]', error: Error: Error while starting zone cleanup. There is no zone preset with id ["6dc0285c-373e-4392-8cd7-ee4894e79db4","484e49ab-60c9-4b1e-a264-bb74af0e1ae9"] at PropertyMqttHandle.setter (/snapshot/Valetudo/backend/lib/mqtt/capabilities/ZoneCleaningCapabilityMqttHandle.js:52:31)

The only positive result has been sending a single zone id, without quotes nor brackets.

Could you confirm that this is the expected behaviour in this new versions?

BTW I had a simple setup with input_booleans in HA that let the family members select the rooms o vacuum. If multiple zones is missing I'll have to think of an alternative way of doing it.

Thanks in advance

forast3r commented 2 years ago

For others searching for an answer to this problem. MQTT didn't work for me but since 2021.06.0 there are rest commands available. See here; #968

I have got this working by adding to configuration.yaml

rest_command:
  vacuum_kitchen:
    url: 'http://192.168.1.195/api/v2/robot/capabilities/ZoneCleaningCapability/presets/fb3e756b-7f29-47c1-98fc-caa64a9bdb85'
    method: put
    headers:
      accept: "*/*"
    content_type: "application/json"
    payload: '{"action": "clean"}'

then you can call this in an automation or script or whatever. The preset ID fb3e756b-7f29-47c1-98fc-caa64a9bdb85 can be found in the Valetudo UI by going to edit the zone and then pressing the i in the circle in the bottom right.

Just an update, using the Rest API (thanks to the swagger interface it was easier to check) the PUT method on /api/v2/robot/capabilities/ZoneCleaningCapability accepts up to five zones, which can be extracted with the help of a template from the zone presets.

{
  "action": "clean",
  "zones": [
    {
      "iterations": 0,
      "points": {
        "pA": {
          "x": 0,
          "y": 0
        },
        "pB": {
          "x": 0,
          "y": 0
        },
        "pC": {
          "x": 0,
          "y": 0
        },
        "pD": {
          "x": 0,
          "y": 0
        }
      },
      "metaData": {}
    }
  ]
}
trancefam commented 2 years ago

@forast3r thank you for the tip. I had a similar problem but you pointed me in the right direction. I wanted the ability to set the number of iterations dynamically for a zone. With segments, this is easy to do via mqtt; however, specifying iterations with zones is not supported on the fly with mqtt (to my knowledge). If it helps anyone, here is my HA config. This does not require hard coding the zone points as it is retrieved from the existing zone_presets sensor:

rest_command:
  vacuum_area_dynamic:
    url: 'http://10.0.0.147/api/v2/robot/capabilities/ZoneCleaningCapability'
    method: put
    headers:
      accept: "*/*"
    content_type: "application/json"
    payload: >
      {
        "action": "clean",
        "zones": [
          {
            "iterations": {{states("input_number.vacuum_iterations") | int }},
            "points": {{ state_attr("sensor.valetudo_robot_zone_presets", inputZoneID)["zones"][0]["points"] | to_json }},
            "metaData": {}
          }
        ]
      }
script:
  vacuum_stove_area:
    alias: Vacuum Stove Area
    sequence:
    - service: rest_command.vacuum_area_dynamic
      data:
        inputZoneID: "1c75bf62-2be6-4ae2-8393-526aa95f0e76"

  vacuum_couch_area:
    alias: Vacuum Couch Area
    sequence:
    - service: rest_command.vacuum_area_dynamic
      data:
        inputZoneID: "ee9d0ee0-5b22-49e1-8455-8812487c88e4"

To use this, I created a input_number helper named vacuum_iterations

forast3r commented 2 years ago

@forast3r thank you for the tip. I had a similar problem but you pointed me in the right direction. I wanted the ability to set the number of iterations dynamically for a zone. With segments, this is easy to do via mqtt; however, specifying iterations with zones is not supported on the fly with mqtt (to my knowledge). If it helps anyone, here is my HA config. This does not require hard coding the zone points as it is retrieved from the existing zone_presets sensor:

rest_command:
  vacuum_area_dynamic:
    url: 'http://10.0.0.147/api/v2/robot/capabilities/ZoneCleaningCapability'
    method: put
    headers:
      accept: "*/*"
    content_type: "application/json"
    payload: >
      {
        "action": "clean",
        "zones": [
          {
            "iterations": {{states("input_number.vacuum_iterations") | int }},
            "points": {{ state_attr("sensor.valetudo_robot_zone_presets", inputZoneID)["zones"][0]["points"] | to_json }},
            "metaData": {}
          }
        ]
      }
script:
  vacuum_stove_area:
    alias: Vacuum Stove Area
    sequence:
    - service: rest_command.vacuum_area_dynamic
      data:
        inputZoneID: "1c75bf62-2be6-4ae2-8393-526aa95f0e76"

  vacuum_couch_area:
    alias: Vacuum Couch Area
    sequence:
    - service: rest_command.vacuum_area_dynamic
      data:
        inputZoneID: "ee9d0ee0-5b22-49e1-8455-8812487c88e4"

To use this, I created a input_number helper named vacuum_iterations

Thanks for pointing, I am trying to make a multiple zone - multi pass template in HA, but actually my jinja2 knowledge is limited. Until now I was just adding to the list of zones the selected ones, but I don't know how to set the iterations number to 2 if an input_boolean is on. The replace function seems to break the json (without replacing the template seems a dict)

{"action": "clean", "zones": 
                {%- set zonepresets = states.sensor.valetudo_vac_zone_presets.attributes -%}
                {%- set dades = namespace(zones=[]) -%}
                {%- for etiqueta,zona in zonepresets.items() -%}
                  {%- if zona.name -%}
                    {%- if states('input_boolean.vac_zona_' ~ zona.name) == 'on' -%}
                        {%- set dades.zones = dades.zones + zona.zones  -%}
                    {%- endif -%}
                  {%- endif -%}
                {%- endfor -%}
                {%- if states('input_boolean.vac_repeat') == 'on' -%}
                  {#%- how to replace "iterations": 1 with "iterations":2??? -%#}
                {%- endif -%}
                {{ dades.zones  }}}

This is the result with a single zone:

{
  "action": "clean",
  "zones": [
    {
      "__class": "ValetudoZone",
      "metaData": {},
      "points": {
        "pA": {
          "x": 2085,
          "y": 2045
        },
        "pB": {
          "x": 2210,
          "y": 2045
        },
        "pC": {
          "x": 2210,
          "y": 2300
        },
        "pD": {
          "x": 2085,
          "y": 2300
        }
      },
      "iterations": 1
    }
  ]
}

Any idea of how to solve it? Thanks in advance!