###################################################################### # @CCOSTAN - Follow Me on X # For more info visit https://www.vcloudinfo.com/click-here # Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig # ------------------------------------------------------------------- # Dreame Vacuum Orchestration - Continuous phased sweep/mop with away/on-demand # Phases: sweep main, sweep baths, mop main, mop baths; notifications + idle auto-start # ------------------------------------------------------------------- ###################################################################### ## 1. Helpers ###################################################################### input_boolean: l10s_vacuum_on_demand: name: Dreame Clean (On-Demand) icon: mdi:robot-vacuum input_select: l10s_vacuum_phase: name: L10s Vacuum Phase options: - sweep_main - sweep_bath - mop_main - mop_bath initial: sweep_main icon: mdi:playlist-check input_text: l10s_vacuum_room_queue: name: L10s Vacuum Room Queue # Room order (id:name): 14 Kitchen, 12 Dining, 10 Living, 7 Master Bedroom, 15 Foyer, 9 Stacey Office, # 17 Formal Dining, 13 Hallway, 8 Justin Bedroom, 6 Paige Bedroom, 4 Master Bathroom, 2 Office, 1 Pool Bath, 3 Kids Bathroom. icon: mdi:format-list-bulleted max: 255 l10s_vacuum_room_catalog: name: L10s Vacuum Room Catalog initial: "6,7,8,9,10,12,13,14,15,17,2,4,1,3" icon: mdi:map max: 255 l10s_vacuum_rooms_cleaned_today: name: L10s Vacuum Rooms Cleaned Today icon: mdi:clipboard-check-outline max: 255 ## 2. Script: Start Next Room ###################################################################### script: l10s_vacuum_start_next_room: alias: 'Away Vacuum: Start Next Room' mode: single sequence: - variables: catalog_raw: "{{ states('input_text.l10s_vacuum_room_catalog') | default('', true) | string | replace(' ', '') }}" catalog_ints: "{{ catalog_raw | regex_findall('[0-9]+') | map('int') | select('gt', 0) | list }}" bath_ids: [1, 3, 4] main_ids: "{{ catalog_ints | reject('in', bath_ids) | list }}" phase_order: ['sweep_main', 'sweep_bath', 'mop_main', 'mop_bath'] phase_state: "{{ states('input_select.l10s_vacuum_phase') }}" phase: "{{ phase_state if phase_state in phase_order else 'sweep_main' }}" cleaning_mode: "{{ 'mopping' if 'mop_' in phase else 'sweeping' }}" queue_raw: "{{ states('input_text.l10s_vacuum_room_queue') | default('', true) | string | replace(' ', '') }}" queue_ints: "{{ queue_raw | regex_findall('[0-9]+') | map('int') | select('gt', 0) | list }}" phase_segments: > {% if phase == 'sweep_main' %} {{ main_ids }} {% elif phase == 'sweep_bath' %} {{ bath_ids }} {% elif phase == 'mop_main' %} {{ main_ids }} {% else %} {{ bath_ids }} {% endif %} segments_to_clean: "{{ queue_ints if queue_ints | length > 0 else phase_segments }}" # 1. Seed the queue if necessary - choose: - conditions: - condition: template value_template: "{{ queue_ints | length == 0 and phase_segments | length > 0 }}" sequence: - service: input_text.set_value target: entity_id: input_text.l10s_vacuum_room_queue data: value: "{{ phase_segments | join(',') }}" default: [] # 2. Check if there is anything to clean and stop if not - choose: - conditions: - condition: template value_template: "{{ segments_to_clean | length == 0 }}" sequence: - stop: 'No rooms left to clean today.' default: [] # 3. Start cleaning - service: select.select_option target: entity_id: select.l10s_vacuum_cleaning_mode data: option: "{{ cleaning_mode }}" - service: vacuum.set_fan_speed target: entity_id: vacuum.l10s_vacuum data: fan_speed: Standard - service: dreame_vacuum.vacuum_clean_segment target: entity_id: vacuum.l10s_vacuum data: # Clean the non-bathrooms if any, otherwise clean the bathrooms segments: "{{ segments_to_clean }}" ## 3. Automations ###################################################################### automation: - alias: 'Vacuum: Reset Cleaned List at 5am' id: 18f7b6d3-c02c-4ec1-88b3-0c3b8b4c6f7b trigger: - platform: time at: '05:00:00' action: - service: input_text.set_value target: entity_id: input_text.l10s_vacuum_rooms_cleaned_today data: value: "" - alias: 'Vacuum: Auto-Start if Idle 3 Days' id: c6b3f1e8-9a3f-4098-9b9e-1c7f2d6f1d11 trigger: - platform: time at: '16:00:00' condition: - condition: template value_template: > {% set last = state_attr('script.l10s_vacuum_start_next_room','last_triggered') %} {{ last is none or (now() - last).days >= 3 }} action: - service: input_boolean.turn_on target: entity_id: input_boolean.l10s_vacuum_on_demand - alias: 'Away Vacuum: Start or Resume When we leave or On-Demand' id: 7f7e0a3c-6452-4f6b-8464-c6c25770a148 trigger: - platform: state entity_id: group.family to: 'not_home' - platform: state entity_id: input_boolean.l10s_vacuum_on_demand to: 'on' condition: - condition: state entity_id: input_boolean.guest_mode state: 'off' - condition: template value_template: > {{ is_state('input_boolean.l10s_vacuum_on_demand', 'on') or is_state('group.family', 'not_home') }} - condition: template value_template: "{{ not is_state('vacuum.l10s_vacuum', 'cleaning') }}" action: - service: script.l10s_vacuum_start_next_room - alias: 'Away Vacuum: Dock When Family Returns' id: 1ef172f2-4b30-4e5b-953d-d4d1ca8701ad trigger: - platform: state entity_id: group.family to: 'home' - platform: state entity_id: input_boolean.l10s_vacuum_on_demand to: 'off' condition: - condition: template value_template: > {{ is_state('vacuum.l10s_vacuum', 'cleaning') or is_state('vacuum.l10s_vacuum', 'returning') or is_state('vacuum.l10s_vacuum', 'paused') }} action: - service: vacuum.pause target: entity_id: vacuum.l10s_vacuum - delay: 00:00:10 - service: vacuum.return_to_base target: entity_id: vacuum.l10s_vacuum - alias: 'Away Vacuum: Confirm Room Cleaned' id: c581c570-55b0-4acd-8b5d-53cfb486cc2a trigger: - platform: state entity_id: sensor.l10s_vacuum_current_room for: '00:03:00' variables: room_map: {14:'kitchen',12:'dining-room',10:'living room',7:'master-bedroom',15:'foyer',9:'stacey-office',17:'formal-dining',13:'hallway',8:'justin-bedroom',6:'paige-bedroom',4:'master-bathroom',2:'office',1:'pool-bath',3:'kids-bathroom'} queue_raw: "{{ states('input_text.l10s_vacuum_room_queue') | default('', true) | string | replace(' ', '') }}" queue_ints: "{{ queue_raw | regex_findall('[0-9]+') | map('int') | list | default([], true) }}" current_room_id: "{{ trigger.to_state.attributes.room_id | default(state_attr('sensor.l10s_vacuum_current_room', 'room_id'), true) | int(0) }}" matched_room_id: "{{ current_room_id if current_room_id > 0 and current_room_id in (queue_ints | default([], true)) else 0 }}" remaining_list: > {% set rem = [] %} {% set removed = namespace(done=false) %} {% for r in queue_ints %} {% if not removed.done and r == matched_room_id %} {% set removed.done = true %} {% else %} {% set rem = rem + [r] %} {% endif %} {% endfor %} {{ rem }} remaining_rooms: "{{ remaining_list | join(',') }}" remaining_count: "{{ remaining_list | length }}" phase_order: ['sweep_main', 'sweep_bath', 'mop_main', 'mop_bath'] phase_state: "{{ states('input_select.l10s_vacuum_phase') }}" phase: "{{ phase_state if phase_state in phase_order else 'sweep_main' }}" phase_index: "{{ phase_order.index(phase) if phase in phase_order else 0 }}" has_next_phase: "{{ phase_index < (phase_order | length) - 1 }}" next_phase: "{{ phase_order[phase_index + 1] if has_next_phase else '' }}" condition: - condition: template value_template: "{{ queue_ints | length > 0 }}" - condition: template value_template: "{{ matched_room_id != 0 }}" - condition: state entity_id: vacuum.l10s_vacuum state: 'cleaning' action: - service: input_text.set_value target: entity_id: input_text.l10s_vacuum_room_queue data: value: "{{ remaining_rooms }}" - variables: cleaned_raw: "{{ states('input_text.l10s_vacuum_rooms_cleaned_today') | default('', true) | string }}" cleaned_parts: "{{ cleaned_raw | regex_findall('[^,]+') | map('trim') | reject('equalto','') | list }}" room_name: "{{ room_map.get(matched_room_id, states('sensor.l10s_vacuum_current_room')) }}" updated_cleaned: > {% set parts = cleaned_parts %} {% if room_name not in parts %} {{ (parts + [room_name]) | join(', ') }} {% else %} {{ parts | join(', ') }} {% endif %} - service: input_text.set_value target: entity_id: input_text.l10s_vacuum_rooms_cleaned_today data: value: "{{ updated_cleaned }}" - service: script.notify_engine data: title: 'Vacuum Room Cleaned' value1: "{{ room_name }} is clean." value2: "Remaining: {{ remaining_count }}." ios_category: 'camera' camera_entity: 'camera.l10s_vacuum_map' content_type: 'jpeg' who: 'carlo' group: 'information' - choose: - conditions: - condition: template value_template: "{{ remaining_count > 0 }}" sequence: - service: script.l10s_vacuum_start_next_room - conditions: - condition: template value_template: "{{ remaining_count == 0 and has_next_phase }}" sequence: - service: input_select.select_option target: entity_id: input_select.l10s_vacuum_phase data: option: "{{ next_phase }}" - service: input_text.set_value target: entity_id: input_text.l10s_vacuum_room_queue data: value: "" - service: script.l10s_vacuum_start_next_room - conditions: - condition: template value_template: "{{ remaining_count == 0 and not has_next_phase }}" sequence: - service: input_select.select_option target: entity_id: input_select.l10s_vacuum_phase data: option: "sweep_main" - service: input_text.set_value target: entity_id: input_text.l10s_vacuum_room_queue data: value: "" - service: script.l10s_vacuum_start_next_room - alias: 'Vacuum Sensor Cleaning Silencer' id: 6548de52-a4a4-4df2-9d66-9c2c15577a7f trigger: - platform: numeric_state entity_id: sensor.l10s_vacuum_sensor_dirty_left below: 10 condition: - condition: state entity_id: sensor.l10s_vacuum_task_status state: 'completed' action: - service: button.press target: entity_id: button.l10s_vacuum_reset_sensor - alias: 'Help Vacuum' id: 6548de52-a4a4-4df2-9d66-9c2c15577a7e trigger: - platform: state entity_id: sensor.l10s_vacuum_error - platform: event event_type: event_did_someone_help_vacuum_loop condition: - condition: template value_template: "{{ states('sensor.l10s_vacuum_error') not in ['no_error', 'unavailable'] }}" action: - service: script.notify_engine data: title: 'Help vacuum' value1: "{{ states('sensor.l10s_vacuum_error') }} - {{states('sensor.l10s_vacuum_current_room')}}" who: 'family' ios_category: 'camera' camera_entity: 'camera.l10s_vacuum_map' content_type: 'jpeg' group: 'information' - wait_template: "{{ is_state('group.bed', 'off') }}" - wait_template: "{{ is_state('group.family', 'home') }}" - delay: 00:03:00 - service: vacuum.locate entity_id: vacuum.l10s_vacuum - service: script.speech_engine data: value1: > {{ "Vacuum error: " ~ states('sensor.l10s_vacuum_error') ~ " [ask Residents to help]" }} Currently in {{states('sensor.l10s_vacuum_current_room')}} - delay: 00:01:00 - service: vacuum.locate entity_id: vacuum.l10s_vacuum - delay: 00:20:00 - event: event_did_someone_help_vacuum_loop