# ac_precool_before_peak — pre-cool the house before the utility peak window # # id / entity : ac_precool_before_peak -> automation.ac_pre_cool_before_peak # trigger : 12:00 local (America/New_York) # purpose : On work days, pre-cool before the 14:00-19:00 peak, harder when # the forecast high is hotter (>=90 -> 68, >=85 -> 70, >=80 -> 71, # below 80 -> no pre-cool). # # Graceful degradation (v2) — a broken dependency must NOT skip pre-cooling: # * workday sensor unavailable/unknown -> fall back to a plain Mon-Fri check. # * weather forecast fails or returns nothing -> assume a regular hot day # (high 88F -> 70F). weather.get_forecasts runs with continue_on_error so a # hard service error can't abort the run; the `fc is defined and is mapping` # guard catches the soft-failure (empty/None) case. # # NOTE: templates are kept on single lines on purpose — YAML folded scalars can # inject stray whitespace/newlines into Jinja. Readability lives in this header. # # v2 (2026-07-09): added workday + weather fallbacks. See AUTOMATIONS.md. id: ac_precool_before_peak alias: AC - Pre-cool before peak description: >- v2 (2026-07-09). Pre-cools before the 2-7pm peak on work days. Falls back to Mon-Fri if the workday sensor fails, and to a regular pre-cool (assume 88F high -> 70F) if the weather forecast fails. Managed in git; see AUTOMATIONS.md. mode: single triggers: - trigger: time at: "12:00:00" conditions: [] actions: - action: weather.get_forecasts continue_on_error: true target: entity_id: weather.forecast_4315aspenhill data: type: daily response_variable: fc - variables: is_workday: "{% set wd = states('binary_sensor.workday_sensor') %}{% if wd in ['on','off'] %}{{ wd == 'on' }}{% else %}{{ now().weekday() < 5 }}{% endif %}" today_high: "{% if fc is defined and fc is mapping and 'weather.forecast_4315aspenhill' in fc and fc['weather.forecast_4315aspenhill'].forecast | default([]) | length > 0 %}{% set today = now().date() %}{% set entries = fc['weather.forecast_4315aspenhill'].forecast | selectattr('datetime') | list %}{% set match = entries | selectattr('datetime','search', today | string) | list %}{{ (match[0].temperature if match else entries[0].temperature) | float(88) }}{% else %}88{% endif %}" setpoint: "{% set h = today_high | float(88) %}{% if h >= 90 %}68{% elif h >= 85 %}70{% elif h >= 80 %}71{% else %}none{% endif %}" - if: - condition: template value_template: "{{ is_workday and setpoint != 'none' }}" then: - action: climate.set_hvac_mode target: entity_id: climate.t6_pro_z_wave_programmable_thermostat_with_smartstart data: hvac_mode: cool - action: climate.set_temperature target: entity_id: climate.t6_pro_z_wave_programmable_thermostat_with_smartstart data: temperature: "{{ setpoint | int }}"