Skip to content

Commit a10ee05

Browse files
committed
Refine vacuum automation logic to improve queue handling, update cleaning phase conditions, and enhance logbook messages for better tracking of vacuum state changes.
1 parent e6b88ac commit a10ee05

File tree

2 files changed

+65
-45
lines changed

2 files changed

+65
-45
lines changed

config/packages/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Live collection of plug-and-play Home Assistant packages. Each YAML file in this
6464
### Dreame vacuum automations
6565
- Logic lives in [vacuum.yaml](vacuum.yaml): continuous four-phase loop (sweep main, sweep baths, mop main, mop baths) driven by `input_select.l10s_vacuum_phase` and `input_text.l10s_vacuum_room_queue`, with per-room notifications and automatic reseeding between phases.
6666
- Uses the Dreame HACS integration with segment IDs to enforce bathrooms last in each sweep/mop pass, dock on arrival, and auto-run if idle for 3+ days.
67-
- Room queue advances on a 3-minute dwell in `sensor.l10s_vacuum_current_room` (queue = remaining rooms); phase changes happen on `sensor.l10s_vacuum_task_status: completed` and an empty queue.
67+
- Room queue advances on a 2-minute dwell in `sensor.l10s_vacuum_current_room` (queue = remaining rooms); phase changes happen on `sensor.l10s_vacuum_task_status: completed` and an empty queue.
6868
![Dreame Automations](../www/custom_ui/floorplan/images/branding/Dreame%20Automations.png)
6969

7070
### Blog & video deep dives

config/packages/vacuum.yaml

Lines changed: 64 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
# -------------------------------------------------------------------
1010
# Notes:
1111
# - `sensor.l10s_vacuum_current_room` can change during transit; require a dwell (`for:`) before dequeuing.
12-
# - Treat 3+ minutes in a room as "being cleaned" and dequeue immediately (queue = remaining rooms).
13-
# - Phase changes are driven by `sensor.l10s_vacuum_task_status: completed` and an empty queue to avoid skipping ahead on false room transitions.
12+
# - Treat 2+ minutes in a room as "being cleaned" and dequeue immediately (queue = remaining rooms).
13+
# - Phase changes are driven by `sensor.l10s_vacuum_task_status: completed` and an empty queue (queue is the source of truth).
1414
# - Avoid reissuing `dreame_vacuum.vacuum_clean_segment` while already cleaning; only send a new segment job when starting/resuming or switching phases.
1515
# - Jinja2 loop scoping: use a `namespace` when building lists (otherwise the queue can appear empty and get cleared).
16-
# - Docked + task complete clears the queue to keep the UI state honest.
16+
# - Docked + task complete only logs queue state; no auto-clearing.
1717
# - Queue-empty trigger ignores already-completed tasks to avoid immediate reseeding.
1818
# - Queue-empty no longer auto-reseeds; phase advance handles the next run on completion.
19+
# - Mop phases use `sweeping_and_mopping` instead of mop-only.
1920
######################################################################
2021

2122
## 1. Helpers
@@ -71,7 +72,7 @@ script:
7172
phase_order: ['sweep_main', 'sweep_bath', 'mop_main', 'mop_bath']
7273
phase_state: "{{ states('input_select.l10s_vacuum_phase') }}"
7374
phase: "{{ phase_state if phase_state in phase_order else 'sweep_main' }}"
74-
cleaning_mode: "{{ 'mopping' if 'mop_' in phase else 'sweeping' }}"
75+
cleaning_mode: "{{ 'sweeping_and_mopping' if 'mop_' in phase else 'sweeping' }}"
7576
queue_raw: "{{ states('input_text.l10s_vacuum_room_queue') | default('', true) | string | replace(' ', '') }}"
7677
queue_ints: "{{ queue_raw | regex_findall('[0-9]+') | map('int') | select('gt', 0) | list }}"
7778
phase_segments: >
@@ -317,7 +318,8 @@ automation:
317318
entity_id: vacuum.l10s_vacuum
318319
to: 'docked'
319320
variables:
320-
queue_empty: "{{ (states('input_text.l10s_vacuum_room_queue') | default('', true) | trim) == '' }}"
321+
queue_raw: "{{ states('input_text.l10s_vacuum_room_queue') | default('', true) | trim }}"
322+
queue_empty: "{{ queue_raw == '' }}"
321323
condition:
322324
- condition: state
323325
entity_id: sensor.l10s_vacuum_task_status
@@ -339,7 +341,7 @@ automation:
339341
- service: script.send_to_logbook
340342
data:
341343
topic: "VACUUM"
342-
message: "Docked but queue still has rooms; leaving queue intact."
344+
message: "Docked after completion; queue still has rooms: {{ queue_raw }}."
343345
default: []
344346

