Mastering Home Assistant Template Sensors: Creating Custom Data Points
- #Home_Assistant
- #Template_Sensor
- #Automation
- #Configuration
- #YAML
- #Smart_Home
- #Jinja2

Understanding Home Assistant Template Sensors
In the world of smart homes, data is king. You have sensors for temperature, humidity, motion, door states, energy usage, and countless other metrics. But often, the raw data from your devices isn't exactly what you need for specific automations or visualizations. This is where Home Assistant's Template Sensors come into play.
A Template Sensor is a virtual sensor entity whose state and attributes are dynamically generated based on one or more existing entities or other data sources within Home Assistant. They allow you to apply logic, perform calculations, extract specific pieces of information, and combine data points using the powerful Jinja2 templating engine built into Home Assistant.
Why Use Template Sensors?
- Data Transformation: Convert units, perform mathematical operations, or clean up messy data.
- Attribute Extraction: Pull out a specific value from a complex attribute (like a JSON string or a list).
- Conditional States: Create a sensor whose state reflects a condition (e.g., 'Hot', 'Cold', 'Comfortable' based on temperature/humidity).
- Data Aggregation: Combine information from multiple sensors into a single entity.
- Custom Monitoring: Track values or conditions not directly exposed by your devices.
- Simplify Automations: Create a single sensor state that simplifies complex automation triggers and conditions.
Essentially, if you can express the desired sensor state or attribute using a Jinja2 template based on available Home Assistant data, you can create a Template Sensor for it.
Setting Up Template Sensors
Template Sensors are configured within your Home Assistant configuration files, typically `configuration.yaml` or within separate files included via the `!include` directive for better organization.
Home Assistant supports two primary ways to define Template Sensors: the older `sensor:` platform syntax and the newer, recommended `template:` integration syntax. We'll focus on the latter as it's more flexible and supports defining multiple template entities (sensors, binary sensors, etc.) under one umbrella.
Using the Modern `template:` Integration
Add the following to your `configuration.yaml` file:
template:
- sensor:
- name: "Outdoor Temperature Fahrenheit"
unique_id: outdoor_temp_fahrenheit
unit_of_measurement: "°F"
state_class: measurement
device_class: temperature
state: >
{{ (states('sensor.outdoor_temperature') | float * 9/5 + 32) | round(1) }}
attributes:
source_entity: sensor.outdoor_temperature
- name: "Current Weather Description"
unique_id: current_weather_description
state: >
{{ state_attr('weather.forecast_home', 'forecast')[0].condition }}
attributes:
temperature: >
{{ state_attr('weather.forecast_home', 'forecast')[0].temperature }}
wind_speed: >
{{ state_attr('weather.forecast_home', 'forecast')[0].wind_speed }}
- name: "Is Living Room Hot"
unique_id: is_living_room_hot
state: >
{% set temp = states('sensor.living_room_temperature') | float(default=0) %}
{% if temp > 25 %}
true
{% else %}
false
{% endif %}
icon: >
{% if is_state('binary_sensor.is_living_room_hot', 'true') %}
mdi:fire
{% else %}
mdi:snowflake
{% endif %}
Let's break down the components:
- `template:`: This is the main integration entry.
- `sensor:`: Under `template:`, you define different entity types. Here we define sensors.
- Each `- name:` block defines a single template sensor.
- `name`: The friendly name for your sensor entity.
- `unique_id`: (Recommended) A unique identifier. This allows you to modify the entity from the Home Assistant UI after creation.
- `unit_of_measurement`, `state_class`, `device_class`: Standard sensor properties that help Home Assistant categorize and display the data correctly (e.g., in history graphs, energy dashboard).
- `state:`: This is the core of the template sensor. It contains the Jinja2 template that determines the sensor's state. The `>` indicates a multi-line string.
- `attributes:`: (Optional) You can define custom attributes for your template sensor, also using templates. This is useful for exposing related data.
- `icon:`: (Optional) You can make the sensor's icon dynamic based on its state or other entities.
In the examples:
- The first sensor converts temperature from Celsius (assuming `sensor.outdoor_temperature` provides Celsius) to Fahrenheit. `| float` converts the state string to a number, `| round(1)` rounds it to one decimal place.
- The second extracts specific attributes (condition, temperature, wind speed) from a weather forecast entity's `forecast` attribute, which is a list. `[0]` gets the first item in the list (the current or today's forecast).
- The third checks if the living room temperature is above 25°C and sets the state to 'true' or 'false'. This could also be defined as a `binary_sensor`. The icon changes based on the state.
After adding or modifying your configuration, check the configuration (`Developer Tools` -> `YAML` -> `Check Configuration`) and restart Home Assistant for the changes to take effect.
Device Integration Tips
Template sensors inherently integrate with your existing devices by reading their states and attributes. Here's how to make the most of it:
- Identify Useful Data: Browse the `Developer Tools` -> `States` page to see the exact entity IDs, states, and attributes available from your devices. This is crucial for building correct templates.
- Complex Attributes: Some devices expose complex data in attributes, like JSON strings (e.g., from REST sensors or specific integrations). You might need Jinja2 filters like `| from_json` to parse them before accessing specific keys. Others might use lists or dictionaries that you access using bracket notation `[key]` or `[index]`.
- Availability: Template sensors will become `unavailable` if the entities they depend on become `unavailable`. Use the `availability_template` to define custom logic for when the template sensor itself should be considered available. For example, it might only be available if *all* dependent sensors are available, or if at least *one* is.
template:
- sensor:
- name: "Average Room Temperature"
unique_id: average_room_temperature
unit_of_measurement: "°C"
state_class: measurement
device_class: temperature
state: >
{% set living_room = states('sensor.living_room_temperature') | float(default=0) %}
{% set bedroom = states('sensor.bedroom_temperature') | float(default=0) %}
{% set office = states('sensor.office_temperature') | float(default=0) %}
{{ ((living_room + bedroom + office) / 3) | round(1) }}
availability: >
{{ not ('unavailable' in [states('sensor.living_room_temperature'), states('sensor.bedroom_temperature'), states('sensor.office_temperature')]) }}
This example calculates the average temperature, and the `availability` template makes the sensor `unavailable` if *any* of the source temperature sensors are `unavailable`.
Best Practices for Managing Reliable Template Sensors
Crafting effective template sensors goes beyond just writing Jinja2 code. Follow these best practices for a robust and maintainable configuration:
- Test Your Templates: Before adding a complex template to your configuration, use the `Developer Tools` -> `Template` editor. Paste your template code and see the real-time output based on the current states of your entities. This is the single most important step for debugging.
- Use the `default` Filter: Entity states can sometimes be `unavailable`, `unknown`, or just empty strings, especially right after Home Assistant starts or if a device drops off the network. Using the `| default(some_value)` filter (e.g., `| float(default=0)`) in your templates prevents errors if the input is not a valid number or is missing.
- Add `unique_id`: Always include a `unique_id`. This allows you to manage the sensor (rename, change icon, add to areas/lovelace) directly from the Home Assistant UI without constantly editing YAML files after the initial creation.
- Keep Templates Readable: For complex logic, use Jinja2 variables (`{% set var_name = ... %}`) to break down calculations or data extraction into smaller, more manageable steps. Use comments (`{# This is a comment #}`) to explain complicated parts of your templates.
- Organize Your Configuration: Don't put all your template sensors in `configuration.yaml`. Use `!include` directives to split them into separate files (e.g., `template.yaml` or `sensors/template_sensors.yaml`) for better organization, especially as your smart home grows.
- Be Mindful of Update Frequency: A template sensor updates whenever the state or relevant attribute of any entity referenced within its `state:` or `attributes:` template changes. Most of the time, this is exactly what you want. However, be aware that referencing entities that update very frequently (like power consumption sensors updating every second) will cause your template sensor to update just as frequently, which is usually fine but something to keep in mind for performance on very low-power systems.
- Leverage Dynamic Properties: Use `icon_template`, `unit_of_measurement_template`, and `attribute_templates` when the icon, unit, or attributes should change based on state or other factors.
- Consider `binary_sensor` for Boolean States: If your template sensor's state is always `true` or `false` (or effectively `on`/`off`), consider defining it under `binary_sensor:` within the `template:` integration instead of `sensor:`. This gives it the correct device class semantics (e.g., `on`/`off` states, different icons).
Conclusion
Template sensors are a cornerstone of advanced Home Assistant configurations. They transform your raw smart home data into meaningful information, enabling more sophisticated automations, cleaner dashboards, and deeper insights into your home's behavior. By mastering the basics of Jinja2 templating within the Home Assistant framework and following best practices for setup and maintenance, you can create a more powerful, flexible, and reliable smart home ecosystem tailored precisely to your needs.

NGC 224
Author bio: