PiotrMachowski / lovelace-xiaomi-vacuum-map-card

This card provides a user-friendly way to fully control map-based vacuums in Home Assistant. Supported brands include Xiaomi (Roborock/Viomi/Dreame/Roidmi/Valetudo/Valetudo RE), Neato, Wyze, Roomba, Ecovacs (and probably more).
MIT License
1.48k stars 254 forks source link

Platform: custom Roborock integration (not via Miio) #518

Closed Xyaren closed 1 year ago

Xyaren commented 1 year ago

Integration repository

https://github.com/humbertogontijo/homeassistant-roborock

Supported features

Vacuum entity/entities

vaccuum.name:
  fan_speed_list:
    - Silent
    - Balanced
    - Turbo
    - Max
  battery_level: 100
  battery_icon: mdi:battery
  fan_speed: Turbo
  icon: mdi:robot-vacuum
  friendly_name: Fussel
  supported_features: 16383
camera.name:
  access_token: dfe6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  entity_picture: >-
    /api/camera_proxy/camera.fussel?token=dfe6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  icon: mdi:map-outline
  friendly_name: Fussel
  supported_features: 1
  calibration_points:
    - vacuum:
        x: 25500
        'y': 25500
      map:
        x: 191
        'y': 144
    - vacuum:
        x: 26500
        'y': 25500
      map:
        x: 211
        'y': 144
    - vacuum:
        x: 25500
        'y': 26500
      map:
        x: 191
        'y': 124
  charger:
    x: 26026
    'y': 25743
    a: -179
  image:
    size: 202960
    offset_y: 225
    offset_x: 319
    height: 430
    scale: 1
    rotation: 0
    width: 472
  is_empty: false
  no_go_areas: []
  no_mopping_areas:
    - x0: 21307
      y0: 22010
      x1: 22401
      y1: 22010
      x2: 22401
      y2: 20375
      x3: 21307
      y3: 20375
    - x0: 21396
      y0: 18858
      x1: 22385
      y1: 18858
      x2: 22385
      y2: 17184
      x3: 21396
      y3: 17184
  path:
    point_length: 0
    point_size: 4
    angle: 0
    path:
      - []
  room_numbers:
    '16': null
    '17': null
    '18': null
    '19': null
  rooms:
    '16':
      x0: 24150
      y0: 16650
      x1: 26050
      y1: 20400
    '17':
      x0: 20900
      y0: 16650
      x1: 24100
      y1: 22050
    '18':
      x0: 24050
      y0: 20450
      x1: 26050
      y1: 23950
    '19':
      x0: 20950
      y0: 22250
      x1: 26050
      y1: 26800
  vacuum_position:
    x: 25847
    'y': 25738
    a: 1
  vacuum_room: 19
  walls:
    - x0: 25222
      y0: 23066
      x1: 25223
      y1: 20478

Service calls

Resetting consumables

service: vacuum.send_command
data:
  command: reset_consumable
  params: sensor_dirty_time
target:
  entity_id: vacuum.fussel

Goto

service: vacuum.send_command
data:
  command: app_goto_target
  params:
    - 23141
    - 24926
target:
  entity_id: vacuum.fussel

Clean Room

service: vacuum.send_command
data:
  command: app_segment_clean
  params:
    - 19
target:
  entity_id: vacuum.fussel

Spot Clean

service: vacuum.clean_spot
data: {}
target:
  entity_id: vacuum.fussel

Locate (Robot announces "I am here" via Speakers)

service: vacuum.locate
data: {}
target:
  entity_id: vacuum.fussel

Stop

service: vacuum.stop
data: {}
target:
  entity_id: vacuum.fussel

There is also

RTB

service: vacuum.return_to_base
data: {}
target:
  entity_id: vacuum.fussel

Untested:

service: vacuum.set_fan_speed
data:
  fan_speed: unknown
target:
  entity_id: vacuum.fussel

Other info

The integration is in a very early stage but being worked on. Attributes on vaccuum are currently still missing. https://github.com/humbertogontijo/homeassistant-roborock/issues/16

All in all very similar to xiaomiMiio.

Rooms use numerical Ids instead of strings!

Xyaren commented 1 year ago

Further information in this discussion: https://github.com/humbertogontijo/homeassistant-roborock/discussions/40

