mirror of
https://github.com/CCOSTAN/Home-AssistantConfig.git
synced 2025-12-03 19:41:47 +00:00
380 lines
14 KiB
YAML
Executable File
380 lines
14 KiB
YAML
Executable File
######################################################################
|
|
# @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 - Room queue, away/on-demand runs
|
|
# Weekday sweep, weekend mop, bathrooms last, notifications
|
|
# -------------------------------------------------------------------
|
|
######################################################################
|
|
|
|
## 1. Helpers
|
|
######################################################################
|
|
|
|
input_boolean:
|
|
l10s_vacuum_weekday_cycle_active:
|
|
name: L10s Weekday Cleaning Active
|
|
icon: mdi:robot-vacuum
|
|
l10s_vacuum_on_demand:
|
|
name: Dream Clean (On-Demand)
|
|
icon: mdi:rocket-launch
|
|
|
|
input_datetime:
|
|
l10s_vacuum_last_weekday_cycle:
|
|
name: L10s Last Weekday Cleaning Cycle
|
|
has_date: true
|
|
has_time: true
|
|
|
|
input_text:
|
|
l10s_vacuum_room_queue:
|
|
name: L10s Vacuum Room Queue
|
|
icon: mdi:format-list-bulleted
|
|
max: 255
|
|
l10s_vacuum_room_catalog:
|
|
name: L10s Vacuum Room Catalog
|
|
# 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.
|
|
initial: "14,12,10,7,15,9,17,13,8,6,4,2,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:
|
|
# Weekday runs are sweeping (vacuum only), weekend runs are mopping
|
|
cleaning_mode: "{{ 'mopping' if now().weekday() in [5, 6] else 'sweeping' }}"
|
|
catalog_raw: "{{ states('input_text.l10s_vacuum_room_catalog') | string | replace(' ', '') }}"
|
|
queue_raw: "{{ states('input_text.l10s_vacuum_room_queue') | string | replace(' ', '') }}"
|
|
last_reset: "{{ as_datetime(states('input_datetime.l10s_vacuum_last_weekday_cycle'), default=None) }}"
|
|
# Seed if queue is empty AND last reset was not today
|
|
can_seed_today: "{{ last_reset is none or last_reset.date() != now().date() }}"
|
|
will_seed: "{{ queue_raw | length == 0 and can_seed_today and catalog_raw | length > 0 }}"
|
|
seeded_queue_list: >
|
|
{% set q = catalog_raw.split(',') if will_seed else queue_raw.split(',') %}
|
|
{{ q | map('int') | list }}
|
|
# Define bathroom IDs for mopping separation
|
|
bath_ids: [1, 3, 4]
|
|
nonbath_list: "{{ seeded_queue_list | reject('in', bath_ids) | list }}"
|
|
bath_list: "{{ seeded_queue_list | select('in', bath_ids) | list }}"
|
|
# Prioritize non-bathrooms first, then bathrooms
|
|
segments_to_clean: >
|
|
{% if nonbath_list | length > 0 %}
|
|
{{ nonbath_list }}
|
|
{% elif bath_list | length > 0 %}
|
|
{{ bath_list }}
|
|
{% else %}
|
|
[]
|
|
{% endif %}
|
|
|
|
# 1. Seed the queue if necessary
|
|
- choose:
|
|
- conditions:
|
|
- condition: template
|
|
value_template: "{{ will_seed }}"
|
|
sequence:
|
|
- service: input_text.set_value
|
|
target:
|
|
entity_id: input_text.l10s_vacuum_room_queue
|
|
data:
|
|
value: "{{ catalog_raw }}"
|
|
- service: input_datetime.set_datetime
|
|
target:
|
|
entity_id: input_datetime.l10s_vacuum_last_weekday_cycle
|
|
data:
|
|
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
|
|
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: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.l10s_vacuum_weekday_cycle_active
|
|
- 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: 'Away Vacuum: Reset Queue (Mon/Sat)'
|
|
id: 93a6e7dc-9c32-4d53-9f7c-651cd60f4b84
|
|
trigger:
|
|
- platform: time
|
|
at: '08:55:00'
|
|
condition:
|
|
- condition: time
|
|
weekday:
|
|
- mon
|
|
- sat
|
|
action:
|
|
- service: input_text.set_value
|
|
target:
|
|
entity_id: input_text.l10s_vacuum_room_queue
|
|
data:
|
|
value: "{{ states('input_text.l10s_vacuum_room_catalog') }}"
|
|
- service: input_text.set_value
|
|
target:
|
|
entity_id: input_text.l10s_vacuum_rooms_cleaned_today
|
|
data:
|
|
value: ""
|
|
- service: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.l10s_vacuum_weekday_cycle_active
|
|
- service: input_datetime.set_datetime
|
|
target:
|
|
entity_id: input_datetime.l10s_vacuum_last_weekday_cycle
|
|
data:
|
|
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
|
|
- service: input_boolean.turn_off
|
|
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: state
|
|
entity_id: input_boolean.l10s_vacuum_weekday_cycle_active
|
|
state: 'on'
|
|
- 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_rooms: >
|
|
{% if matched_room_id == 0 %}
|
|
{{ queue_ints | join(',') }}
|
|
{% else %}
|
|
{% 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 | join(',') }}
|
|
{% endif %}
|
|
|
|
condition:
|
|
# Only run if there's actually a queue and a room was successfully matched to the start of the queue
|
|
- 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') }}"
|
|
room_name: "{{ room_map.get(matched_room_id, states('sensor.l10s_vacuum_current_room')) }}"
|
|
updated_cleaned: >
|
|
{% set parts = cleaned_raw.split(',') if cleaned_raw | length > 0 else [] %}
|
|
{% if room_name not in parts %}
|
|
{{ (parts + [room_name]) | join(', ') }}
|
|
{% else %}
|
|
{{ cleaned_raw }}
|
|
{% endif %}
|
|
remaining_count: "{{ remaining_rooms.split(',') | length if remaining_rooms | length > 0 else 0 }}"
|
|
- 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 done'
|
|
value1: "{{ room_name }} cleaned."
|
|
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_rooms | length > 0 }}"
|
|
sequence:
|
|
- service: script.l10s_vacuum_start_next_room
|
|
- conditions:
|
|
- condition: template
|
|
value_template: "{{ remaining_rooms | length == 0 }}"
|
|
sequence:
|
|
- service: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.l10s_vacuum_weekday_cycle_active
|
|
- service: input_datetime.set_datetime
|
|
target:
|
|
entity_id: input_datetime.l10s_vacuum_last_weekday_cycle
|
|
data:
|
|
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
|
|
|
|
- alias: 'Away Vacuum: Cycle Complete'
|
|
id: 8fa7779a-957b-49a3-84e7-36ca93c2e0d2
|
|
trigger:
|
|
- platform: state
|
|
entity_id: sensor.l10s_vacuum_task_status
|
|
to: 'completed'
|
|
- platform: state
|
|
entity_id: vacuum.l10s_vacuum
|
|
to: 'docked'
|
|
for: 00:05:00
|
|
condition:
|
|
- condition: template
|
|
value_template: "{{ is_state('sensor.l10s_vacuum_task_status', 'completed') }}"
|
|
- condition: template
|
|
value_template: "{{ (states('input_text.l10s_vacuum_room_queue') | replace(' ', '')) | length == 0 }}"
|
|
action:
|
|
- service: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.l10s_vacuum_weekday_cycle_active
|
|
- service: input_datetime.set_datetime
|
|
target:
|
|
entity_id: input_datetime.l10s_vacuum_last_weekday_cycle
|
|
data:
|
|
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
|
|
|
|
- alias: 'Away Vacuum: Start Bathrooms When Pending'
|
|
id: 6b8d7d0e-fc21-4a2f-bd9e-4c51f6b9c2c3
|
|
|
|
- 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
|