Skip to content

Templated Thresholds

Jason Rhubottom edited this page Aug 2, 2026 · 5 revisions

Templated Thresholds

Every numeric threshold field in the table below accepts a Home Assistant Jinja2 template in place of a fixed number. Type a template into the field and Adaptive Cover Pro renders it to a number once per update cycle, so the threshold can follow a season, a sensor, an input_number helper, or any other state you can express in a template, without an external automation calling a service.

A separate field, the Motion Occupancy Template on the Automation screen, takes a condition template (truthy/falsy) rather than a number. It is documented at the bottom of this page.

Numeric threshold templates shipped in v2.28.0; threshold fields added since then β€” the hysteresis release edges and the extreme-heat threshold β€” accepted a template from the release that introduced each field. The boolean-state templates (Is Sunny / Presence / Is Raining / Is Windy) shipped in v2.29.0 β€” see Boolean-state templates below.

Referring to this cover's own entities. Every field on this page β€” numeric and boolean alike β€” renders with an acp namespace that resolves this instance's own entities by name, so you can write {{ is_state(acp.sun_infront, 'on') }} instead of pasting a long, install-specific entity ID that breaks the next time something gets renamed. The full key list, the exclusion rule, and the loop hazards are on Template Self-References.


Which fields accept a template

This table is the complete list. If a numeric threshold field is not on it, it takes a plain number only.

Screen Field
Climate β†’ Light & Cloud Lux Threshold
Climate β†’ Light & Cloud Irradiance Threshold
Climate β†’ Light & Cloud Cloud Coverage Threshold
Climate β†’ Light & Cloud Lux Release Threshold
Climate β†’ Light & Cloud Irradiance Release Threshold
Climate β†’ Light & Cloud Cloud Coverage Release Threshold
Climate β†’ Temperature & Climate Minimum Comfort Temperature
Climate β†’ Temperature & Climate Maximum Comfort Temperature
Climate β†’ Temperature & Climate Outdoor Temperature Threshold
Climate β†’ Temperature & Climate Extreme Heat Threshold (Outside)
Climate β†’ Temperature & Climate Low Temperature Release Threshold
Climate β†’ Temperature & Climate High Temperature Release Threshold
Climate β†’ Temperature & Climate Outside Temperature Release Threshold
Climate β†’ Temperature & Climate Extreme Heat Release Threshold
Weather Safety Wind Speed Threshold
Weather Safety Rain Rate Threshold
Weather Safety Wind Direction Tolerance

Seven of these are release thresholds β€” the optional hysteresis counterparts that sit directly beneath their activate threshold on the same screen, and stop a trigger from chattering across its edge. They are blank by default, which means the smoothing is off; a template works in one exactly as it does in the activate field above it.

A plain number still works in every one of these fields. Templating is opt-in: leave a number and nothing changes.


Writing a template

The field is a Jinja code editor with entity autocomplete and syntax highlighting, the same editor Home Assistant uses for template sensors. Your template must render to a number.