PiotrMachowski commented 1 year ago

@Xyaren @Matte8519 Could you provide me some info about entities created by Roborock integration?

  1. Open your main dashboard
  2. Open browser's dev tools (with F12 button)
  3. Open console
  4. Paste following code in the console:
    getDeviceData = async (entity) => {
        const hass = document.querySelector("home-assistant").hass;
        const vacuumDeviceId = (
            await hass.callWS({
                type: "config/entity_registry/get",
                entity_id: entity,
            })
        )["device_id"];
        const vacuumSensors = (
            await hass.callWS({
                type: "config/entity_registry/list",
            })
        ).filter(e => e.device_id === vacuumDeviceId);
        Promise.all(
            vacuumSensors.map(vs =>
                hass.callWS({
                    type: "config/entity_registry/get",
                    entity_id: vs.entity_id,
                }),
            ),
        ).then(v => console.log(v));
    }
  5. Retrieve entities related to the vacuum entity using following command:
    getDeviceData("vacuum.your_vacuum");
  6. Two entries should be printed, please copy content of the second one (click with right mouse button on it and choose "Copy object" option)
  7. Send me copied values to piotr.machowski.dev [at] gmail.com
Xyaren commented 1 year ago

Just sent you the email 👍

This is my current card config which is using a custom sensor:

Code - WARNING: Long ## Sensor ```yml template: - sensor: - name: "Fussel loaded map" state: > {% set t = (state_attr('camera.fussel_map','room_numbers') or {}).keys() %} {% if 20 in t %}ground_floor {% elif 17 in t %}first_floor {% elif 16 in t %}attic {% else %}unknown{{t}} {% endif %} # trigger: # - platform: state # entity_id: camera.fussel_map # attribute: room_numbers ``` ## Card ```yml type: custom:xiaomi-vacuum-map-card map_locked: true map_source: camera: camera.fussel_map crop: top: 230 left: 80 right: 400 bottom: 210 calibration_source: camera: true entity: vacuum.fussel vacuum_platform: send_command preset_name: OG conditions: - entity: sensor.fussel_loaded_map value: first_floor map_modes: - name: Pin & Go icon: mdi:map-marker-plus run_immediately: true coordinates_rounding: true selection_type: MANUAL_POINT max_selections: 1 repeats_type: NONE max_repeats: 1 service_call_schema: service: roborock.vacuum_goto service_data: x_coord: '[[point_x]]' y_coord: '[[point_y]]' target: entity_id: '[[entity_id]]' - name: Zone reinigen icon: mdi:select-drag run_immediately: false coordinates_rounding: true selection_type: MANUAL_RECTANGLE max_selections: 5 repeats_type: EXTERNAL max_repeats: 3 service_call_schema: service: roborock.vacuum_clean_zone service_data: zone: '[[selection]]' repeats: '[[repeats]]' target: entity_id: '[[entity_id]]' - name: Räume icon: mdi:floor-plan run_immediately: false coordinates_rounding: true selection_type: ROOM max_selections: 10 repeats_type: REPEAT max_repeats: 3 service_call_schema: service: roborock.vacuum_clean_segment service_data: segments: '[[selection]]' target: entity_id: '[[entity_id]]' predefined_selections: - id: 16 icon: name: mdi:broom x: 25100 'y': 18525 label: text: Bad x: 25100 'y': 18525 offset_y: 35 outline: - - 24150 - 16650 - - 26050 - 16650 - - 26050 - 20400 - - 24150 - 20400 - id: 17 icon: name: mdi:broom x: 22500 'y': 19350 label: text: Arbeitszimmer x: 22500 'y': 19350 offset_y: 35 outline: - - 20900 - 16650 - - 24100 - 16650 - - 24100 - 22050 - - 20900 - 22050 - id: 18 icon: name: mdi:broom x: 25050 'y': 22200 label: text: Flur x: 25050 'y': 22200 offset_y: 35 outline: - - 24050 - 20450 - - 26050 - 20450 - - 26050 - 23950 - - 24050 - 23950 - id: 19 icon: name: mdi:broom x: 23500 'y': 24525 label: text: Schlafzimmer x: 23500 'y': 24525 offset_y: 35 outline: - - 20950 - 22250 - - 26050 - 22250 - - 26050 - 26800 - - 20950 - 26800 variables: {} title: Roboter tiles: - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery-charging unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value: charging - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery-charging-100 unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value: charging_completed - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value_not: charging - entity: vacuum.fussel attribute: vacuum_status value_not: charging_completed - tile_id: error entity: vacuum.fussel label: Error attribute: error icon: mdi:robot-vacuum-alert conditions: - entity: vacuum.fussel attribute: error value_not: '' - tile_id: status entity: vacuum.fussel label: Status attribute: state icon: mdi:robot-vacuum unit: '' translations: docked: Angedockt cleaning: Reinigung paused: Pausiert idle: Untätig - tile_id: fan_speed entity: vacuum.fussel label: Lüftergeschwindigkeit attribute: fan_speed icon: mdi:fan translations: silent: Leise standard: Standard medium: Medium turbo: Turbo auto: Auto gentle: Sanft - tile_id: dnd entity: vacuum.fussel label: Do Not Disturb attribute: dnd_enabled icon: mdi:bell-sleep unit: '' translations: '0': Deaktiviert '1': Aktiviert - tile_id: sensor_dirty_left label: Sensors left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: sensor_dirty_time entity_id: vacuum.fussel entity: sensor.fussel_sensor_dirty_left icon: mdi:eye-outline precision: 0 translations: {} - tile_id: filter_left label: Filter left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: filter_work_time entity_id: vacuum.fussel entity: sensor.fussel_filter_left icon: mdi:air-filter precision: 0 translations: {} - tile_id: main_brush_left label: Main brush left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: main_brush_work_time entity_id: vacuum.fussel entity: sensor.fussel_main_brush_left icon: mdi:brush precision: 0 translations: {} - tile_id: side_brush_left label: Side brush left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: side_brush_work_time entity_id: vacuum.fussel entity: sensor.fussel_side_brush_left icon: mdi:brush-outline precision: 0 translations: {} - tile_id: cleaning_count label: Cleaning count entity: sensor.fussel_total_clean_count icon: mdi:counter precision: 0 translations: {} - tile_id: loaded_map label: Geladene Karte entity: sensor.fussel_loaded_map icon: mdi:floor-plan translations: attic: Dachboden ground_floor: Erdgeschoss first_floor: Obergeschoss - tile_id: cleaning_duration_current label: Aktuelle Reinigungsdauer entity: sensor.fussel_current_clean_duration icon: mdi:timer-sand unit: min multiplier: 0.016667 precision: 2 - tile_id: cleaning_area_current label: Aktuelle Reinigungsfläche entity: sensor.fussel_current_clean_area icon: mdi:texture-box unit: m² precision: 2 - tile_id: cleaning_duration_last label: Letze Reinigungsdauer entity: sensor.fussel_last_clean_duration icon: mdi:timer-sand-full unit: min multiplier: 0.016667 precision: 2 - tile_id: cleaning_area_last label: Letzte Reinigungsfläche entity: sensor.fussel_last_clean_area icon: mdi:texture-box unit: m² precision: 2 icons: - icon: mdi:play conditions: - entity: vacuum.fussel value_not: cleaning - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: returning tooltip: Start tap_action: action: call-service service: vacuum.start service_data: entity_id: vacuum.fussel - icon: mdi:pause conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: idle - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: paused tooltip: Pause tap_action: action: call-service service: vacuum.pause service_data: entity_id: vacuum.fussel - icon: mdi:stop conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: idle - entity: vacuum.fussel value_not: error tooltip: Stop tap_action: action: call-service service: vacuum.stop service_data: entity_id: vacuum.fussel - icon: mdi:home-map-marker conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: returning tooltip: Return to base tap_action: action: call-service service: vacuum.return_to_base service_data: entity_id: vacuum.fussel - icon: mdi:target-variant conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: cleaning - entity: vacuum.fussel value_not: returning tooltip: Clean spot tap_action: action: call-service service: vacuum.clean_spot service_data: entity_id: vacuum.fussel - icon: mdi:map-marker tooltip: Locate tap_action: action: call-service service: vacuum.locate service_data: entity_id: vacuum.fussel - icon: mdi:home-floor-g tooltip: Erdgeschoss tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 1 - icon: mdi:home-floor-1 tooltip: 1. Obergeschoss tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 0 - icon: mdi:home-floor-2 tooltip: Dachboden tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 2 two_finger_pan: true additional_presets: - preset_name: Erdgeschoss entity: vacuum.fussel map_locked: true map_source: camera: camera.fussel_map crop: top: 130 left: 150 right: 100 bottom: 250 calibration_source: camera: true conditions: - entity: sensor.fussel_loaded_map value: ground_floor map_modes: - name: Pin & Go icon: mdi:map-marker-plus run_immediately: true coordinates_rounding: true selection_type: MANUAL_POINT max_selections: 1 repeats_type: NONE max_repeats: 1 service_call_schema: service: roborock.vacuum_goto service_data: x_coord: '[[point_x]]' y_coord: '[[point_y]]' target: entity_id: '[[entity_id]]' - name: Zone reinigen icon: mdi:select-drag run_immediately: false coordinates_rounding: true selection_type: MANUAL_RECTANGLE max_selections: 5 repeats_type: EXTERNAL max_repeats: 3 service_call_schema: service: roborock.vacuum_clean_zone service_data: zone: '[[selection]]' repeats: '[[repeats]]' target: entity_id: '[[entity_id]]' - name: Räume icon: mdi:floor-plan run_immediately: false coordinates_rounding: true selection_type: ROOM max_selections: 10 repeats_type: REPEAT max_repeats: 3 service_call_schema: service: roborock.vacuum_clean_segment service_data: segments: '[[selection]]' target: entity_id: '[[entity_id]]' predefined_selections: - id: '16' icon: name: mdi:stove x: 32425 'y': 23525 label: text: Küche x: 32425 'y': 23525 offset_y: 35 outline: - - 30450 - 22550 - - 34400 - 22550 - - 34400 - 24500 - - 30450 - 24500 - id: '17' icon: name: mdi:cupboard-outline x: 31375 'y': 25250 label: text: Room 17 x: 31375 'y': 25250 offset_y: 35 outline: - - 30700 - 24500 - - 32050 - 24500 - - 32050 - 26000 - - 30700 - 26000 - id: '18' icon: name: mdi:toilet x: 33400 'y': 25450 label: text: Gäste WC x: 33400 'y': 25450 offset_y: 35 outline: - - 32400 - 24600 - - 34400 - 24600 - - 34400 - 26300 - - 32400 - 26300 - id: '19' icon: name: mdi:hanger x: 33375 'y': 27025 label: text: Flur x: 33375 'y': 27025 offset_y: 35 outline: - - 32200 - 26300 - - 34550 - 26300 - - 34550 - 27750 - - 32200 - 27750 - id: '20' icon: name: mdi:sofa x: 27375 'y': 25125 label: text: Wohnzimmer x: 27375 'y': 25125 offset_y: 35 outline: - - 22550 - 22550 - - 32200 - 22550 - - 32200 - 27700 - - 22550 - 27700 icons: - icon: mdi:play conditions: - entity: vacuum.fussel value_not: cleaning - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: returning tooltip: Start tap_action: action: call-service service: vacuum.start service_data: entity_id: vacuum.fussel - icon: mdi:pause conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: idle - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: paused tooltip: Pause tap_action: action: call-service service: vacuum.pause service_data: entity_id: vacuum.fussel - icon: mdi:stop conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: idle - entity: vacuum.fussel value_not: error tooltip: Stop tap_action: action: call-service service: vacuum.stop service_data: entity_id: vacuum.fussel - icon: mdi:home-map-marker conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: returning tooltip: Return to base tap_action: action: call-service service: vacuum.return_to_base service_data: entity_id: vacuum.fussel - icon: mdi:target-variant conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: cleaning - entity: vacuum.fussel value_not: returning tooltip: Clean spot tap_action: action: call-service service: vacuum.clean_spot service_data: entity_id: vacuum.fussel - icon: mdi:map-marker tooltip: Locate tap_action: action: call-service service: vacuum.locate service_data: entity_id: vacuum.fussel - icon: mdi:home-floor-g tooltip: Erdgeschoss tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 1 - icon: mdi:home-floor-1 tooltip: 1. Obergeschoss tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 0 - icon: mdi:home-floor-2 tooltip: Dachboden tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 2 tiles: - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery-charging unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value: charging - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery-charging-100 unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value: charging_completed - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value_not: charging - entity: vacuum.fussel attribute: vacuum_status value_not: charging_completed - tile_id: error entity: vacuum.fussel label: Error attribute: error icon: mdi:robot-vacuum-alert conditions: - entity: vacuum.fussel attribute: error value_not: '' - tile_id: status entity: vacuum.fussel label: Status attribute: state icon: mdi:robot-vacuum unit: '' translations: docked: Angedockt cleaning: Reinigung paused: Pausiert idle: Untätig - tile_id: fan_speed entity: vacuum.fussel label: Lüftergeschwindigkeit attribute: fan_speed icon: mdi:fan translations: silent: Leise standard: Standard medium: Medium turbo: Turbo auto: Auto gentle: Sanft - tile_id: dnd entity: vacuum.fussel label: Do Not Disturb attribute: dnd_enabled icon: mdi:bell-sleep unit: '' translations: '0': Deaktiviert '1': Aktiviert - tile_id: sensor_dirty_left label: Sensors left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: sensor_dirty_time entity_id: vacuum.fussel entity: sensor.fussel_sensor_dirty_left icon: mdi:eye-outline precision: 0 translations: {} - tile_id: filter_left label: Filter left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: filter_work_time entity_id: vacuum.fussel entity: sensor.fussel_filter_left icon: mdi:air-filter precision: 0 translations: {} - tile_id: main_brush_left label: Main brush left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: main_brush_work_time entity_id: vacuum.fussel entity: sensor.fussel_main_brush_left icon: mdi:brush precision: 0 translations: {} - tile_id: side_brush_left label: Side brush left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: side_brush_work_time entity_id: vacuum.fussel entity: sensor.fussel_side_brush_left icon: mdi:brush-outline precision: 0 translations: {} - tile_id: cleaning_count label: Cleaning count entity: sensor.fussel_total_clean_count icon: mdi:counter precision: 0 translations: {} - tile_id: loaded_map label: Geladene Karte entity: sensor.fussel_loaded_map icon: mdi:floor-plan translations: attic: Dachboden ground_floor: Erdgeschoss first_floor: Obergeschoss - tile_id: cleaning_duration_current label: Aktuelle Reinigungsdauer entity: sensor.fussel_current_clean_duration icon: mdi:timer-sand unit: min multiplier: 0.016667 precision: 2 - tile_id: cleaning_area_current label: Aktuelle Reinigungsfläche entity: sensor.fussel_current_clean_area icon: mdi:texture-box unit: m² precision: 2 - tile_id: cleaning_duration_last label: Letze Reinigungsdauer entity: sensor.fussel_last_clean_duration icon: mdi:timer-sand-full unit: min multiplier: 0.016667 precision: 2 - tile_id: cleaning_area_last label: Letzte Reinigungsfläche entity: sensor.fussel_last_clean_area icon: mdi:texture-box unit: m² precision: 2 - preset_name: Dachboden entity: vacuum.fussel map_locked: true map_source: camera: camera.fussel_map crop: top: 230 left: 170 right: 180 bottom: 100 calibration_source: camera: true conditions: - entity: sensor.fussel_loaded_map value: attic icons: - icon: mdi:play conditions: - entity: vacuum.fussel value_not: cleaning - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: returning tooltip: Start tap_action: action: call-service service: vacuum.start service_data: entity_id: vacuum.fussel - icon: mdi:pause conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: idle - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: paused tooltip: Pause tap_action: action: call-service service: vacuum.pause service_data: entity_id: vacuum.fussel - icon: mdi:stop conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: idle - entity: vacuum.fussel value_not: error tooltip: Stop tap_action: action: call-service service: vacuum.stop service_data: entity_id: vacuum.fussel - icon: mdi:home-map-marker conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: returning tooltip: Return to base tap_action: action: call-service service: vacuum.return_to_base service_data: entity_id: vacuum.fussel - icon: mdi:target-variant conditions: - entity: vacuum.fussel value_not: docked - entity: vacuum.fussel value_not: error - entity: vacuum.fussel value_not: cleaning - entity: vacuum.fussel value_not: returning tooltip: Clean spot tap_action: action: call-service service: vacuum.clean_spot service_data: entity_id: vacuum.fussel - icon: mdi:map-marker tooltip: Locate tap_action: action: call-service service: vacuum.locate service_data: entity_id: vacuum.fussel - icon: mdi:home-floor-g tooltip: Erdgeschoss tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 1 - icon: mdi:home-floor-1 tooltip: 1. Obergeschoss tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 0 - icon: mdi:home-floor-2 tooltip: Dachboden tap_action: action: call-service service: roborock.camera_load_multi_map service_data: entity_id: camera.fussel_map map_flag: 2 tiles: - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery-charging unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value: charging - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery-charging-100 unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value: charging_completed - tile_id: battery_level entity: vacuum.fussel label: Battery attribute: battery_level icon: mdi:battery unit: '%' conditions: - entity: vacuum.fussel attribute: vacuum_status value_not: charging - entity: vacuum.fussel attribute: vacuum_status value_not: charging_completed - tile_id: error entity: vacuum.fussel label: Error attribute: error icon: mdi:robot-vacuum-alert conditions: - entity: vacuum.fussel attribute: error value_not: '' - tile_id: status entity: vacuum.fussel label: Status attribute: state icon: mdi:robot-vacuum unit: '' translations: docked: Angedockt cleaning: Reinigung paused: Pausiert idle: Untätig - tile_id: fan_speed entity: vacuum.fussel label: Lüftergeschwindigkeit attribute: fan_speed icon: mdi:fan translations: silent: Leise standard: Standard medium: Medium turbo: Turbo auto: Auto gentle: Sanft - tile_id: dnd entity: vacuum.fussel label: Do Not Disturb attribute: dnd_enabled icon: mdi:bell-sleep unit: '' translations: '0': Deaktiviert '1': Aktiviert - tile_id: sensor_dirty_left label: Sensors left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: sensor_dirty_time entity_id: vacuum.fussel entity: sensor.fussel_sensor_dirty_left icon: mdi:eye-outline precision: 0 translations: {} - tile_id: filter_left label: Filter left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: filter_work_time entity_id: vacuum.fussel entity: sensor.fussel_filter_left icon: mdi:air-filter precision: 0 translations: {} - tile_id: main_brush_left label: Main brush left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: main_brush_work_time entity_id: vacuum.fussel entity: sensor.fussel_main_brush_left icon: mdi:brush precision: 0 translations: {} - tile_id: side_brush_left label: Side brush left unit: h multiplier: 0.0002777777777777778 hold_action: action: call-service service: vacuum.send_command confirmation: true service_data: command: reset_consumable params: side_brush_work_time entity_id: vacuum.fussel entity: sensor.fussel_side_brush_left icon: mdi:brush-outline precision: 0 translations: {} - tile_id: cleaning_count label: Cleaning count entity: sensor.fussel_total_clean_count icon: mdi:counter precision: 0 translations: {} - tile_id: loaded_map label: Geladene Karte entity: sensor.fussel_loaded_map icon: mdi:floor-plan translations: attic: Dachboden ground_floor: Erdgeschoss first_floor: Obergeschoss - tile_id: cleaning_duration_current label: Aktuelle Reinigungsdauer entity: sensor.fussel_current_clean_duration icon: mdi:timer-sand unit: min multiplier: 0.016667 precision: 2 - tile_id: cleaning_area_current label: Aktuelle Reinigungsfläche entity: sensor.fussel_current_clean_area icon: mdi:texture-box unit: m² precision: 2 - tile_id: cleaning_duration_last label: Letze Reinigungsdauer entity: sensor.fussel_last_clean_duration icon: mdi:timer-sand-full unit: min multiplier: 0.016667 precision: 2 - tile_id: cleaning_area_last label: Letzte Reinigungsfläche entity: sensor.fussel_last_clean_area icon: mdi:texture-box unit: m² precision: 2 map_modes: - name: Pin & Go icon: mdi:map-marker-plus run_immediately: true coordinates_rounding: true selection_type: MANUAL_POINT max_selections: 1 repeats_type: NONE max_repeats: 1 service_call_schema: service: roborock.vacuum_goto service_data: x_coord: '[[point_x]]' y_coord: '[[point_y]]' target: entity_id: '[[entity_id]]' - name: Zone reinigen icon: mdi:select-drag run_immediately: false coordinates_rounding: true selection_type: MANUAL_RECTANGLE max_selections: 5 repeats_type: EXTERNAL max_repeats: 3 service_call_schema: service: roborock.vacuum_clean_zone service_data: zone: '[[selection]]' repeats: '[[repeats]]' target: entity_id: '[[entity_id]]' ```

