FIXED: Ecovacs Deebot 2019 & OZMO Series - Working Library

I changed vacuum name in app with a name ambrogio and rebuild all entities and sensor but the problem is the same

Logger: homeassistant.helpers.entity
Source: custom_components/deebot/vacuum.py:209
First occurred: 12:02:39 (1 occurrences)
Last logged: 12:02:39
Update for vacuum.ambrogio fails

Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.8/site-packages/homeassistant/helpers/entity.py", line 278, in async_update_ha_state
    await self.async_device_update()
  File "/srv/homeassistant/lib/python3.8/site-packages/homeassistant/helpers/entity.py", line 474, in async_device_update
    raise exc
  File "/home/homeassistant/.homeassistant/custom_components/deebot/vacuum.py", line 209, in async_update
    with open(self._live_map_path, "wb") as fh:
FileNotFoundError: [Errno 2] No such file or directory: 'www/ambrogio_liveMap.png'

If I check [sensor.ambrogio_last_clean_image], I see the image and link is ok but then not generate image on www folder

Do I understand that it has created a file at least once:

If I check [sensor.ambrogio_last_clean_image], I see the image and link is ok
So it made at least one copy of the last image?

Sorry, I think I am at the end of my usefulness. I assume you have a folder in your main HA install called www and the permissions are correct. Maybe share a screenshot of your folder structure with permissions, and also repost your latest configuration.

Did a couple updates on my setup. I added an icon for the battery status. I also removed the specific values for rooms and replaced them with the entity attributes. (I noticed that each time I tweaked my setup, the numbers for each room changed)
ha_deebot

For lovelace GUI:

cards:
  - buttons:
      locate: false
      pause: false
      return: false
      spot: false
      start: false
      stop: false
    entity: vacuum.roomba
    image: /local/deebot.jpg
    name: Roomba
    type: 'custom:xiaomi-vacuum-card'
    vendor: deebot
  - cards:
      - color: white
        entity: null
        icon: 'mdi:map-marker-radius'
        name: Find
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        tap_action:
          action: call-service
          service: vacuum.locate
          service_data:
            entity_id: vacuum.roomba
        type: 'custom:button-card'
      - color: white
        entity: null
        icon: 'mdi:play'
        name: Auto
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        tap_action:
          action: call-service
          service: vacuum.start
          service_data:
            entity_id: vacuum.roomba
        type: 'custom:button-card'
      - type: 'custom:config-template-card'
        entities:
          - input_boolean.deebot_dining_room
          - input_boolean.deebot_kitchen
          - input_boolean.deebot_living_room
          - input_boolean.deebot_bedroom
          - input_boolean.deebot_bathroom
          - input_boolean.deebot_closet
          - input_boolean.deebot_back_hall
          - input_boolean.deebot_entry
        card:
          type: 'custom:button-card'
          color: white
          entity: null
          icon: 'mdi:view-dashboard-outline'
          name: Rooms
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: script.vacuum_clean_zone
      - color: white
        entity: null
        icon: 'mdi:pause'
        name: Pause
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        tap_action:
          action: call-service
          service: vacuum.pause
          service_data:
            entity_id: vacuum.roomba
        type: 'custom:button-card'
      - color: white
        entity: null
        icon: 'mdi:robot-vacuum'
        name: Dock
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        tap_action:
          action: call-service
          service: vacuum.return_to_base
          service_data:
            entity_id: vacuum.roomba
        type: 'custom:button-card'
    type: horizontal-stack
  - cards:
      - color: yellow
        entity: input_boolean.deebot_kitchen
        icon: 'mdi:toaster-oven'
        name: Kitchen
        state:
          - color: 'rgb(100, 100, 100)'
            value: 'off'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
      - color: yellow
        entity: input_boolean.deebot_living_room
        icon: 'mdi:sofa'
        name: Family Room
        state:
          - color: 'rgb(100, 100, 100)'
            value: 'off'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
      - color: yellow
        entity: input_boolean.deebot_bedroom
        icon: 'mdi:bed-king'
        name: Bedroom
        state:
          - color: 'rgb(100, 100, 100)'
            value: 'off'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
      - color: yellow
        entity: input_boolean.deebot_bathroom
        icon: 'mdi:shower'
        name: Bathroom
        state:
          - color: 'rgb(100, 100, 100)'
            value: 'off'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
    type: horizontal-stack
  - cards:
      - color: yellow
        entity: input_boolean.deebot_closet
        icon: 'mdi:hanger'
        name: Closet
        state:
          - color: 'rgb(100, 100, 100)'
            value: 'off'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
      - color: yellow
        entity: input_boolean.deebot_back_hall
        icon: 'mdi:toilet'
        name: Guest Hallway
        state:
          - color: 'rgb(100, 100, 100)'
            value: 'off'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
      - color: yellow
        entity: input_boolean.deebot_entry
        icon: 'mdi:door-open'
        name: Foyer
        state:
          - color: 'rgb(100, 100, 100)'
            value: 'off'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
      - color: yellow
        entity: input_boolean.deebot_dining_room
        icon: 'mdi:silverware-variant'
        name: Dining Room
        state:
          - color: 'rgb(100, 100, 100)'
            value: 'off'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
    type: horizontal-stack
  - cards:
      - type: 'custom:config-template-card'
        entities:
          - sensor.deebot_fan_speed
        variables:
          - 'states[''sensor.deebot_fan_speed''].state'
        card:
          color: '${vars[0] === ''quiet'' ? ''yellow'' : ''white''}'
          entity: null
          icon: 'mdi:fan'
          name: Quiet
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: vacuum.set_fan_speed
            service_data:
              entity_id: vacuum.roomba
              fan_speed: quiet
          type: 'custom:button-card'
      - type: 'custom:config-template-card'
        entities:
          - sensor.deebot_fan_speed
        variables:
          - 'states[''sensor.deebot_fan_speed''].state'
        card:
          color: '${vars[0] === ''normal'' ? ''yellow'' : ''white''}'
          entity: null
          icon: 'mdi:fan'
          name: Normal
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: vacuum.set_fan_speed
            service_data:
              entity_id: vacuum.roomba
              fan_speed: normal
          type: 'custom:button-card'
      - type: 'custom:config-template-card'
        entities:
          - sensor.deebot_fan_speed
        variables:
          - 'states[''sensor.deebot_fan_speed''].state'
        card:
          color: '${vars[0] === ''max'' ? ''yellow'' : ''white''}'
          entity: null
          icon: 'mdi:fan'
          name: Max
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: vacuum.set_fan_speed
            service_data:
              entity_id: vacuum.roomba
              fan_speed: max
          type: 'custom:button-card'
      - type: 'custom:config-template-card'
        entities:
          - sensor.deebot_fan_speed
        variables:
          - 'states[''sensor.deebot_fan_speed''].state'
        card:
          color: '${vars[0] === ''max+'' ? ''yellow'' : ''white''}'
          entity: null
          icon: 'mdi:fan'
          name: Max+
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: vacuum.set_fan_speed
            service_data:
              entity_id: vacuum.roomba
              fan_speed: max+
          type: 'custom:button-card'
      - color: 'rgb(0, 255, 0)'
        entity: input_boolean.deebot_times
        icon: 'mdi:numeric-2'
        name: Clean Cycles
        state:
          - color: 'rgb(255, 0, 0)'
            value: 'off'
            icon: 'mdi:numeric-1'
        styles:
          card:
            - font-size: 12px
            - background-color: black
            - color: white
        type: 'custom:button-card'
    type: horizontal-stack
  - cards:
      - type: 'custom:config-template-card'
        entities:
          - sensor.roomba_water_level
        variables:
          - 'states[''sensor.roomba_water_level''].state'
        card:
          color: '${vars[0] === ''low'' ? ''yellow'' : ''white''}'
          entity: null
          icon: 'mdi:flask-empty-outline'
          name: Low
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: vacuum.send_command
            service_data:
              command: set_water
              entity_id: vacuum.roomba
              params:
                amount: low
          type: 'custom:button-card'
      - type: 'custom:config-template-card'
        entities:
          - sensor.roomba_water_level
        variables:
          - 'states[''sensor.roomba_water_level''].state'
        card:
          color: '${vars[0] === ''medium'' ? ''yellow'' : ''white''}'
          entity: null
          icon: 'mdi:flask-outline'
          name: Medium
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: vacuum.send_command
            service_data:
              command: set_water
              entity_id: vacuum.roomba
              params:
                amount: medium
          type: 'custom:button-card'
      - type: 'custom:config-template-card'
        entities:
          - sensor.roomba_water_level
        variables:
          - 'states[''sensor.roomba_water_level''].state'
        card:
          color: '${vars[0] === ''high'' ? ''yellow'' : ''white''}'
          entity: null
          icon: 'mdi:flask-empty'
          name: High
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: vacuum.send_command
            service_data:
              command: set_water
              entity_id: vacuum.roomba
              params:
                amount: high
          type: 'custom:button-card'
      - type: 'custom:config-template-card'
        entities:
          - sensor.roomba_water_level
        variables:
          - 'states[''sensor.roomba_water_level''].state'
        card:
          color: '${vars[0] === ''ultrahigh'' ? ''yellow'' : ''white''}'
          entity: null
          icon: 'mdi:flask-empty-plus'
          name: Ultrahigh
          styles:
            card:
              - font-size: 12px
              - background-color: black
              - color: white
          tap_action:
            action: call-service
            service: vacuum.send_command
            service_data:
              command: set_water
              entity_id: vacuum.roomba
              params:
                amount: ultrahigh
          type: 'custom:button-card'
      - type: 'custom:config-template-card'
        entities:
          - sensor.roomba_water_level
        variables:
          - states.vacuum.roomba.battery_icon
        card:
          color: white
          entity: null
          icon: '[[[return states[''vacuum.roomba'' ].attributes.battery_icon]]]'
          name: '[[[return states[''vacuum.roomba'' ].attributes.battery_level]]]'
          styles:
            card:
              - font-size: 12px
              - font-weight: bold
              - background-color: black
              - color: white
            icon:
              - color: |
                  [[[ 
                    if (states['vacuum.roomba' ].attributes.battery_level < 40) return 'red'; 
                    else if (states['vacuum.roomba' ].attributes.battery_level < 85) return 'yellow';
                    else return 'green';
                  ]]]
          type: 'custom:button-card'
    type: horizontal-stack