{{ states('input_number.summer_high_temp') | float }}
{# Tighter comfort band in winter, wider in summer #}
{{ 23 if now().month in (11, 12, 1, 2) else 26 }}
{# Track an outdoor sensor, with a fallback if it goes unavailable #}
{{ states('sensor.outdoor_temp') | float(25) }}

The unit for each field (Β°C, lux, W/mΒ², %, and so on) is shown in the field's description text rather than next to the editor, because the template editor has no fixed unit.


How rendering works

  • The template is rendered once per update cycle, before the position calculation runs. The calculation engine only ever sees the resulting number, never the raw template.
  • Use a float default (| float(25)) for any value that can go unavailable. A bare | float on an unavailable sensor renders to 0, which is rarely the threshold you want.
  • If a template fails to render to a number β€” a syntax error, an unavailable entity with no fallback, a non-numeric result β€” that field falls back to its built-in default for the cycle, and the failure is logged once (not every cycle) until it recovers. The cover keeps operating; one bad template does not stall the rest of the configuration.

Seeing the resolved value

Open the cover's diagnostics (see Debug & Diagnostics). Any field configured with a template appears under templated_thresholds, showing both the raw template string and the value it last rendered to:

"templated_thresholds": {
  "temp_high": { "template": "{{ 23 if now().month in (11,12,1,2) else 26 }}", "resolved": 26.0 }
}

Fields configured with a plain number do not appear there, so the list is exactly the set of thresholds currently driven by a template.


Motion Occupancy Template

The Motion Occupancy Template field on the Automation screen is the condition-template counterpart. It takes a template that renders truthy or falsy, and treats a truthy result as occupancy. It is OR'd with the configured Motion Sensors: presence is reported when any motion sensor is active or the template renders truthy.

{# Treat the room as occupied whenever a guest switch is on #}
{{ is_state('input_boolean.guest_mode', 'on') }}

Truthiness follows Home Assistant's usual condition rules (on, true, 1 count as true). An empty field, a non-template value, or a render failure all read as falsy, so a broken template can never wedge the room into permanent occupancy. The template can be used on its own, with no motion sensors configured, when occupancy is something you compute upstream.


Boolean-state templates

Available in v2.29.0 and later.

Four more condition fields take a truthy/falsy Jinja template, each one paired with the entity it sits next to on the same screen. Where the numeric fields above render to a number, these render to a state: a truthy result means the named condition is true.

Screen Field Truthy means Feeds
Climate β†’ Light & Cloud Is Sunny template sun is on the window Cloud suppression (sun absent β‡’ cloudy β‡’ suppress)
Climate β†’ Temperature & Climate Presence template the space is occupied Climate mode (presence)
Weather Safety Is Raining template it is raining Weather-safety override
Weather Safety Is Windy template it is windy Weather-safety override

Each field is optional and unset by default. A template that is empty, isn't Jinja, or fails to render gives no opinion β€” the field falls through to its companion entity, and then to that screen's built-in logic. A broken template can never force the condition on or off.

Combine mode. Each template field has a companion logic selector (OR / AND) that decides how the template folds in with the entity beside it:

  • OR (the default) β€” the condition is true when the template is truthy or the entity reads active.
  • AND β€” the condition is true only when the template is truthy and the entity reads active (the template gates the entity).

With no companion entity configured, the template alone decides in either mode. The mode only has an effect when a template is actually set.

{# Is Sunny: bright enough AND the forecast isn't overcast #}
{{ states('sensor.outdoor_lux') | float(0) > 15000
   and not is_state('weather.home', 'cloudy') }}

This is distinct from the Motion Occupancy Template above (which feeds the motion manager) β€” the Presence template here feeds climate-mode presence.


Worked example: an asymmetric (left/right) wind window

The built-in Wind Direction Tolerance on the Weather Safety screen is symmetric β€” it measures the angle between the wind bearing and the window azimuth and compares it to one tolerance, so it can only describe an arc that is equally wide on both sides. That's a poor fit for an awning that is sheltered on one side (a neighbouring house) but exposed on the other, where the safe arc might be 20Β° on one side and 130Β° on the other.

The Is Windy template lets you describe any arc you like, with independent left and right tolerances. Because each cover is its own Adaptive Cover Pro instance, you give each one its own template. Point the instance's Is Windy template at the snippet below, leave that instance's built-in Wind Speed Sensor / Wind Direction Sensor fields blank so the symmetric check doesn't also fire, and the template becomes the sole "is it windy?" signal β€” reacting live whenever the sensors it references change.

{% set azimuth = 135 %}          {# direction the awning faces, in degrees #}
{% set left_tolerance = 20 %}    {# sheltered side, counter-clockwise #}
{% set right_tolerance = 130 %}  {# exposed side, clockwise #}
{% set speed_threshold = 30 %}   {# in whatever unit your wind sensor uses #}
{% set speed = states('sensor.wind_speed') | float(none) %}
{% set bearing = states('sensor.wind_bearing') | float(none) %}
{% if speed is none %}false
{% elif bearing is none %}{{ speed >= speed_threshold }}
{% else %}
{% set diff = ((bearing - azimuth + 180) % 360) - 180 %}
{{ speed >= speed_threshold and ((0 <= diff <= right_tolerance) or (-left_tolerance <= diff < 0)) }}
{% endif %}

diff is the signed shortest angle between the wind bearing and the awning's azimuth, wrapped to βˆ’180…+180. right_tolerance covers the clockwise (exposed) side and left_tolerance the counter-clockwise (sheltered) side, so the two can be sized independently. With the values above β€” azimuth 135Β°, left 20Β°, right 130Β° β€” a bearing of 255Β° (120Β° clockwise) reads windy, 120Β° (15Β° counter-clockwise) reads windy, but 266Β° (131Β° clockwise) and the whole sheltered side read calm.

For a second awning that is the mirror image (exposed on the other side), paste the same template into its instance with the azimuth and the two tolerances swapped to match its geometry.

If the bearing sensor drops out, the template falls back to speed alone so the cover stays protected rather than silently exposed; change the {% elif bearing is none %} line to false if you'd prefer it to fail open on that side instead.


Related pages

🏠 Home Β· ✨ Features Β· πŸ“° What's New

Buy Me A Coffee

πŸš€ Getting Started

🧠 Core Concepts

πŸ“ Cover Types

βš™οΈ Configuration

πŸ”Œ Entities & Services

πŸ› οΈ Operations

πŸ”§ Advanced Use Cases

🎨 Dashboard

πŸ§ͺ Testing & Simulation

πŸ“š Reference

πŸ‘©β€πŸ’» For Developers

Clone this wiki locally