home xyaren de_personal-dashboard_robot

PiotrMachowski commented 1 year ago

@Xyaren great, thank you!

PiotrMachowski commented 1 year ago

Can you check out this version?

v2.1.3-beta.1

Xyaren commented 1 year ago

image

GoTo works. Zone Cleaning works (Including multiplier). Room Config generation works, cleaning is started.

The default looks better than the actual homeassistant-roborock template due to the stats missing?

PiotrMachowski commented 1 year ago

~That's weird, it should generate more tiles than default (Miio) platform... Are there any errors in browser's console? Can you show card's config?~

EDIT: I have fixed it in v2.1.3-beta.3

Xyaren commented 1 year ago

image

PiotrMachowski commented 1 year ago

It looks good 👍 I have not added all tiles that you have configured manually because it seems to be a bit too much. Buuuuut I might add them and create an instruction that will explain how to disable a specific tile instead

Xyaren commented 1 year ago

I think the "Status" is quite useful to have the other ones are probably not that useful.

PiotrMachowski commented 1 year ago

Status tile should work, can you show attributes of your vacuum entity? It should contain status attribute

Xyaren commented 1 year ago
fan_speed_list:
  - 'off'
  - silent
  - balanced
  - turbo
  - max
  - max_plus
  - custom
mop_mode_list:
  - standard
  - deep
  - deep_plus
  - custom
