AutomationDataset/elas123/elas123_automations.yaml

2512 lines
77 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

- id: als_auto_error_cleanup
alias: ALS - Auto Error Cleanup
description: Automatically clears resolved errors after 1 hour
mode: restart
trigger:
- trigger: time_pattern
hours: /1
condition:
- condition: state
entity_id: binary_sensor.als_system_error_detected
state: 'on'
action:
- repeat:
for_each:
- bedroom
- kitchen
- bathroom
- hallway
- laundry
- livingroom
sequence:
- variables:
room: '{{ repeat.item }}'
error_entity: input_text.als_error_{{ room }}
- if:
- condition: template
value_template: '{{ states(error_entity) not in ['''', ''unknown'', ''unavailable'']
}}'
- condition: template
value_template: '{% set room_name = room | replace(''livingroom'', ''living_room'')
%} {% if room == ''laundry'' %}{% set room_name = ''laundry_room'' %}{%
endif %} {% set target_sensor = ''sensor.'' ~ room_name ~ ''_target_brightness''
%} {{ states(target_sensor) not in [''unknown'', ''unavailable''] }}'
then:
- action: input_text.set_value
target:
entity_id: '{{ error_entity }}'
data:
value: ''
- id: als_teach_button_bridge
alias: ALS - Teach Button Bridge
mode: single
trigger:
- trigger: state
entity_id: input_button.als_teach_now
action:
- variables:
sel: '{{ states(''input_select.als_teaching_room'') }}'
room_key: "{% set map = {\n 'Bedroom':'bedroom',\n 'Kitchen':'kitchen',\n\
\ 'Living Room':'livingroom',\n 'Hallway':'hallway',\n 'Bathroom':'bathroom',\n\
\ 'Laundry':'laundry'\n} %} {{ map.get(sel, 'kitchen') }}"
brightness: '{{ states(''input_number.als_teaching_brightness'') | int(50) }}'
- action: pyscript.als_teach_room
data:
room: '{{ room_key }}'
brightness: '{{ brightness }}'
- action: input_text.set_value
target:
entity_id: input_text.als_last_teach_status
data:
value: Taught {{ room_key }} → {{ brightness }}% at {{ now().strftime('%H:%M:%S')
}}
- id: als_reload_pyscript_button
alias: ALS - Reload Pyscript Button
mode: single
trigger:
- trigger: state
entity_id: input_button.als_reload_pyscript
action:
- action: pyscript.reload
- action: input_text.set_value
target:
entity_id: input_text.als_last_teach_status
data:
value: Pyscript reloaded at {{ now().strftime('%H:%M:%S') }}
- id: als_run_test_engine_button
alias: ALS - Run Test Engine Now
mode: single
trigger:
- trigger: state
entity_id: input_button.als_run_test_engine
action:
- action: pyscript.parallel_test_run_now
- action: input_text.set_value
target:
entity_id: input_text.als_last_teach_status
data:
value: Test engine wrote values at {{ now().strftime('%H:%M:%S') }}
- id: home_state_evaluation
alias: Home State Evaluation
triggers:
- trigger: time_pattern
minutes: /5
- trigger: state
entity_id:
- binary_sensor.working_today
- device_tracker.iphone15
- device_tracker.work_iphone
conditions:
- condition: template
value_template: '{{ not is_state(''input_select.home_state'',''Night'') }}'
- condition: template
value_template: '{{ not is_state(''input_boolean.manual_home_state_override'',''on'')
}}'
- condition: template
value_template: '{{ states(''sensor.calculated_home_mode'') not in [''unknown'',''unavailable'']
}}'
actions:
- action: script.evaluate_home_mode
- id: apple_tv_night_mode_trigger
alias: Apple TV → Night Mode (20:0023:00 Only)
triggers:
- trigger: state
entity_id: media_player.bedroom
to:
- playing
- paused
- idle
from:
- 'off'
- unknown
- unavailable
- standby
for:
seconds: 8
conditions:
- condition: time
after: '20:00:00'
before: '23:00:00'
- condition: state
entity_id: binary_sensor.both_phones_home
state: 'on'
- condition: state
entity_id: input_boolean.apple_tv_bedroom_night_control
state: 'on'
- condition: template
value_template: '{{ not is_state(''input_select.home_state'',''Night'') }}'
actions:
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: Night
- id: night_mode_11pm_failsafe
alias: Night Mode 11 PM Failsafe
triggers:
- trigger: time
at: '23:00:00'
conditions:
- condition: state
entity_id: binary_sensor.both_phones_home
state: 'on'
- condition: template
value_template: '{{ not is_state(''input_select.home_state'',''Night'') }}'
actions:
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: Night
- id: learn_evening_transition_time
alias: Learn Evening Transition Time
triggers:
- trigger: state
entity_id: input_boolean.evening_mode_override
to: 'on'
actions:
- action: input_number.set_value
target:
entity_id: input_number.manual_evening_elevation_setting
data:
value: '{{ state_attr(''sun.sun'',''elevation'') }}'
- id: reset_evening_override_at_night
alias: Reset Evening Override at Night
triggers:
- trigger: state
entity_id: input_select.home_state
to: Night
conditions:
- condition: state
entity_id: input_boolean.evening_mode_override
state: 'on'
actions:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.evening_mode_override
- id: als_end_early_morning_mode
alias: ALS - Transition from Early Morning to Day
triggers:
- trigger: state
entity_id: binary_sensor.als_morning_transition_ready
to: 'on'
conditions:
- condition: state
entity_id: input_select.home_state
state: Early Morning
actions:
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: Day
- id: sun_elevation_history_tracker
alias: Sun Elevation History Tracker
description: Updates sun elevation history every 15 minutes for rate calculation
triggers:
- trigger: time_pattern
minutes: /15
actions:
- action: input_number.set_value
target:
entity_id: input_number.sun_elevation_history
data:
value: '{{ state_attr(''sun.sun'',''elevation'') | float(0) }}'
- id: enhanced_8am_failsafe
alias: Enhanced 8 AM Failsafe
description: Force Day mode at 8 AM if not already in Day or Away mode
triggers:
- trigger: time
at: 08:00:00
conditions:
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state:
- Day
- Away
- condition: state
entity_id: binary_sensor.both_phones_home
state: 'on'
actions:
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: Day
- action: logbook.log
data:
name: 8 AM Failsafe
message: 'WARNING: Forced Day mode - system was stuck in {{ trigger.from_state.state
}} mode'
- id: sleep_in_ramp_start
alias: Sleep-In Ramp - Start
description: Starts the sleep-in ramp with calculate-once smart duration
mode: single
triggers:
- trigger: state
entity_id: input_boolean.sleep_in_ramp_active
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.sleep_in_ramp_system_enable
state: 'on'
- condition: state
entity_id: input_select.home_state
state: Night
actions:
- variables:
current_sun: '{{ state_attr(''sun.sun'', ''elevation'') | float(0) }}'
sun_rate: '{{ states(''sensor.sun_elevation_rate'') | float(0.03) }}'
target_el: '{{ states(''input_number.current_day_threshold'') | float(10) }}'
rate_based_minutes: '{{ ((target_el - current_sun) / sun_rate) | round(0) if
sun_rate > 0.005 and sun_rate < 0.2 else 999 }}'
elevation_based_minutes: '{{ states(''sensor.minutes_to_day_mode_elevation'')
| int(999) }}'
motion_time: '{{ now() }}'
motion_hour: '{{ motion_time.hour }}'
motion_minute: '{{ motion_time.minute }}'
is_work_window: '{{ (motion_hour == 4 and motion_minute >= 50) or (motion_hour
== 5 and motion_minute == 0) }}'
work_base: '{{ states(''input_number.workday_ramp_base_duration'') | int(50)
}}'
off_base: '{{ states(''input_number.offday_ramp_base_duration'') | int(75) }}'
base_duration: '{{ work_base if is_work_window else off_base }}'
calculated_duration: "{% if 10 <= rate_based_minutes <= 180 %}\n {{ rate_based_minutes\
\ }}\n{% elif 10 <= elevation_based_minutes <= 240 %}\n {{ elevation_based_minutes\
\ }}\n{% else %}\n {% set season = states('sensor.current_season') %}\n \
\ {{ 60 if season == 'Winter' else 45 if season in ['Spring', 'Fall'] else\
\ 30 }}\n{% endif %}"
final_duration: "{% if calculated_duration < 30 %}\n {{ [calculated_duration\
\ * 0.8, 15] | max }}\n{% elif calculated_duration < 60 %}\n {{ [calculated_duration\
\ * 0.9, 25] | max }}\n{% else %}\n {% set season = states('sensor.current_season')\
\ %}\n {% set multiplier = 1.3 if season == 'Winter' else 0.8 if season ==\
\ 'Summer' else 1.0 %}\n {{ [base_duration * multiplier, 120] | min }}\n\
{% endif %}"
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.ramp_start_time
data:
datetime: '{{ now().strftime(''%Y-%m-%d %H:%M:%S'') }}'
- action: input_number.set_value
target:
entity_id: input_number.calculated_ramp_duration
data:
value: '{{ final_duration | round(0) }}'
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.ramp_calculated_end_time
data:
datetime: '{{ (now() + timedelta(minutes=final_duration|int)).strftime(''%Y-%m-%d
%H:%M:%S'') }}'
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.first_kitchen_motion_today
data:
datetime: '{{ now().strftime(''%Y-%m-%d %H:%M:%S'') }}'
- action: input_boolean.turn_on
target:
entity_id: input_boolean.daily_motion_lock
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: Early Morning
- id: sleep_in_ramp_complete
alias: Sleep-In Ramp - Complete
description: Completes the ramp when 100% progress is reached OR Day mode begins
mode: single
triggers:
- trigger: template
value_template: "{{ is_state('input_boolean.sleep_in_ramp_active', 'on') and\n\
\ states('sensor.sleep_in_ramp_progress') | float(0) >= 100 }}\n"
for:
seconds: 5
- trigger: state
entity_id: sensor.calculated_home_mode
to: Day
conditions:
- condition: state
entity_id: input_boolean.sleep_in_ramp_active
state: 'on'
actions:
- variables:
motion_time_str: '{{ states(''input_datetime.first_kitchen_motion_today'') }}'
is_non_work_day: "{% if motion_time_str not in ['unknown', 'unavailable', '']\
\ %}\n {% set motion_time = as_datetime(motion_time_str) %}\n {% set motion_hour\
\ = motion_time.hour %}\n {% set motion_minute = motion_time.minute %}\n\
\ {% set is_work_window = (motion_hour == 4 and motion_minute >= 50) or (motion_hour\
\ == 5 and motion_minute == 0) %}\n {{ not is_work_window }}\n{% else %}\n\
\ {{ not is_state('binary_sensor.working_today', 'on') }}\n{% endif %}"
- action: input_boolean.turn_off
target:
entity_id: input_boolean.sleep_in_ramp_active
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: Day
- if:
- condition: template
value_template: '{{ is_non_work_day }}'
- condition: state
entity_id: input_boolean.kitchen_wled_enable
state: 'on'
then:
- action: light.turn_off
target:
entity_id:
- light.sink_wled
- light.frig_strip
- action: logbook.log
data:
name: WLED Control
message: Kitchen WLED turned off at end of non-work day ramp
- action: logbook.log
data:
name: Sleep-In Ramp
message: 'Ramp complete - Triggered by: {{ trigger.platform }} | Non-work day:
{{ is_non_work_day }}'
- id: daily_motion_reset
alias: Daily Motion Reset
description: Resets daily motion lock and tracking at midnight
triggers:
- trigger: time
at: 00:00:00
actions:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.daily_motion_lock
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.first_kitchen_motion_today
data:
datetime: ''
- id: evening_temperature_ramp_start
alias: ALS - Evening Temperature Ramp Start
description: Starts the evening temperature ramp when Evening mode begins
mode: single
triggers:
- trigger: state
entity_id: input_select.home_state
to: Evening
conditions:
- condition: state
entity_id: input_boolean.enable_evening_temperature_ramp
state: 'on'
- condition: state
entity_id: input_select.home_state
state: Evening
actions:
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.evening_ramp_started
data:
datetime: '{{ now() }}'
- action: input_number.set_value
target:
entity_id: input_number.evening_ramp_start_temp
data:
value: '{{ states(''sensor.intelligent_temperature_master'') | int(4000) }}'
- id: evening_temperature_ramp_apply_existing
alias: ALS - Apply Ramp to Already-On Lights
description: Updates lights that are already on when Evening mode starts
mode: single
triggers:
- trigger: state
entity_id: input_select.home_state
to: Evening
conditions:
- condition: state
entity_id: input_boolean.enable_evening_temperature_ramp
state: 'on'
actions:
- delay:
seconds: 2
- if:
- condition: or
conditions:
- condition: state
entity_id: light.lamp_1
state: 'on'
- condition: state
entity_id: light.lamp_2
state: 'on'
then:
- action: light.turn_on
target:
entity_id:
- light.lamp_1
- light.lamp_2
data:
color_temp_kelvin: '{{ states(''sensor.evening_temperature_ramp'') | int(4000)
}}'
transition: 10
- if:
- condition: state
entity_id: light.closet
state: 'on'
then:
- action: light.turn_on
target:
entity_id: light.closet
data:
color_temp_kelvin: '{{ states(''sensor.evening_temperature_ramp'') | int(4000)
}}'
transition: 10
- id: evening_temperature_ramp_cleanup
alias: ALS - Evening Temperature Ramp Cleanup
description: Cleans up ramp data when Evening ends or at midnight reset
mode: restart
triggers:
- trigger: state
entity_id: input_select.home_state
from: Evening
id: mode_change
- trigger: time
at: 00:00:00
id: midnight_reset
conditions:
- condition: state
entity_id: input_boolean.enable_evening_temperature_ramp
state: 'on'
actions:
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.evening_ramp_started
data:
datetime: ''
- action: input_number.set_value
target:
entity_id: input_number.evening_ramp_start_temp
data:
value: 4000
- id: evening_smooth_temperature_ramp_start
alias: Evening - Start Smooth Temperature Ramp
description: Starts smooth temperature ramping for all evening lights
mode: single
triggers:
- trigger: state
entity_id: input_select.home_state
to: Evening
- trigger: state
entity_id: sensor.evening_temperature_ramp
id: sensor_change
conditions:
- condition: state
entity_id: input_select.home_state
state: Evening
- condition: state
entity_id: input_boolean.enable_evening_temperature_ramp
state: 'on'
- condition: or
conditions:
- condition: state
entity_id: light.lamp_1
state: 'on'
- condition: state
entity_id: light.lamp_2
state: 'on'
- condition: state
entity_id: light.closet
state: 'on'
actions:
- action: script.turn_on
target:
entity_id: script.evening_smooth_temperature_ramp
- id: evening_smooth_temperature_ramp_stop
alias: Evening - Stop Smooth Temperature Ramp
description: Stops smooth temperature ramping when Evening ends
mode: restart
triggers:
- trigger: state
entity_id: input_select.home_state
from: Evening
actions:
- action: script.turn_off
target:
entity_id: script.evening_smooth_temperature_ramp
- action: logbook.log
data:
name: Evening Automation
message: ✅ Evening smooth temperature ramp stopped - home state changed from
Evening
- id: kitchen_pyscript_morning_ramp_trigger
alias: Kitchen - Morning Ramp PyScript Trigger (motion)
mode: single
trigger:
- trigger: state
entity_id:
- binary_sensor.aqara_motion_sensor_p1_occupancy
- binary_sensor.kitchen_iris_frig_occupancy
to: 'on'
condition:
- condition: state
entity_id: input_boolean.sleep_in_ramp_system_enable
state: 'on'
- condition: state
entity_id: input_select.home_state
state: Night
action:
- action: pyscript.morning_ramp_first_motion
data:
sensor: '{{ trigger.entity_id }}'
- id: livingroom_auto_lights_main
alias: Living Room - Auto Control
description: Controls living room lighting based on home state and weather
mode: restart
triggers:
- trigger: state
entity_id: input_select.home_state
- trigger: state
entity_id: sensor.living_room_target_brightness
conditions:
- condition: state
entity_id: input_boolean.livingroom_auto_lights_enable
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
actions:
- variables:
target_brightness: '{{ states(''sensor.living_room_target_brightness'') | int(0)
}}'
target_temperature: '{{ states(''sensor.evening_temperature_ramp'') | int(3000)
}}'
- choose:
- conditions:
- condition: template
value_template: '{{ target_brightness > 0 }}'
sequence:
- action: light.turn_on
target:
entity_id:
- light.lamp_1
- light.lamp_2
data:
brightness_pct: '{{ target_brightness }}'
color_temp_kelvin: '{{ target_temperature }}'
- conditions:
- condition: template
value_template: '{{ target_brightness == 0 }}'
sequence:
- action: light.turn_off
target:
entity_id:
- light.lamp_1
- light.lamp_2
data:
transition: 5
- id: living_room_weather_transition
alias: Living Room - Smooth Weather Transition
description: Slowly adjusts brightness when weather conditions change and lights
are already on.
mode: restart
triggers:
- trigger: state
entity_id: sensor.living_room_target_brightness
conditions:
- condition: state
entity_id: input_boolean.enable_weather_transitions
state: 'on'
- condition: or
conditions:
- condition: state
entity_id: light.lamp_1
state: 'on'
- condition: state
entity_id: light.lamp_2
state: 'on'
- condition: state
entity_id: input_select.home_state
state: Day
- condition: template
value_template: '{{ (trigger.to_state.state | int(0) - trigger.from_state.state
| int(0)) | abs > 10 }}'
actions:
- variables:
transition_seconds: '{{ states(''input_number.weather_transition_duration_minutes'')
| int(5) * 60 }}'
- action: light.turn_on
target:
entity_id:
- light.lamp_1
- light.lamp_2
data:
brightness_pct: '{{ trigger.to_state.state | int(0) }}'
transition: '{{ transition_seconds }}'
- id: living_room_evening_ramp_control
alias: Living Room - Evening Ramp Control
description: Starts or stops the evening lighting ramp based on home state.
mode: single
triggers:
- trigger: state
entity_id: input_select.home_state
to: Evening
id: start
- trigger: state
entity_id: input_select.home_state
from: Evening
id: stop
conditions:
- condition: state
entity_id: input_boolean.living_room_evening_ramp_enabled
state: 'on'
actions:
- choose:
- conditions:
- condition: trigger
id: start
sequence:
- action: script.turn_on
target:
entity_id: script.als_living_room_evening_ramp
- conditions:
- condition: trigger
id: stop
sequence:
- action: script.turn_off
target:
entity_id: script.als_living_room_evening_ramp
- id: laundry_motion_lights
alias: Laundry Room - Motion Lights
description: Motion-triggered lighting with adaptive/intelligent brightness control
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.laundry_iris_occupancy
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.laundry_motion_automation
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
- condition: template
value_template: "{{ trigger.from_state is not none and\n trigger.from_state.state\
\ not in ['unknown', 'unavailable'] }}\n"
actions:
- action: light.turn_on
target:
entity_id: light.laundry_room
data:
brightness_pct: '{{ states(''sensor.laundry_room_target_brightness'') | int
}}'
- id: laundry_motion_off
alias: Laundry Room - Motion Off
description: Turns off laundry lights after motion timeout
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.laundry_iris_occupancy
to: 'off'
for:
seconds: '{{ states(''input_number.laundry_motion_timeout'') | int(30) }}'
conditions:
- condition: state
entity_id: input_boolean.laundry_motion_automation
state: 'on'
- condition: state
entity_id: light.laundry_room
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
actions:
- action: light.turn_off
target:
entity_id: light.laundry_room
data:
transition: 3
- id: laundry_mode_transitions
alias: Laundry Room - Mode Transitions
description: Handles lighting changes when home mode changes
mode: restart
triggers:
- trigger: state
entity_id: input_select.home_state
actions:
- choose:
- conditions: '{{ trigger.to_state.state == ''Away'' }}'
sequence:
- action: light.turn_off
target:
entity_id: light.laundry_room
- conditions: '{{ trigger.to_state.state == ''Night'' and is_state(''light.laundry_room'',
''on'') }}'
sequence:
- action: light.turn_on
target:
entity_id: light.laundry_room
data:
brightness_pct: '{{ states(''sensor.laundry_room_target_brightness'') |
int }}'
transition: 5
- id: hallway_motion_lights
alias: Hallway - Motion Lights
description: Motion-triggered lighting with adaptive/intelligent brightness control
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.hallway_iris_occupancy
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.hallway_motion_automation
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
- condition: template
value_template: "{{ trigger.from_state is not none and\n trigger.from_state.state\
\ not in ['unknown', 'unavailable'] }}\n"
actions:
- action: light.turn_on
target:
entity_id: light.hallway
data:
brightness_pct: '{{ states(''sensor.hallway_target_brightness'') | int }}'
- id: hallway_motion_off
alias: Hallway - Motion Off
description: Turns off hallway lights after motion timeout
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.hallway_iris_occupancy
to: 'off'
for:
seconds: '{{ states(''input_number.hallway_motion_timeout'') | int(30) }}'
conditions:
- condition: state
entity_id: input_boolean.hallway_motion_automation
state: 'on'
- condition: state
entity_id: light.hallway
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
actions:
- action: light.turn_off
target:
entity_id: light.hallway
data:
transition: 3
- id: bedroom_motion_lights
alias: Bedroom - Motion Lights
description: 'Primary automation: Turns on the closet light when motion is detected.'
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.bedroom_x_occupancy
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.bedroom_motion_automation
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
- condition: template
value_template: "{{ trigger.from_state is not none and\n trigger.from_state.state\
\ not in ['unknown', 'unavailable'] }}\n"
actions:
- action: light.turn_on
target:
entity_id: light.closet
data:
brightness_pct: '{{ states(''sensor.bedroom_target_brightness'') | int }}'
color_temp_kelvin: '{{ state_attr(''sensor.bedroom_target_brightness'', ''temperature'')
| int(3000) }}'
- id: bedroom_motion_off
alias: Bedroom - Motion Off
description: Turns off closet light after motion timeout.
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.bedroom_x_occupancy
to: 'off'
for:
seconds: '{{ states(''input_number.bedroom_motion_timeout'') | int(30) }}'
conditions:
- condition: state
entity_id: input_boolean.bedroom_motion_automation
state: 'on'
- condition: state
entity_id: light.closet
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
actions:
- action: light.turn_off
target:
entity_id: light.closet
data:
transition: 2
- id: bedroom_mode_transitions
alias: Bedroom - Mode Transitions
description: Handles lighting changes when home mode changes (e.g., to Away or Night).
mode: restart
triggers:
- trigger: state
entity_id: input_select.home_state
actions:
- choose:
- conditions: '{{ trigger.to_state.state == ''Away'' }}'
sequence:
- action: light.turn_off
target:
entity_id: light.closet
- conditions: '{{ trigger.to_state.state == ''Night'' and is_state(''light.closet'',
''on'') }}'
sequence:
- action: light.turn_on
target:
entity_id: light.closet
data:
brightness_pct: '{{ states(''sensor.bedroom_target_brightness'') | int }}'
color_temp_kelvin: '{{ state_attr(''sensor.bedroom_target_brightness'',
''temperature'') | int(3000) }}'
- id: bathroom_motion_on
alias: Bathroom - Motion Detected
mode: single
triggers:
- trigger: state
entity_id: binary_sensor.bathroom_motion_combined
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.bathroom_motion_automation
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
- condition: template
value_template: "{{ trigger.from_state is not none and\n trigger.from_state.state\
\ not in ['unknown', 'unavailable'] }}\n"
actions:
- action: light.turn_on
target:
entity_id: light.bathroom_2_main_lights
data:
brightness_pct: '{{ states(''sensor.bathroom_target_brightness'') | int }}'
- id: bathroom_door_closes
alias: Bathroom - Door Closes
description: When door closes, set lights to 100% and enable hold mode
mode: single
triggers:
- trigger: state
entity_id: binary_sensor.bathroom_contact_contact
to: 'off'
for:
seconds: 2
conditions:
- condition: state
entity_id: input_boolean.bathroom_motion_automation
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
actions:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.bathroom_100_percent_hold
- action: light.turn_on
target:
entity_id: light.bathroom_2_main_lights
data:
brightness_pct: 100
- id: bathroom_door_opens
alias: Bathroom - Door Opens
description: When door opens, disable hold mode and transition lights back to smart
brightness
mode: single
triggers:
- trigger: state
entity_id: binary_sensor.bathroom_contact_contact
to: 'on'
for:
seconds: 2
conditions:
- condition: state
entity_id: input_boolean.bathroom_motion_automation
state: 'on'
- condition: state
entity_id: light.bathroom_2_main_lights
state: 'on'
- condition: not
conditions:
- condition: state
entity_id: input_select.home_state
state: Away
actions:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.bathroom_100_percent_hold
- action: light.turn_on
target:
entity_id: light.bathroom_2_main_lights
data:
brightness_pct: '{{ states(''sensor.bathroom_target_brightness'') | int }}'
transition: 5
- id: bathroom_motion_clear
alias: Bathroom - Motion Clears
description: Turn off lights after 30s of no motion, but ONLY if door is open
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.bathroom_motion_combined
to: 'off'
for:
seconds: 30
conditions:
- condition: state
entity_id: input_boolean.bathroom_motion_automation
state: 'on'
- condition: state
entity_id: light.bathroom_2_main_lights
state: 'on'
- condition: state
entity_id: binary_sensor.bathroom_contact_contact
state: 'on'
actions:
- action: light.turn_off
target:
entity_id: light.bathroom_2_main_lights
data:
transition: 3
- id: bathroom_hold_mode_timeout
alias: Bathroom - Hold Mode Timeout Failsafe
description: Turns off 100% hold mode after a set duration to prevent it getting
stuck
mode: single
triggers:
- trigger: state
entity_id: input_boolean.bathroom_100_percent_hold
to: 'on'
for:
minutes: '{{ states(''input_number.bathroom_hold_timeout'') | int(30) }}'
conditions:
- condition: state
entity_id: input_boolean.bathroom_100_percent_hold
state: 'on'
actions:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.bathroom_100_percent_hold
- action: logbook.log
data:
name: Bathroom Hold Mode
message: ⏰ Hold mode timed out and was automatically disabled.
- id: als_system_error_capture
alias: ALS - System Error Capture
description: Captures system log errors and classifies them by room/system
mode: queued
max_exceeded: silent
triggers:
- trigger: event
event_type: system_log_event
event_data:
level: ERROR
- trigger: event
event_type: system_log_event
event_data:
level: CRITICAL
- trigger: event
event_type: system_log_event
event_data:
level: WARNING
conditions:
- condition: state
entity_id: input_boolean.als_diagnostics_enabled
state: 'on'
actions:
- action: pyscript.process_als_error
data:
message: '{{ trigger.event.data.message }}'
level: '{{ trigger.event.data.level }}'
source: '{{ trigger.event.data.name | default(''Unknown'') }}'
- id: routine_timing_capture
alias: Routine Timing - Completion Detection
description: Detects routine completion when living room lights are turned off during
Early Morning mode
mode: single
triggers:
- trigger: state
entity_id:
- light.lamp_1
- light.lamp_2
to: 'off'
for:
seconds: 5
conditions:
- condition: state
entity_id: input_select.home_state
state: Early Morning
- condition: state
entity_id: light.lamp_1
state: 'off'
- condition: state
entity_id: light.lamp_2
state: 'off'
- condition: template
value_template: "{{ (now() - states.light.lamp_1.last_changed).total_seconds()\
\ > 30 and\n (now() - states.light.lamp_2.last_changed).total_seconds() >\
\ 30 }}\n"
actions:
- variables:
completion_time: '{{ now().strftime(''%H:%M:%S'') }}'
day_type: '{{ ''work'' if is_state(''binary_sensor.workday_sensor'', ''on'')
else ''weekend'' }}
'
- action: pyscript.store_routine_timing
data:
completion_time_str: '{{ completion_time }}'
confidence_pct: 90.0
- action: logbook.log
data:
name: Routine Learning
message: 📊 Captured routine completion at {{ completion_time }} ({{ day_type
}} day)
- if:
- condition: state
entity_id: input_boolean.als_verbose_logging
state: 'on'
then:
- action: notify.persistent_notification
data:
title: 🎯 Routine Learning
message: Learned routine completion at {{ completion_time }} on {{ day_type
}} day
data:
tag: routine_learning
- id: manual_routine_completion
alias: Routine Timing - Manual Completion
description: Manually trigger routine completion capture
triggers:
- trigger: state
entity_id: input_boolean.manual_routine_capture
to: 'on'
conditions:
- condition: state
entity_id: input_select.home_state
state: Early Morning
actions:
- variables:
completion_time: '{{ now().strftime(''%H:%M:%S'') }}'
- action: pyscript.store_routine_timing
data:
completion_time_str: '{{ completion_time }}'
confidence_pct: 75.0
- action: logbook.log
data:
name: Routine Learning
message: 📊 Manual routine completion captured at {{ completion_time }}
- action: input_boolean.turn_off
target:
entity_id: input_boolean.manual_routine_capture
- id: health_pills_auto_refresh
alias: Health Pills Auto Refresh
description: Automatically refresh health pills when error feeds are updated
mode: queued
max_exceeded: silent
triggers:
- trigger: state
entity_id:
- input_text.als_error_feed_kitchen
- input_text.als_error_feed_bedroom
- input_text.als_error_feed_livingroom
- input_text.als_error_feed_bathroom
- input_text.als_error_feed_hallway
- input_text.als_error_feed_laundry
- trigger: state
entity_id:
- input_text.als_error_kitchen
- input_text.als_error_bedroom
- input_text.als_error_livingroom
- input_text.als_error_bathroom
- input_text.als_error_hallway
- input_text.als_error_laundry
conditions:
- condition: template
value_template: '{{ trigger.from_state.state != trigger.to_state.state }}'
actions:
- delay: 00:00:01
- action: pyscript.refresh_all_health_calculations
data: {}
- id: periodic_health_validation
alias: Periodic Health System Validation
description: Run health system tests every 6 hours
triggers:
- trigger: time_pattern
hours: /6
conditions:
- condition: state
entity_id: input_boolean.health_monitoring_auto_test
state: 'on'
actions:
- action: script.verify_health_system_accuracy
data: {}
- id: smart_health_status_notifications
alias: Smart Health Status Notifications
description: Context-aware notifications for health status changes with cooldown
management
mode: single
max_exceeded: silent
triggers:
- trigger: state
entity_id: sensor.global_health_status
for:
seconds: 30
conditions:
- condition: state
entity_id: input_boolean.smart_notifications_enabled
state: 'on'
- condition: template
value_template: '{{ trigger.from_state.state != trigger.to_state.state }}'
- condition: template
value_template: '{{ trigger.from_state.state not in [''unknown'', ''unavailable'']
}}'
actions:
- action: pyscript.handle_health_status_notification
data:
current_status: '{{ trigger.to_state.state }}'
previous_status: '{{ trigger.from_state.state }}'
status_attributes: "{{\n {\n 'status_text': state_attr('sensor.global_health_status',\
\ 'status_text'),\n 'affected_rooms': state_attr('sensor.global_health_status',\
\ 'affected_rooms'),\n 'total_error_count': state_attr('sensor.global_health_status',\
\ 'total_error_count'),\n 'summary': state_attr('sensor.global_health_status',\
\ 'summary')\n } | to_json\n}}"
- id: test_smart_notifications
alias: Test Smart Notifications
description: Manual trigger to test notification system
mode: single
triggers:
- trigger: state
entity_id: input_boolean.notification_debug_mode
from: 'off'
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.smart_notifications_enabled
state: 'on'
actions:
- action: pyscript.test_notification_system
data: {}
- delay: 00:00:05
- action: input_boolean.turn_off
target:
entity_id: input_boolean.notification_debug_mode
- id: update_quiet_hours_status
alias: Update Quiet Hours Status
description: Track whether we're currently in quiet hours
mode: single
triggers:
- trigger: time_pattern
minutes: '*'
- trigger: state
entity_id:
- input_datetime.quiet_hours_start
- input_datetime.quiet_hours_end
- input_boolean.quiet_hours_enabled
actions:
- action: pyscript.update_quiet_hours_status
data: {}
- id: diagnostic_dashboard_auto_refresh
alias: Diagnostic Dashboard Auto Refresh
description: Automatically refresh dashboard when key data changes
mode: queued
max_exceeded: silent
triggers:
- trigger: state
entity_id:
- sensor.global_health_status
- input_text.als_learning_status
- input_text.learning_performance_metrics
- trigger: time_pattern
minutes: /5
conditions:
- condition: state
entity_id: input_boolean.diagnostic_dashboard_enabled
state: 'on'
actions:
- delay: 00:00:01
- action: script.refresh_dashboard_data
data: {}
- id: learning_status_monitor
alias: Learning Status Monitor
description: Monitor and update ALS learning system status
mode: restart
triggers:
- trigger: time_pattern
minutes: /2
conditions:
- condition: state
entity_id: input_boolean.als_diagnostics_enabled
state: 'on'
actions:
- action: pyscript.update_learning_system_status
data: {}
- action: pyscript.update_learning_performance_metrics
data: {}
- id: health_status_change_handler
alias: Health Status Change Handler
description: Handle health status changes with smart notifications
mode: queued
triggers:
- trigger: state
entity_id: sensor.global_health_status
from:
- 🟩
- 🟨
- 🟥
to:
- 🟩
- 🟨
- 🟥
conditions:
- condition: template
value_template: '{{ trigger.from_state.state != trigger.to_state.state }}'
- condition: state
entity_id: input_boolean.smart_notifications_enabled
state: 'on'
actions:
- delay: 00:00:30
- action: pyscript.handle_health_status_notification
data:
current_status: '{{ trigger.to_state.state }}'
previous_status: '{{ trigger.from_state.state }}'
status_attributes: '{{ trigger.to_state.attributes | to_json }}'
- id: quiet_hours_status_updater
alias: Quiet Hours Status Updater
description: Update quiet hours suppression status
mode: restart
triggers:
- trigger: time_pattern
minutes: /5
- trigger: state
entity_id:
- input_boolean.quiet_hours_enabled
- input_datetime.quiet_hours_start
- input_datetime.quiet_hours_end
actions:
- action: pyscript.update_quiet_hours_status
data: {}
- id: diagnostic_system_maintenance
alias: Diagnostic System Maintenance
description: Periodic maintenance and cleanup for diagnostic system
triggers:
- trigger: time_pattern
hours: /4
conditions:
- condition: state
entity_id: input_boolean.als_diagnostics_enabled
state: 'on'
actions:
- action: pyscript.perform_diagnostic_maintenance
data: {}
- action: script.refresh_dashboard_data
data: {}
- id: diagnostic_config_change_handler
alias: Diagnostic Configuration Change Handler
description: Handle configuration changes and refresh system
mode: restart
triggers:
- trigger: state
entity_id:
- input_number.error_retention_days
- input_number.max_errors_per_room
- input_number.health_check_interval
- input_number.error_threshold_warning
- input_number.error_threshold_critical
actions:
- delay: 00:00:02
- action: script.refresh_dashboard_data
data: {}
- action: logbook.log
data:
name: ALS Diagnostics
message: ⚙️ Configuration updated - dashboard refreshed
- id: maintenance_periodic_health_check
alias: 'Maintenance: Periodic Health Check'
description: Run health validation every 15 minutes
trigger:
- platform: time_pattern
minutes: /15
condition:
- condition: state
entity_id: input_boolean.maintenance_auto_cleanup_enabled
state: 'on'
action:
- service: pyscript.maintenance_health_check
data:
debug_mode: '{{ is_state(''input_boolean.maintenance_debug_mode'', ''on'') }}'
- service: logbook.log
data:
name: ALS Maintenance
message: Periodic health check completed
- id: maintenance_periodic_cleanup
alias: 'Maintenance: Automated Cleanup'
description: Run automated cleanup based on configured interval
trigger:
- platform: time_pattern
hours: /1
condition:
- condition: state
entity_id: input_boolean.maintenance_auto_cleanup_enabled
state: 'on'
- condition: template
value_template: "{% set last_cleanup = states('input_datetime.maintenance_last_cleanup_time')\
\ %} {% set interval_hours = states('input_number.maintenance_cleanup_interval_hours')\
\ | int %} {% if last_cleanup == 'unknown' %}\n true\n{% else %}\n {% set\
\ last_time = strptime(last_cleanup, '%Y-%m-%d %H:%M:%S') %}\n {% set now =\
\ now() %}\n {% set hours_since = (now - last_time).total_seconds() / 3600\
\ %}\n {{ hours_since >= interval_hours }}\n{% endif %}\n"
action:
- service: pyscript.maintenance_automated_cleanup
data:
retention_days: '{{ states(''input_number.maintenance_error_retention_days'')
| int }}'
max_entries: '{{ states(''input_number.maintenance_max_error_entries'') | int
}}'
debug_mode: '{{ is_state(''input_boolean.maintenance_debug_mode'', ''on'') }}'
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.maintenance_last_cleanup_time
data:
datetime: '{{ now() }}'
- service: counter.increment
target:
entity_id: counter.maintenance_cleanup_runs
- service: logbook.log
data:
name: ALS Maintenance
message: Automated cleanup completed
- id: maintenance_performance_alert
alias: 'Maintenance: Performance Alert'
description: Alert when system performance is degraded
trigger:
- platform: numeric_state
entity_id: sensor.maintenance_system_health
below: 50
for:
minutes: 5
condition:
- condition: state
entity_id: input_boolean.maintenance_performance_monitoring
state: 'on'
action:
- service: persistent_notification.create
data:
title: ALS System Performance Warning
message: 'System health is at {{ states(''sensor.maintenance_system_health'')
}}%. Consider running manual cleanup or adjusting retention settings.
'
notification_id: als_performance_warning
- service: logbook.log
data:
name: ALS Maintenance
message: 'Performance alert triggered - Health: {{ states(''sensor.maintenance_system_health'')
}}%'
entity_id: sensor.maintenance_system_health
- id: maintenance_data_buildup_prevention
alias: 'Maintenance: Data Buildup Prevention'
description: Prevent excessive data buildup
trigger:
- platform: numeric_state
entity_id: sensor.als_total_error_count
above: '{{ states(''input_number.maintenance_max_error_entries'') | int }}'
condition:
- condition: state
entity_id: input_boolean.maintenance_auto_cleanup_enabled
state: 'on'
action:
- service: pyscript.maintenance_emergency_cleanup
data:
target_count: '{{ (states(''input_number.maintenance_max_error_entries'') |
int * 0.8) | int }}'
debug_mode: '{{ is_state(''input_boolean.maintenance_debug_mode'', ''on'') }}'
- service: persistent_notification.create
data:
title: ALS Emergency Cleanup Triggered
message: 'Error count exceeded limit. Emergency cleanup performed. Reduced to
{{ (states(''input_number.maintenance_max_error_entries'') | int * 0.8) |
int }} entries.
'
notification_id: als_emergency_cleanup
- service: logbook.log
data:
name: ALS Maintenance
message: Emergency cleanup triggered - Error count exceeded limit
- id: unlock_door_on_arrival
alias: Unlock door when either iPhone arrives home
description: Auto unlock front door when either phone enters home zone
triggers:
- trigger: zone
entity_id: device_tracker.iphone15
zone: zone.home
event: enter
- trigger: zone
entity_id: device_tracker.work_iphone
zone: zone.home
event: enter
conditions:
- condition: state
entity_id: input_boolean.smart_lock_auto_unlock
state: 'on'
actions:
- action: lock.unlock
target:
entity_id: lock.aqara_smart_lock_u100_lock
- action: notify.mobile_app_iphone15
data:
message: The front door was unlocked.
- action: notify.mobile_app_rrvqklh23h_iphone
data:
message: The front door was unlocked.
mode: single
- id: smart_switch_1_manual_amber_activate
alias: Smart Switch 1 - Manual Amber Activate
triggers:
- trigger: state
entity_id: input_boolean.smart_switch_1_manual_amber_trigger
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.smart_switch_1_amber_mode_enable
state: 'on'
actions:
- action: script.smart_switch_1_amber_sequence
- action: input_boolean.turn_off
target:
entity_id: input_boolean.smart_switch_1_manual_amber_trigger
- action: logbook.log
data:
name: Smart Switch 1 Amber
message: Manual amber mode activated
entity_id: light.smart_switch_1
- id: smart_switch_2_manual_amber_activate
alias: Smart Switch 2 - Manual Amber Activate
triggers:
- trigger: state
entity_id: input_boolean.smart_switch_2_manual_amber_trigger
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.smart_switch_2_amber_mode_enable
state: 'on'
actions:
- action: script.smart_switch_2_amber_sequence
- action: input_boolean.turn_off
target:
entity_id: input_boolean.smart_switch_2_manual_amber_trigger
- action: logbook.log
data:
name: Smart Switch 2 Amber
message: Manual amber mode activated
entity_id: light.smart_switch_2
- id: smart_switch_1_amber_button
alias: Smart Switch 1 - Amber Button
triggers:
- trigger: state
entity_id: input_button.smart_switch_1_activate_amber
actions:
- action: script.smart_switch_1_amber_sequence
- id: smart_switch_1_normal_button
alias: Smart Switch 1 - Normal Button
triggers:
- trigger: state
entity_id: input_button.smart_switch_1_normal_mode
actions:
- action: light.turn_on
target:
entity_id: light.smart_switch_1
data:
brightness_pct: 80
color_temp_kelvin: 4000
- id: smart_switch_2_amber_button
alias: Smart Switch 2 - Amber Button
triggers:
- trigger: state
entity_id: input_button.smart_switch_2_activate_amber
actions:
- action: script.smart_switch_2_amber_sequence
- id: smart_switch_2_normal_button
alias: Smart Switch 2 - Normal Button
triggers:
- trigger: state
entity_id: input_button.smart_switch_2_normal_mode
actions:
- action: light.turn_on
target:
entity_id: light.smart_switch_2
data:
brightness_pct: 80
color_temp_kelvin: 4000
- id: both_switches_amber_button
alias: Both Switches - Amber Button
triggers:
- trigger: state
entity_id: input_button.both_switches_amber
actions:
- action: script.both_switches_amber_mode
- id: both_switches_normal_button
alias: Both Switches - Normal Button
triggers:
- trigger: state
entity_id: input_button.both_switches_normal
actions:
- action: light.turn_on
target:
entity_id:
- light.smart_switch_1
- light.smart_switch_2
data:
brightness_pct: 80
color_temp_kelvin: 4000
- id: als_auto_error_cleanup
alias: ALS - Auto Error Cleanup
description: Automatically clears resolved errors after 1 hour
mode: restart
trigger:
- trigger: time_pattern
hours: /1
condition:
- condition: state
entity_id: binary_sensor.als_system_error_detected
state: 'on'
action:
- repeat:
for_each:
- bedroom
- kitchen
- bathroom
- hallway
- laundry
- livingroom
sequence:
- variables:
room: '{{ repeat.item }}'
error_entity: input_text.als_error_{{ room }}
- if:
- condition: template
value_template: '{{ states(error_entity) not in ['''', ''unknown'', ''unavailable'']
}}'
- condition: template
value_template: '{% set room_name = room | replace(''livingroom'', ''living_room'')
%} {% if room == ''laundry'' %}{% set room_name = ''laundry_room'' %}{%
endif %} {% set target_sensor = ''sensor.'' ~ room_name ~ ''_target_brightness''
%} {{ states(target_sensor) not in [''unknown'', ''unavailable''] }}'
then:
- action: input_text.set_value
target:
entity_id: '{{ error_entity }}'
data:
value: ''
- id: als_teach_button_bridge
alias: ALS - Teach Button Bridge
mode: single
trigger:
- trigger: state
entity_id: input_button.als_teach_now
action:
- variables:
sel: '{{ states(''input_select.als_teaching_room'') }}'
room_key: "{% set map = {\n 'Bedroom':'bedroom',\n 'Kitchen':'kitchen',\n\
\ 'Living Room':'livingroom',\n 'Hallway':'hallway',\n 'Bathroom':'bathroom',\n\
\ 'Laundry':'laundry'\n} %} {{ map.get(sel, 'kitchen') }}"
brightness: '{{ states(''input_number.als_teaching_brightness'') | int(50) }}'
- action: pyscript.als_teach_room
data:
room: '{{ room_key }}'
brightness: '{{ brightness }}'
- action: input_text.set_value
target:
entity_id: input_text.als_last_teach_status
data:
value: Taught {{ room_key }} → {{ brightness }}% at {{ now().strftime('%H:%M:%S')
}}
- id: als_reload_pyscript_button
alias: ALS - Reload Pyscript Button
mode: single
trigger:
- trigger: state
entity_id: input_button.als_reload_pyscript
action:
- action: pyscript.reload
- action: input_text.set_value
target:
entity_id: input_text.als_last_teach_status
data:
value: Pyscript reloaded at {{ now().strftime('%H:%M:%S') }}
- id: als_run_test_engine_button
alias: ALS - Run Test Engine Now
mode: single
trigger:
- trigger: state
entity_id: input_button.als_run_test_engine
action:
- action: pyscript.parallel_test_run_now
- action: input_text.set_value
target:
entity_id: input_text.als_last_teach_status
data:
value: Test engine wrote values at {{ now().strftime('%H:%M:%S') }}
- id: pyscript_to_home_state_ui_authoritative
alias: 'Home State (Authoritative): Controller → UI'
mode: restart
trigger:
- trigger: state
entity_id: pyscript.home_state
condition:
- condition: template
value_template: '{{ states(''pyscript.home_state'') != states(''input_select.home_state'')
}}'
action:
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: '{{ states(''pyscript.home_state'') }}'
- id: home_state_ui_to_pyscript_override_only
alias: 'Home State (Override Only): UI → Controller'
mode: single
trigger:
- trigger: state
entity_id: input_select.home_state
condition:
- condition: state
entity_id: input_boolean.manual_home_state_override
state: 'on'
- condition: template
value_template: '{{ states(''input_select.home_state'') != states(''pyscript.home_state'')
}}'
action:
- action: pyscript.set_home_mode
data:
mode: '{{ states(''input_select.home_state'') }}'
- id: home_state_ui_guard_override_off_strict
alias: 'Home State Guard: Snap UI Back (Override OFF)'
mode: restart
trigger:
- trigger: state
entity_id: input_select.home_state
condition:
- condition: state
entity_id: input_boolean.manual_home_state_override
state: 'off'
- condition: template
value_template: '{{ states(''input_select.home_state'') != states(''pyscript.home_state'')
}}'
action:
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: '{{ states(''pyscript.home_state'') }}'
- id: home_state_reconciler_authoritative
alias: Home State Reconciler (Controller Wins)
mode: restart
trigger:
- trigger: state
entity_id: binary_sensor.home_state_diverged
to: 'on'
condition:
- condition: state
entity_id: input_boolean.manual_home_state_override
state: 'off'
action:
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: '{{ states(''pyscript.home_state'') }}'
- id: home_state_startup_sync
alias: 'Home State Startup Sync: Controller → UI'
mode: single
trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: pyscript_reload
action:
- choose:
- conditions:
- condition: template
value_template: '{{ states(''pyscript.home_state'') not in [''unknown'',''unavailable'','''']
}}'
sequence:
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: '{{ states(''pyscript.home_state'') }}'
- id: sleep_in_ramp_start
alias: Sleep-In Ramp - Start
description: Starts the sleep-in ramp with calculate-once smart duration
mode: single
triggers:
- trigger: state
entity_id: input_boolean.sleep_in_ramp_active
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.sleep_in_ramp_system_enable
state: 'on'
- condition: state
entity_id: input_select.home_state
state: Night
actions:
- variables:
current_sun: '{{ state_attr(''sun.sun'', ''elevation'') | float(0) }}'
sun_rate: '{{ states(''sensor.sun_elevation_rate'') | float(0.03) }}'
target_el: '{{ states(''input_number.current_day_threshold'') | float(10) }}'
rate_based_minutes: '{{ ((target_el - current_sun) / sun_rate) | round(0) if
sun_rate > 0.005 and sun_rate < 0.2 else 999 }}'
elevation_based_minutes: '{{ states(''sensor.minutes_to_day_mode_elevation'')
| int(999) }}'
motion_time: '{{ now() }}'
motion_hour: '{{ motion_time.hour }}'
motion_minute: '{{ motion_time.minute }}'
is_work_window: '{{ (motion_hour == 4 and motion_minute >= 50) or (motion_hour
== 5 and motion_minute == 0) }}'
work_base: '{{ states(''input_number.workday_ramp_base_duration'') | int(50)
}}'
off_base: '{{ states(''input_number.offday_ramp_base_duration'') | int(75) }}'
base_duration: '{{ work_base if is_work_window else off_base }}'
calculated_duration: "{% if 10 <= rate_based_minutes <= 180 %}\n {{ rate_based_minutes\
\ }}\n{% elif 10 <= elevation_based_minutes <= 240 %}\n {{ elevation_based_minutes\
\ }}\n{% else %}\n {% set season = states('sensor.current_season') %}\n \
\ {{ 60 if season == 'Winter' else 45 if season in ['Spring', 'Fall'] else\
\ 30 }}\n{% endif %}"
final_duration: "{% if calculated_duration < 30 %}\n {{ [calculated_duration\
\ * 0.8, 15] | max }}\n{% elif calculated_duration < 60 %}\n {{ [calculated_duration\
\ * 0.9, 25] | max }}\n{% else %}\n {% set season = states('sensor.current_season')\
\ %}\n {% set multiplier = 1.3 if season == 'Winter' else 0.8 if season ==\
\ 'Summer' else 1.0 %}\n {{ [base_duration * multiplier, 120] | min }}\n\
{% endif %}"
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.ramp_start_time
data:
datetime: '{{ now().strftime(''%Y-%m-%d %H:%M:%S'') }}'
- action: input_number.set_value
target:
entity_id: input_number.calculated_ramp_duration
data:
value: '{{ final_duration | round(0) }}'
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.ramp_calculated_end_time
data:
datetime: '{{ (now() + timedelta(minutes=final_duration|int)).strftime(''%Y-%m-%d
%H:%M:%S'') }}'
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.first_kitchen_motion_today
data:
datetime: '{{ now().strftime(''%Y-%m-%d %H:%M:%S'') }}'
- action: input_boolean.turn_on
target:
entity_id: input_boolean.daily_motion_lock
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: Early Morning
- id: sleep_in_ramp_complete
alias: Sleep-In Ramp - Complete
description: Completes the ramp when 100% progress is reached OR Day mode begins
mode: single
triggers:
- trigger: template
value_template: "{{ is_state('input_boolean.sleep_in_ramp_active', 'on') and\n\
\ states('sensor.sleep_in_ramp_progress') | float(0) >= 100 }}\n"
for:
seconds: 5
- trigger: state
entity_id: sensor.calculated_home_mode
to: Day
conditions:
- condition: state
entity_id: input_boolean.sleep_in_ramp_active
state: 'on'
actions:
- variables:
motion_time_str: '{{ states(''input_datetime.first_kitchen_motion_today'') }}'
is_non_work_day: "{% if motion_time_str not in ['unknown', 'unavailable', '']\
\ %}\n {% set motion_time = as_datetime(motion_time_str) %}\n {% set motion_hour\
\ = motion_time.hour %}\n {% set motion_minute = motion_time.minute %}\n\
\ {% set is_work_window = (motion_hour == 4 and motion_minute >= 50) or (motion_hour\
\ == 5 and motion_minute == 0) %}\n {{ not is_work_window }}\n{% else %}\n\
\ {{ not is_state('binary_sensor.working_today', 'on') }}\n{% endif %}"
- action: input_boolean.turn_off
target:
entity_id: input_boolean.sleep_in_ramp_active
- action: input_select.select_option
target:
entity_id: input_select.home_state
data:
option: Day
- if:
- condition: template
value_template: '{{ is_non_work_day }}'
- condition: state
entity_id: input_boolean.kitchen_wled_enable
state: 'on'
then:
- action: light.turn_off
target:
entity_id:
- light.sink_wled
- light.frig_strip
- action: logbook.log
data:
name: WLED Control
message: Kitchen WLED turned off at end of non-work day ramp
- action: logbook.log
data:
name: Sleep-In Ramp
message: 'Ramp complete - Triggered by: {{ trigger.platform }} | Non-work day:
{{ is_non_work_day }}'
- id: daily_motion_reset
alias: Daily Motion Reset
description: Resets daily motion lock and tracking at midnight
triggers:
- trigger: time
at: 00:00:00
actions:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.daily_motion_lock
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.first_kitchen_motion_today
data:
datetime: ''
- id: kitchen_pyscript_morning_ramp_trigger
alias: Kitchen - Morning Ramp PyScript Trigger (motion)
mode: single
trigger:
- trigger: state
entity_id:
- binary_sensor.aqara_motion_sensor_p1_occupancy
- binary_sensor.kitchen_iris_frig_occupancy
to: 'on'
condition:
- condition: state
entity_id: input_boolean.sleep_in_ramp_system_enable
state: 'on'
- condition: state
entity_id: pyscript.home_state
state: Night
action:
- action: pyscript.morning_ramp_first_motion
data:
sensor: '{{ trigger.entity_id }}'
- id: unlock_door_on_arrival
alias: Unlock door when either iPhone arrives home
description: Auto unlock front door when either phone enters the home zone
triggers:
- trigger: zone
entity_id: device_tracker.iphone15
zone: zone.home
event: enter
- trigger: zone
entity_id: device_tracker.work_iphone
zone: zone.home
event: enter
conditions:
- condition: state
entity_id: input_boolean.smart_lock_auto_unlock
state: 'on'
actions:
- action: logbook.log
data:
name: Smart Lock
message: Arrival unlock triggered by {{ trigger.entity_id or trigger.platform
}}
entity_id: lock.aqara_smart_lock_u100_lock
- action: lock.unlock
target:
entity_id: lock.aqara_smart_lock_u100_lock
- action: notify.mobile_app_iphone15
data:
message: The front door was unlocked (arrival).
- action: notify.mobile_app_rrvqklh23h_iphone
data:
message: The front door was unlocked (arrival).
mode: single
- id: auto_lock_when_door_closes
alias: Auto-lock instantly when front door closes
description: Locks immediately when contact sensor reports closed
triggers:
- trigger: state
entity_id: binary_sensor.front_door_contact_contact
from: 'on'
to: 'off'
conditions:
- condition: state
entity_id: input_boolean.smart_lock_auto_lock
state: 'on'
- condition: state
entity_id: lock.aqara_smart_lock_u100_lock
state: unlocked
actions:
- action: logbook.log
data:
name: Smart Lock
message: Door closed → locking now
entity_id: lock.aqara_smart_lock_u100_lock
- action: lock.lock
target:
entity_id: lock.aqara_smart_lock_u100_lock
- action: notify.mobile_app_iphone15
data:
message: The front door auto-locked instantly after closing.
- action: notify.mobile_app_rrvqklh23h_iphone
data:
message: The front door auto-locked instantly after closing.
mode: restart
- id: track_last_departed_phone
alias: Track last phone departed
triggers:
- trigger: zone
entity_id: device_tracker.iphone15
zone: zone.home
event: leave
id: iphone15_leave
- trigger: zone
entity_id: device_tracker.work_iphone
zone: zone.home
event: leave
id: work_iphone_leave
actions:
- choose:
- conditions:
- condition: trigger
id: iphone15_leave
sequence:
- action: input_text.set_value
target:
entity_id: input_text.smart_lock_last_departed
data:
value: iphone15
- action: logbook.log
data:
name: Smart Lock
message: Last departed set to iphone15
- conditions:
- condition: trigger
id: work_iphone_leave
sequence:
- action: input_text.set_value
target:
entity_id: input_text.smart_lock_last_departed
data:
value: work_iphone
- action: logbook.log
data:
name: Smart Lock
message: Last departed set to work_iphone
mode: restart
- id: away_enforce_after_5min
alias: Away enforce after 5 minutes
description: After 5 minutes away, lock if needed and notify only the last departed
phone
triggers:
- trigger: state
entity_id: binary_sensor.both_phones_home
to: 'off'
for:
minutes: 5
conditions:
- condition: state
entity_id: input_boolean.smart_lock_away_enforce
state: 'on'
- condition: state
entity_id: binary_sensor.both_phones_home
state: 'off'
- condition: state
entity_id: binary_sensor.front_door_contact_contact
state: 'off'
actions:
- action: logbook.log
data:
name: Smart Lock
message: Away 5-min check running
entity_id: lock.aqara_smart_lock_u100_lock
- choose:
- conditions:
- condition: state
entity_id: lock.aqara_smart_lock_u100_lock
state: unlocked
sequence:
- action: lock.lock
target:
entity_id: lock.aqara_smart_lock_u100_lock
- choose:
- conditions:
- condition: template
value_template: '{{ states(''input_text.smart_lock_last_departed'') ==
''iphone15'' }}'
sequence:
- action: notify.mobile_app_iphone15
data:
message: 'Away check: Door was still unlocked after 5 minutes, locking
now.'
- conditions:
- condition: template
value_template: '{{ states(''input_text.smart_lock_last_departed'') ==
''work_iphone'' }}'
sequence:
- action: notify.mobile_app_rrvqklh23h_iphone
data:
message: 'Away check: Door was still unlocked after 5 minutes, locking
now.'
mode: single
- id: away_door_left_open
alias: Away alert if door left open
description: If both phones are away and door stays open >2 minutes, notify last
departed phone
triggers:
- trigger: state
entity_id: binary_sensor.front_door_contact_contact
to: 'on'
for:
minutes: 2
conditions:
- condition: state
entity_id: binary_sensor.both_phones_home
state: 'off'
actions:
- action: logbook.log
data:
name: Smart Lock
message: Door left open 2+ min while away
entity_id: lock.aqara_smart_lock_u100_lock
- choose:
- conditions:
- condition: template
value_template: '{{ states(''input_text.smart_lock_last_departed'') == ''iphone15''
}}'
sequence:
- action: notify.mobile_app_iphone15
data:
message: 'Away alert: The front door has been left open for 2 minutes.'
- conditions:
- condition: template
value_template: '{{ states(''input_text.smart_lock_last_departed'') == ''work_iphone''
}}'
sequence:
- action: notify.mobile_app_rrvqklh23h_iphone
data:
message: 'Away alert: The front door has been left open for 2 minutes.'
mode: single
- id: smart_switch_1_manual_amber_activate
alias: Smart Switch 1 - Manual Amber Activate
triggers:
- trigger: state
entity_id: input_boolean.smart_switch_1_manual_amber_trigger
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.smart_switch_1_amber_mode_enable
state: 'on'
actions:
- action: script.smart_switch_1_amber_sequence
- action: input_boolean.turn_off
target:
entity_id: input_boolean.smart_switch_1_manual_amber_trigger
- action: logbook.log
data:
name: Smart Switch 1 Amber
message: Manual amber mode activated
entity_id: light.smart_switch_1
- id: smart_switch_2_manual_amber_activate
alias: Smart Switch 2 - Manual Amber Activate
triggers:
- trigger: state
entity_id: input_boolean.smart_switch_2_manual_amber_trigger
to: 'on'
conditions:
- condition: state
entity_id: input_boolean.smart_switch_2_amber_mode_enable
state: 'on'
actions:
- action: script.smart_switch_2_amber_sequence
- action: input_boolean.turn_off
target:
entity_id: input_boolean.smart_switch_2_manual_amber_trigger
- action: logbook.log
data:
name: Smart Switch 2 Amber
message: Manual amber mode activated
entity_id: light.smart_switch_2
- id: smart_switch_1_amber_button
alias: Smart Switch 1 - Amber Button
triggers:
- trigger: state
entity_id: input_button.smart_switch_1_activate_amber
actions:
- action: script.smart_switch_1_amber_sequence
- id: smart_switch_1_normal_button
alias: Smart Switch 1 - Normal Button
triggers:
- trigger: state
entity_id: input_button.smart_switch_1_normal_mode
actions:
- action: light.turn_on
target:
entity_id: light.smart_switch_1
data:
brightness_pct: 80
color_temp_kelvin: 4000
- id: smart_switch_2_amber_button
alias: Smart Switch 2 - Amber Button
triggers:
- trigger: state
entity_id: input_button.smart_switch_2_activate_amber
actions:
- action: script.smart_switch_2_amber_sequence
- id: smart_switch_2_normal_button
alias: Smart Switch 2 - Normal Button
triggers:
- trigger: state
entity_id: input_button.smart_switch_2_normal_mode
actions:
- action: light.turn_on
target:
entity_id: light.smart_switch_2
data:
brightness_pct: 80
color_temp_kelvin: 4000
- id: both_switches_amber_button
alias: Both Switches - Amber Button
triggers:
- trigger: state
entity_id: input_button.both_switches_amber
actions:
- action: script.both_switches_amber_mode
- id: both_switches_normal_button
alias: Both Switches - Normal Button
triggers:
- trigger: state
entity_id: input_button.both_switches_normal
actions:
- action: light.turn_on
target:
entity_id:
- light.smart_switch_1
- light.smart_switch_2
data:
brightness_pct: 80
color_temp_kelvin: 4000
- id: trial_gate_yaml_home_state_eval
alias: TRIAL Gate YAML Home State Evaluation
mode: restart
triggers:
- trigger: state
entity_id: input_boolean.use_pyscript_home_state
actions:
- choose:
- conditions:
- condition: state
entity_id: input_boolean.use_pyscript_home_state
state: 'on'
sequence:
- action: automation.turn_off
target:
entity_id: automation.home_state_evaluation
- action: logbook.log
data:
name: TRIAL
message: Disabled YAML Home State Evaluation (toggle ON)
- conditions:
- condition: state
entity_id: input_boolean.use_pyscript_home_state
state: 'off'
sequence:
- action: automation.turn_on
target:
entity_id: automation.home_state_evaluation
- action: logbook.log
data:
name: TRIAL
message: Enabled YAML Home State Evaluation (toggle OFF)
- alias: Monitor Dryer Running State
id: monitor_dryer_running
description: Track when dryer starts and stops running
mode: restart
triggers:
- trigger: numeric_state
entity_id: sensor.dryer_dryer_electric_w_value
above: 50
id: dryer_start
- trigger: numeric_state
entity_id: sensor.dryer_dryer_electric_w_value
below: 50
for:
minutes: 2
id: dryer_stop
actions:
- choose:
- conditions:
- condition: trigger
id: dryer_start
sequence:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.dryer_running
- action: logbook.log
data:
name: Dryer Status
message: Dryer started running
- conditions:
- condition: trigger
id: dryer_stop
sequence:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.dryer_running
- action: logbook.log
data:
name: Dryer Status
message: Dryer finished running
- action: script.send_dryer_done_notification
- alias: Simple Washer Done Notification
id: simple_washer_done
description: Alexa announces and iPhone notifies when washer is done, checks if
dryer is running
mode: single
triggers:
- trigger: numeric_state
entity_id: sensor.washer_power
below: 8
for:
minutes: 1
conditions:
- condition: state
entity_id: input_boolean.washer_notifications
state: 'on'
- condition: state
entity_id: input_boolean.dryer_reminder_enable
state: 'on'
actions:
- action: script.send_washer_done_notification
- alias: Dryer Reminder Every 15min
id: dryer_reminder_every_15min
description: Keep reminding every 15min until clothes moved to dryer
mode: restart
triggers:
- trigger: time_pattern
minutes: /15
conditions:
- condition: state
entity_id: input_boolean.washer_notifications
state: 'on'
- condition: state
entity_id: input_boolean.dryer_reminder_enable
state: 'on'
- condition: state
entity_id: input_boolean.clothes_in_dryer_pending
state: 'on'
- condition: time
after: 08:00:00
before: '21:00:00'
actions:
- action: script.send_iphone_notification
data:
title: '🔔 Reminder: Dryer?'
message: Don't forget - did you move the clothes to the dryer?
actions:
- action: CLOTHES_IN_DRYER_YES
title: ✅ Yes, all moved!
- action: CLOTHES_REMIND_30MIN
title: ⏰ Remind me later
- alias: Handle Clothes in Dryer Confirmed
id: handle_clothes_in_dryer_yes
description: Stop reminders when user confirms clothes in dryer
mode: single
triggers:
- trigger: event
event_type: mobile_app_notification_action
event_data:
action: CLOTHES_IN_DRYER_YES
actions:
- action: script.handle_confirmation
data:
boolean_entity: input_boolean.clothes_in_dryer_pending
title: 👍 Perfect!
message: Great job! No more reminders.
- alias: Handle Dryer Remind 30min
id: handle_dryer_remind_30min
description: Snooze dryer reminder for 30 minutes
mode: restart
triggers:
- trigger: event
event_type: mobile_app_notification_action
event_data:
action: CLOTHES_REMIND_30MIN
actions:
- action: script.handle_snooze
data:
boolean_entity: input_boolean.clothes_in_dryer_pending
snooze_title: ⏰ Snoozed!
snooze_message: I'll remind you again in 30 minutes.
reminder_title: 🔔 Snooze Over!
reminder_message: Did you move the clothes to the dryer now?
reminder_actions:
- action: CLOTHES_IN_DRYER_YES
title: ✅ Yes, all moved!
- action: CLOTHES_REMIND_30MIN
title: ⏰ Remind me later
- alias: Washer Cleaning Reminder - Check After Cycle
id: washer_cleaning_after_cycle
description: Check if washer needs cleaning after each wash cycle (every 30 days)
mode: single
triggers:
- trigger: numeric_state
entity_id: sensor.washer_power
below: 8
for:
minutes: 1
conditions:
- condition: state
entity_id: input_boolean.washer_notifications
state: 'on'
- condition: state
entity_id: input_boolean.washer_cleaning_reminder_enable
state: 'on'
- condition: state
entity_id: input_boolean.washer_cleaning_pending
state: 'off'
- condition: time
after: 08:00:00
before: '21:00:00'
actions:
- variables:
last_cleaned: '{{ states(''input_datetime.washer_last_cleaned'') }}'
days_since_cleaned: "{% if last_cleaned != 'unknown' %}\n {{ ((as_timestamp(now())\
\ - as_timestamp(last_cleaned)) / 86400) | round(0) }}\n{% else %}\n 31\n\
{% endif %}"
- if:
- condition: template
value_template: '{{ days_since_cleaned >= 30 }}'
then:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.washer_cleaning_pending
- action: script.send_iphone_notification
data:
title: 🧽 Washer Maintenance Time!
message: '{% if last_cleaned != ''unknown'' %} It''s been {{ days_since_cleaned
}} days since you last cleaned the washer. Time for a cleaning cycle? {%
else %} When did you last clean the washer? It''s been a while - time for
a maintenance cycle? {% endif %}'
actions:
- action: WASHER_CLEANED_YES
title: ✅ Just cleaned it!
- action: WASHER_CLEAN_REMIND_LATER
title: 🌙 Remind me tonight
- alias: Washer Cleaning Reminder - Nag Every Hour
id: washer_cleaning_nag_hourly
description: Keep reminding about washer cleaning every hour until confirmed
mode: restart
triggers:
- trigger: time_pattern
minutes: 0
conditions:
- condition: state
entity_id: input_boolean.washer_notifications
state: 'on'
- condition: state
entity_id: input_boolean.washer_cleaning_reminder_enable
state: 'on'
- condition: state
entity_id: input_boolean.washer_cleaning_pending
state: 'on'
- condition: time
after: 09:00:00
before: '21:00:00'
actions:
- action: script.send_iphone_notification
data:
title: 🔔 Cleaning Reminder
message: Don't forget - your washer needs a cleaning cycle soon!
actions:
- action: WASHER_CLEANED_YES
title: ✅ Just cleaned it!
- action: WASHER_CLEAN_REMIND_LATER
title: 🌙 Remind me tonight
- alias: Handle Washer Cleaned Confirmed
id: handle_washer_cleaned_yes
description: Stop reminders when user confirms washer was cleaned
mode: single
triggers:
- trigger: event
event_type: mobile_app_notification_action
event_data:
action: WASHER_CLEANED_YES
actions:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.washer_cleaning_pending
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.washer_last_cleaned
data:
date: '{{ now().strftime(''%Y-%m-%d'') }}'
- action: script.handle_confirmation
data:
boolean_entity: input_boolean.washer_cleaning_pending
title: 🌟 Excellent!
message: Thanks! I'll remind you again in 30 days.
- alias: Handle Washer Clean Remind Tonight
id: handle_washer_clean_remind_tonight
description: Snooze washer cleaning reminder until evening
mode: restart
triggers:
- trigger: event
event_type: mobile_app_notification_action
event_data:
action: WASHER_CLEAN_REMIND_LATER
actions:
- action: script.handle_snooze
data:
boolean_entity: input_boolean.washer_cleaning_pending
snooze_title: 🌙 Got it!
snooze_message: I'll remind you tonight about washer cleaning.
delay_time: '19:00:00'
reminder_title: 🌆 Evening Reminder!
reminder_message: Good time to run a washer cleaning cycle tonight?
reminder_actions:
- action: WASHER_CLEANED_YES
title: ✅ Just cleaned it!
- action: WASHER_CLEAN_REMIND_LATER
title: 📅 Maybe tomorrow