type: vertical-stack

In addition to using attributes for room numbers, I also added an ā€œerror echeckā€ so that if the script did not detect a room, just vacuum the balcony (my smallest zone).

updated clean_a_room script:

clean_a_room:
  alias: Clean a Room
  sequence:
  - service: input_text.set_value
    data_template:
      entity_id: input_text.valueroom
      value: '{{room}},'
  - service: vacuum.send_command
    data_template:
      command: spot_area
      entity_id: vacuum.roomba
      params:
        cleanings: "{% set y = room %} {% set y = y | lower %} {% if \"2\" in y or\
          \ \"twice\" in y %} {% set y = \"2\" %} {% else %} {% set y = \"1\" %} {%\
          \ endif %} {{y}}        \n"
        rooms: '{% set x = room %} {% set x = x | lower
        %} {% if "house" in x %} {% set x = (states[''vacuum.roomba'' ].attributes.room_living_room|string+","+states[''vacuum.roomba'' ].attributes.room_bedroom|string+","+ states[''vacuum.roomba'' ].attributes.room_bathroom|string+","+states[''vacuum.roomba'' ].attributes.room_storeroom|string+","+states[''vacuum.roomba'' ].attributes.room_dining_room|string+","+states[''vacuum.roomba'' ].attributes.room_kitchen|string+","+states[''vacuum.roomba'' ].attributes.room_corridor|string+","+states[''vacuum.roomba'' ].attributes.room_balcony|string+",") %} {% else %}
        {% set x = x | replace(",","") %} {% set x = x | replace("master ","") %}
        {% set x = x | replace("2","") %} {% set x = x | replace("bedroom",states[''vacuum.roomba'' ].attributes.room_bedroom|string+",")
        %} {% set x = x | replace("family room",states[''vacuum.roomba'' ].attributes.room_living_room|string+",") %} {% set x = x | replace("living
        room",states[''vacuum.roomba'' ].attributes.room_living_room|string+",") %} {% set x = x | replace("dining room",states[''vacuum.roomba'' ].attributes.room_dining_room|string+",") %} {% set x =
        x | replace("kitchen",states[''vacuum.roomba'' ].attributes.room_kitchen|string+",") %} {% set x = x | replace("guest bathroom",states[''vacuum.roomba'' ].attributes.room_corridor|string+",")
        %} {% set x = x | replace("guest bath",states[''vacuum.roomba'' ].attributes.room_corridor|string+",") %} {% set x = x | replace("bathroom",states[''vacuum.roomba'' ].attributes.room_bathroom|string+",")
        %} {% set x = x | replace("closet",states[''vacuum.roomba'' ].attributes.room_storeroom|string+",") %} {% set x = x | replace("back hall",states[''vacuum.roomba'' ].attributes.room_corridor|string+",")
        %} {% set x = x | replace("hallway",states[''vacuum.roomba'' ].attributes.room_corridor|string+",") %} {% set x = x | replace("entry",states[''vacuum.roomba'' ].attributes.room_balcony|string+",")
        %} {% set x = x | replace("foyer",states[''vacuum.roomba'' ].attributes.room_balcony|string+",") %} {% set x = x | replace(" times","") %} {% set x = x | replace("
        twice","") %} {% set x = x | replace(" and ","") %} {% set x = x | replace("the
        ","") %} {% set x = x | regex_replace("[^0-9,]","")
          %} {% endif %} {% if x=="" %} {% set x=states[''vacuum.roomba'' ].attributes.room_balcony|string+"," %} {% endif %} {{x}}'
  mode: single

and updated vacuum_clean_zone:

vacuum_clean_zone:
  alias: Clean Zone
  sequence:
  - service: vacuum.send_command
    data_template:
      command: spot_area
      entity_id: vacuum.roomba
      params:
        cleanings: '{%- if is_state(''input_boolean.deebot_times'', ''on'') -%}{{2|int}}{%-
          else -%}{{1|int}}{% endif %}

          '
        rooms: >
          {% set x='' %} {%- if is_state('input_boolean.deebot_living_room','on') -%} {% set x=x + states['vacuum.roomba' ].attributes.room_living_room|string+',' %} {%- endif -%} 
          {%- if is_state('input_boolean.deebot_bedroom', 'on') -%} {% set x=x + states['vacuum.roomba' ].attributes.room_bedroom|string+',' %} {%- endif -%} 
          {%- if is_state('input_boolean.deebot_bathroom', 'on') -%}{% set x=x + states['vacuum.roomba' ].attributes.room_bathroom|string+',' %} {%- endif -%}
          {%- if is_state('input_boolean.deebot_closet', 'on') -%} {% set x=x + states['vacuum.roomba' ].attributes.room_storeroom|string+',' %} {%- endif -%}             
          {%- if is_state('input_boolean.deebot_dining_room','on') -%} {% set x=x + states['vacuum.roomba' ].attributes.room_dining_room|string+',' %} {%- endif -%}
          {%- if is_state('input_boolean.deebot_back_hall', 'on') -%} {% set x=x + states['vacuum.roomba' ].attributes.room_corridor|string+',' %} {%- endif -%} 
          {%- if is_state('input_boolean.deebot_kitchen', 'on') -%} {% set x=x + states['vacuum.roomba' ].attributes.room_kitchen|string+',' %} {%- endif -%}
          {%- if is_state('input_boolean.deebot_entry', 'on') -%} {% set x=x + states['vacuum.roomba' ].attributes.room_balcony|string+',' %} {%- endif -%}  {{x}}
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.deebot_kitchen
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.deebot_bedroom
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.deebot_bathroom
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.deebot_living_room
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.deebot_dining_room
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.deebot_back_hall
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.deebot_entry
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.deebot_times
2 Likes

Just set up a OZMO T8+ working perfectly fine. Now will this become the default Home assistant integration at some point? The T8 also has astation that contains a dustbin and suck the Robot empty after every run. I can also trigger this via the app. Would it be possible to include this as a command?

@Tomibeck
Hello,
were you able to generate the map in the www folder?

Yes thatā€™s working. But I canā€™t seem to find the right card to display the last completed floor plan ( The one with the URL)

I use a custom card,custom:config-template-card , for mine. But the Picture card should work, too.

1 Like

I donā€™t think it is vacuum related. The error seems to imply configuration or setup error. Can you post your latest setup and the structure of your www folder?

deebot:
  username: **************
  password: ***************
  country: us
  continent: na
  deviceid:
    - E02*****************

  # Not sure this is working
  live_map: True                    # Enable Live Map.. may cause issues on low power hardware | Default: True
  show_color_rooms: False           # Enable draw room colors as in the app | Default: False
  livemappath: 'www/' 


I have exactly the same problem described. A house with 2 floors, but moving vacuum cleaner from one floor to the other doesnā€™t update the areas list.
I couldnā€™t find any post about this issue.
Does this custom component https://github.com/And3rsL/Deebot-for-hassio/issues support multiple floors?

Do any of you have a problem with T8 aivi auto merging/dividing rooms as it pleases, after iā€™ve labeled everything already? i keep having to change my script so it fits, am i doing something wrong ?

My bigger issue is that a ā€œNew Environment is detectedā€ and my map needs rebuilt. So I have at least modified my code, to not rely on the manually assigning the values. In stead I use the attribute of the vacuum to get the number dynamically.

This way after my map is re scanned and I assign rooms, the code will not need touched.

Hope that helps.

Could you explain how? im new to HA and have only used node.red to code my automations so far, only thing iā€™ve done in HA is a few scripts for the vacuum and a boolean.
attributes.room_bedroom, that means you have your bedroom labeled as bedroom right ? my bot also throws all labels away when it auto merge/divide

:EDIT:
shouldnt room number and attributes.room_bedroom give the same result ?

Quick question about the livemap. I have the LiveMap working, updating as the robot goes around. However, the camera card doesnā€™t update, says idle. I have a camera card set up with the camera entity, canā€™t seem to work out what I have done wrong. Image updates in the www folder fine. Must be the card. I have tried a few variants, centred around the card yaml provided by users on here.

type: picture-entity
entity: vacuum.deathstar
aspect_ratio: 100%
camera_image: camera.deebot_live_map

How did you set up the camera entity?

Thanks Tomibeck.

camera:
  - platform: generic
    name: Deebot_live_map
    still_image_url: "https://xxx/local/deathstar_liveMap.png"
    verify_ssl: false

The url works when testing and is updated every so often by the integration throughout a clean.

i only use http but not sure if this will make a difference.

I donā€™t think so - my proxy forces https anyway, and I found it didnā€™t seem to bring the image up with http. So yours updates every so often with the latest image? If I open the file on the host every 30 seconds or so it has updated but Home Assistant card remains the same image from when I added the image.

Iā€™m using this integration from my Ozmo T8 and is working fineā€¦
One strange thing is that main entity vacuum.oz (Oz is robot name) isnā€™t updating when robot starts to clean (scheduled job). Iā€™m getting docked even more then 30min is passed from starting. I have reinstall integration, restart HA but without any success. My HA is running on Rpi4 4GB RAM, Home Assistant Core 2021.1.0.
Other sensor entities are updating when job starts:

  • sensor.oz_stats_area

  • sensor.oz_stats_time

Also is it possible to get location of the robot in form of some type of coordinates?

A new release has come out that supports multi-floor. I am still very much a novice with HA, so still working on how to integrate this.

Still working out how to integrate this. My main issue is the room list hasnā€™t been updating when I move floors so unsure how I will solve this at the moment.

If you have HACS installed you only have to update ā€œDeebot for Hassioā€ component as soon as version 1.9.8 is available