mop_intensity_list:
  - 'off'
  - mild
  - moderate
  - intense
  - custom
msg_ver: 2
msg_seq: 1937
state: docked
battery: 100
clean_time: 50
clean_area: 382500
error_code: 0
map_present: 1
in_cleaning: 0
in_returning: 0
in_fresh_state: 1
lab_status: 3
water_box_status: 0
fan_power: 102
dnd_enabled: 0
map_status: 3
is_locating: 0
lock_status: 0
water_box_mode: 202
water_box_carriage_status: 0
mop_forbidden_enable: 0
adbumper_status:
  - 0
  - 0
  - 0
water_shortage_status: 0
dock_type: 0
dust_collection_status: 0
auto_dust_collection: 1
mop_mode: standard
debug_mode: 0
dock_error_status: 0
unsave_map_reason: 4
unsave_map_flag: 0
battery_level: 100
battery_icon: mdi:battery-charging-100
fan_speed: balanced
vacuum_status: charging
mop_intensity: moderate
error: Keine
icon: mdi:robot-vacuum
friendly_name: Fussel
supported_features: 16383
PiotrMachowski commented 1 year ago

Ok, "Status" tile is missing because Roborock integration declares that is supports VacuumEntityFeature.STATUS, but its attributes doesn't contain it. I suspect this is caused by defining state_attributes instead of extra_state_attributes (here). Could you try to adjust this misalignment (probably just in your own instance at first) and check if the appropriate attribute and its tile will appear?

