UI advanced example¶
Main feature is ability to specify via UI the order of the cleaned rooms. Thanks to @aidbish for the initial idea.
Setup¶
For this setup to work, you need some custom components (all available via HACS)
Configuration¶
Below you can find the snippets for this example including the backend configuration. Adjust it for your needs.
Todo
Please change the of the entities accordingly. My vacuum has the name "susi". Search for this name :)
Backend (configuration.yaml)¶
script:
deebot_clean:
description: Start a deebot cleaning task
variables:
queue: input_text.deebot_susi_queue
vacuum_bot: vacuum.susi
sequence:
- alias: Get room numbers
variables:
# See for appending to list
# https://github.com/home-assistant/core/issues/33678#issuecomment-609424851
rooms: >-
{%- set queue_split = states(queue).split(",") -%}
{%- set rooms = state_attr(vacuum_bot, "rooms")-%}
{%- set data = namespace(rooms=[]) -%}
{%- for room_name in queue_split -%}
{%- set data.rooms = data.rooms + [rooms[room_name]] -%}
{%- endfor -%}
{{ data.rooms | join(",") }}
- alias: Send cleaning job to vacuum
service: vacuum.send_command
data:
entity_id: "{{ vacuum_bot }}"
command: spot_area
params:
rooms: "{{ rooms }}"
cleanings: 1
deebot_room_queue:
description: Add/Remove a room from the queue
fields:
queue:
description: The queue variable
example: input_text.deebot_susi_queue
room:
description: Room, which should be removed or added
example: kitchen
sequence:
- service: input_text.set_value
target:
entity_id: "{{ queue }}"
data:
value: >-
{%- set queue_state = states(queue) -%}
{%- set queue_split = queue_state.split(",") -%}
{%- if queue_state | length == 0 -%}
{{ room }}
{%- elif room in queue_split -%}
{{ queue_split | reject("eq", room) | list | join(",")}}
{%- else -%}
{{ (queue_split + [room]) | join(",") }}
{%- endif -%}
automation:
- alias: Staubsauger Zimmer resetieren
trigger:
- platform: event
event_type: deebot_cleaning_job
event_data:
status: finished
condition: []
action:
- alias: Reset room queue
service: input_text.set_value
target:
entity_id: input_text.deebot_susi_queue
data:
value: ""
mode: single
recorder:
exclude:
entities:
- input_text.deebot_susi_queue
- script.deebot_room_queue
entity_globs:
- sensor.deebot_*_queue_*
input_text:
deebot_susi_queue:
name: Susi Raum Reihenfolge
max: 255 # Current max limit. See https://www.home-assistant.io/integrations/input_text/#max
# Room name comes from the integration to match attribute names
template:
unique_id: deebot_susi_queue
trigger:
- platform: state
entity_id: input_text.deebot_susi_queue
sensor:
# Add for each room the following. Change room_name accordingly
- unique_id: deebot_susi_queue_living_room
name: deebot_susi_queue_living_room
# room_name must match the room name provided by the vacuum
state: >
{% set room_name = "living_room" %}
{% set queue = trigger.to_state.state.split(",") %}
{{ queue.index(room_name)+1 if room_name in queue else 0 }}
UI configuration¶
In the UI we use button card templates to reduce duplicate code. More information can be found in their documentation.
button_card_templates:
vacuum_service:
color: var(--text-color)
entity: vacuum.susi # change me
tap_action:
action: call-service
service_data:
entity_id: vacuum.susi # change me
lock:
enabled: |
[[[ return variables.enabled ]]]
exemptions: []
styles:
card:
- height: 80px
lock:
- color: var(--primary-text-color)
state:
- operator: template
value: |
[[[ return variables.enabled ]]]
styles:
card:
- color: var(--disabled-text-color)
vacuum_room:
color: var(--text-color)
variables:
# change me
lock_enabled: >
[[[ return ['cleaning', 'paused'].includes(states['vacuum.susi'].state)
]]]
state:
- operator: template
value: |
[[[ return variables.lock_enabled && entity.state == 0 ]]]
styles:
card:
- color: var(--disabled-text-color)
- styles:
card:
- background-color: var(--primary-color)
operator: ">="
value: 1
styles:
card:
- font-size: 12px
grid:
- position: relative
custom_fields:
order:
- display: |
[[[
if (entity.state == "0")
return "none";
return "block";
]]]
- position: absolute
- left: 5%
- top: 5%
- height: 20px
- width: 20px
- font-size: 20px
- font-weight: bold
- line-height: 20px
custom_fields:
order: |
[[[ return entity.state ]]]
tap_action:
action: call-service
service: script.deebot_room_queue
service_data:
queue: input_text.deebot_susi_queue
lock:
enabled: |
[[[ return variables.lock_enabled ]]]
exemptions: []
Below the actual card configuration
type: vertical-stack
cards:
- type: custom:vacuum-card
entity: vacuum.susi # change me
stats:
default:
- entity_id: sensor.susi_life_span_brush # change me
unit: "%"
subtitle: Hauptbürste
- entity_id: sensor.susi_life_span_side_brush # change me
unit: "%"
subtitle: Seitenbürsten
- entity_id: sensor.susi_life_span_filter # change me
unit: "%"
subtitle: Filter
cleaning:
- entity_id: sensor.susi_stats_area # change me
unit: m²
subtitle: Geputzte Fläche
- entity_id: sensor.susi_stats_time # change me
unit: Minuten
subtitle: Reinigungsdauer
show_status: true
show_toolbar: false
compact_view: true
- type: custom:button-card
color: auto-no-temperature
name: Räume zum Putzen auswählen
styles:
card:
- font-size: 18px
- height: 30px
name:
- color: var(--primary-color)
- type: horizontal-stack
cards:
# Add the following chard for each room. Change values accordingly
- type: custom:button-card
template: vacuum_room
entity: sensor.deebot_susi_queue_living_room # change me
icon: mdi:sofa
name: Wohnzimmer
tap_action:
service_data:
room: living_room # change me
- type: horizontal-stack
cards:
- type: conditional
conditions:
- entity: vacuum.susi # change me
state_not: cleaning
- entity: vacuum.susi # change me
state_not: paused
card:
type: custom:button-card
template: vacuum_service
icon: mdi:play
name: Start
tap_action:
action: call-service
service: script.deebot_clean
variables:
# change me
enabled: |
[[[
return ((!states['input_text.deebot_susi_queue'].state ||
states['input_text.deebot_susi_queue'].state.length === 0)
&& ['docked', 'idle', 'error', 'returning'].includes(entity.state))
]]]
- type: conditional
conditions:
- entity: vacuum.susi # change me
state: cleaning
card:
type: custom:button-card
color: auto
icon: mdi:pause
name: Pause
tap_action:
action: call-service
service: vacuum.pause
service_data:
entity_id: vacuum.susi # change me
styles:
card:
- height: 80px
- background-color: var(-color)
- type: conditional
conditions:
- entity: vacuum.susi # change me
state: paused
card:
type: custom:button-card
color: auto
icon: mdi:play-pause
name: Weiter
tap_action:
action: call-service
service: vacuum.start
service_data:
entity_id: vacuum.susi # change me
styles:
card:
- height: 80px
- background-color: var(-color)
- type: custom:button-card
template: vacuum_service
icon: mdi:stop
name: Stop
tap_action:
service: vacuum.stop
variables:
enabled: |
[[[
return !(['cleaning', 'paused', 'returning'].includes(entity.state))
]]]
- type: horizontal-stack
cards:
- type: custom:button-card
template: vacuum_service
icon: mdi:home-map-marker
name: Zurück zur Ladestation
tap_action:
service: vacuum.return_to_base
variables:
enabled: |
[[[
return ['docked', 'returning'].includes(entity.state)
]]]
- type: custom:button-card
color: auto
icon: mdi:map-marker
name: Lokalisieren
tap_action:
action: call-service
service: vacuum.locate
service_data:
entity_id: vacuum.susi # change me
styles:
card:
- height: 80px
- background-color: var(-color)
- type: picture-entity
entity: camera.susi_live_map # change me
tap_action:
action: none
hold_action:
action: none
show_state: false
show_name: false