345347
- alias: 'Away Vacuum: Advance Phase on Task Complete'
@@ -353,62 +355,80 @@ automation:
353355
- condition: state
354356
entity_id: input_boolean.l10s_vacuum_on_demand
355357
state: 'on'
356-
- condition: template
357-
value_template: "{{ (states('input_text.l10s_vacuum_room_queue') | default('', true) | trim) == '' }}"
358358
variables:
359+
queue_raw: "{{ states('input_text.l10s_vacuum_room_queue') | default('', true) | trim }}"
360+
queue_empty: "{{ queue_raw == '' }}"
359361
phase_order: ['sweep_main', 'sweep_bath', 'mop_main', 'mop_bath']
360362
phase_state: "{{ states('input_select.l10s_vacuum_phase') }}"
361363
phase: "{{ phase_state if phase_state in phase_order else 'sweep_main' }}"
362364
phase_index: "{{ phase_order.index(phase) if phase in phase_order else 0 }}"
363365
has_next_phase: "{{ phase_index < (phase_order | length) - 1 }}"
364366
next_phase: "{{ phase_order[phase_index + 1] if has_next_phase else '' }}"
365367
action:
366-
- service: script.send_to_logbook
367-
data:
368-
topic: "VACUUM"
369-
message: >
370-
Phase complete: {{ phase }}. {{
371-
'Advancing to ' ~ next_phase ~ '.' if has_next_phase else 'All phases complete; shutting down.'
372-
}}
373368
- choose:
374369
- conditions:
375370
- condition: template
376-
value_template: "{{ has_next_phase }}"
371+
value_template: "{{ queue_empty }}"
377372
sequence:
378-
- service: input_select.select_option
379-
target:
380-
entity_id: input_select.l10s_vacuum_phase
373+
- service: script.send_to_logbook
381374
data:
382-
option: "{{ next_phase }}"
383-
- service: input_text.set_value
384-
target:
385-
entity_id: input_text.l10s_vacuum_room_queue
375+
topic: "VACUUM"
376+
message: >
377+
Phase complete: {{ phase }}. {{
378+
'Advancing to ' ~ next_phase ~ '.' if has_next_phase else 'All phases complete; shutting down.'
379+
}}
380+
- choose:
381+
- conditions:
382+
- condition: template
383+
value_template: "{{ has_next_phase }}"
384+
sequence:
385+
- service: input_select.select_option
386+
target:
387+
entity_id: input_select.l10s_vacuum_phase
388+
data:
389+
option: "{{ next_phase }}"
390+
- service: input_text.set_value
391+
target:
392+
entity_id: input_text.l10s_vacuum_room_queue
393+
data:
394+
value: ""
395+
- wait_template: "{{ not is_state('vacuum.l10s_vacuum', 'returning') and not is_state('vacuum.l10s_vacuum', 'cleaning') }}"
396+
timeout: '01:30:00'
397+
continue_on_timeout: false
398+
- service: script.l10s_vacuum_start_next_room
399+
- conditions:
400+
- condition: template
401+
value_template: "{{ not has_next_phase }}"
402+
sequence:
403+
- service: input_select.select_option
404+
target:
405+
entity_id: input_select.l10s_vacuum_phase
406+
data:
407+
option: "sweep_main"
408+
- service: input_text.set_value
409+
target:
410+
entity_id: input_text.l10s_vacuum_room_queue
411+
data:
412+
value: ""
413+
- service: input_boolean.turn_off
414+
target:
415+
entity_id: input_boolean.l10s_vacuum_on_demand
416+
- service: vacuum.return_to_base
417+
target:
418+
entity_id: vacuum.l10s_vacuum
419+
default: []
420+
- conditions:
421+
- condition: template
422+
value_template: "{{ not queue_empty }}"
423+
sequence:
424+
- service: script.send_to_logbook
386425
data:
387-
value: ""
426+
topic: "VACUUM"
427+
message: "Task complete but queue not empty for {{ phase }}; resuming: {{ queue_raw }}."
388428
- wait_template: "{{ not is_state('vacuum.l10s_vacuum', 'returning') and not is_state('vacuum.l10s_vacuum', 'cleaning') }}"
389429
timeout: '01:30:00'
390430
continue_on_timeout: false
391431
- service: script.l10s_vacuum_start_next_room
392-
- conditions:
393-
- condition: template
394-
value_template: "{{ not has_next_phase }}"
395-
sequence:
396-
- service: input_select.select_option
397-
target:
398-
entity_id: input_select.l10s_vacuum_phase
399-
data:
400-
option: "sweep_main"
401-
- service: input_text.set_value
402-
target:
403-
entity_id: input_text.l10s_vacuum_room_queue
404-
data:
405-
value: ""
406-
- service: input_boolean.turn_off
407-
target:
408-
entity_id: input_boolean.l10s_vacuum_on_demand
409-
- service: vacuum.return_to_base
410-
target:
411-
entity_id: vacuum.l10s_vacuum
412432
default: []
413433

414434
- alias: 'Vacuum Sensor Cleaning Silencer'

0 commit comments

Comments
 (0)