Xyaren commented 1 year ago

I'm not the developer, maybe @humbertogontijo can help ?

PiotrMachowski commented 1 year ago

You can just modify it in your HA in vacuum.py file to confirm it:

```diff status = self._device_status.state return STATE_CODES_TO_STATUS.get(status) @property - def state_attributes(self) -> dict[str, Any]: """Return the state attributes of the vacuum cleaner.""" if not self._device_status: return {} data = dict(self._device_status) ``` ```diff status = self._device_status.state return STATE_CODES_TO_STATUS.get(status) @property + def extra_state_attributes(self) -> dict[str, Any]: """Return the state attributes of the vacuum cleaner.""" if not self._device_status: return {} data = dict(self._device_status) ```

After modification you have to restart HA and check attributes of the vacuum entity for changes.

humbertogontijo commented 1 year ago

@PiotrMachowski thank you for the tip @Xyaren You should see the status tile automatically now using version 0.1.2 of the Roborock integration

PiotrMachowski commented 1 year ago

@humbertogontijo great, thanks for a quick fix!

Xyaren commented 1 year ago

Nice! Working :)

Misiu commented 1 year ago

Hopefully, Roborock will be soon a core integration: https://github.com/home-assistant/core/pull/89456 🤞

PiotrMachowski commented 1 year ago

@Misiu Looks good 👍 unfortunately I don't think it will have map support soon

Misiu commented 1 year ago

@PiotrMachowski I've just tried https://github.com/humbertogontijo/homeassistant-roborock with Your card (v2.2.0-beta.1) and the map got extracted (not sure if we are talking about the same feature 🙂) image Sadly the maps look the same as in the Roborock app, which is terrible (it's not because of your card btw), so now I need to read a bit more about the possibility to replace that terrible image with a custom-made image (without those rays going out thru windows) and use that image as a background (is this even supported?)

BTW I noticed that card is making a lot of requests to http://homeassistant.local:8123/api/camera_proxy/camera.stefan_map?token=XXX is this a bug or maybe we can disable this (I get the same image all the time)? I can create a separate issue with more details on this.

PiotrMachowski commented 1 year ago

I've just tried https://github.com/humbertogontijo/homeassistant-roborock with Your card (v2.2.0-beta.1) and the map got extracted (not sure if we are talking about the same feature 🙂)

The version in PR doesn't contain map camera.

Sadly the maps look the same as in the Roborock app, which is terrible (it's not because of your card btw)

Well, map rendering is also handled by my code - taken from Map Extractor

BTW I noticed that card is making a lot of requests to http://homeassistant.local:8123/api/camera_proxy/camera.stefan_map?token=XXX is this a bug or maybe we can disable this (I get the same image all the time)?

This is caused by refreshing the map image whenever the card is updated (e.g. because of change in entity that is displayed in a tile). I might try to optimize it someday though

Misiu commented 1 year ago

This is caused by refreshing the map image whenever the card is updated (e.g. because of change in entity that is displayed in a tile). I might try to optimize it someday though

That would be awesome! A lot of unneeded requests could be skipped.

The version in PR doesn't contain map camera.

Didn't know that, I'm using the integration I linked via HACS.

Well, map rendering is also handled by my code - taken from Map Extractor

The map displayed on your card looks exactly like the map in the Roborock app, so that's not the problem. What I was trying to ask: is there an option to use a static (custom-made) image as a card image and only show vacuum position on it?

This is the image I get from the camera proxy: image I could use Gimp or https://www.photopea.com/ to create a custom (much cleaner) image and use it instead. Just don't know if this is possible.

PiotrMachowski commented 1 year ago

What I was trying to ask: is there an option to use a static (custom-made) image as a card image and only show vacuum position on it?

No, it's not possible at this moment. There is a feature request for this functionality: #503

Lash-L commented 1 year ago

@Misiu Looks good 👍 unfortunately I don't think it will have map support soon

Yep - Core approval takes a bit. Map support will come but it is on the lower end of my priorities for the official integration, and we'll need the extraction logic in a custom pypi package.

PiotrMachowski commented 1 year ago

@Lash-L yeah, I'll do it someday 😉 anyway, I don't think that official integration will include calibration points

Lash-L commented 1 year ago

@Lash-L yeah, I'll do it someday 😉

Yep no rush! Like I said it is on the lower end of my priorities anyways

anyway, I don't think that official integration will include calibration points

What do you mean by calibration points?

PiotrMachowski commented 1 year ago

Calibration points are a concept that I have introduced in the first version of this card. They are used to calculate coordinates in the vacuum's coordinate system from coordinates on the map image. More on them here.

They are required for this card to work properly. Integrations that provide map that can be used automatically with this card return calibration points as an attribute of a camera entity. Custom Roborock integration returns them here

wigster commented 1 year ago

Sorry to butt in, but I just wanted to ask the extent to which Roborock support is working in the last beta. As a result of the Roborock integration in core 2023.5 I discovered the HACS integration and would like to move over from Xiaomi, but I depend on your card to drive the vacuum.

Lash-L commented 1 year ago

The Hacs integration works very well with the card.

The core integration will not work with the card for at least a few more releases

humbertogontijo commented 1 year ago

@wigster for now you can check https://github.com/humbertogontijo/homeassistant-roborock/discussions/40

PiotrMachowski commented 1 year ago

Done in v2.2.0