Working with states
Home Assistant keeps track of everything in your home as a collection of entitiesAn entity represents a sensor, actor, or function in Home Assistant. Entities are used to monitor physical properties or to control other entities. An entity is usually part of a device or a service. [Learn more]. Each entity has a state (its current value) and often a few attributes (extra details about it). When you write a template, you are almost always reading state or attributes from one or more entities.
This page explains how to get at that information inside a template.
First, go look at your states
Before you write a single line of template, spend five minutes at Settings > Developer tools > States. This is where Home Assistant shows you every entity it knows about, its current state, and all of its attributes.
For example, you might see something like this for your outdoor thermometer:
Entity: sensor.outdoor_temperature
State: 22.5
Attributes:
unit_of_measurement: °C
device_class: temperature
friendly_name: Outdoor temperature
This one entity has:
- An entity ID (
sensor.outdoor_temperature). This is the name you use to look it up. - A state (
22.5). That is the entity’s main value. - Several attributes (unit of measurement, device class, friendly name). These are extra pieces of information that go along with the state.
When you write {{ states('sensor.outdoor_temperature') }}, Home Assistant looks up that exact entity ID and gives you back its state. It is that direct.
Keep the Developer Tools > States page open in a separate browser tab while you write templates. You can search for entities, see exactly what state and attributes they have, and make sure you are spelling entity IDs correctly. It is the single most useful debugging habit you can build.
Reading a state
The states function gives you the current state of an entity. You pass it the entity ID as text.
The kitchen light is {{ states('light.kitchen') }}.
The kitchen light is on.
Every state is text
Here is something that catches everyone at least once. Home Assistant stores every entity state as text. Even when a sensor looks like it’s giving you a number, states() hands it back as a piece of text. So states('sensor.outdoor_temperature') returns the text '22.5', not the number 22.5.
Why does that matter? Because you can’t do math with text, and comparing text to a number gives surprising results. For example, '6' < '10' is False (text is sorted alphabetically, so '6' comes after '1'). If you try to do math directly, you will get an error or the wrong answer.
{{ states('sensor.outdoor_temperature') | float(0) + 5 }}
27.5
The | float(0) part converts the text to a number. The 0 is a fallback: if the conversion fails (maybe the sensor is offline), the template uses 0 instead of crashing.
Rule of thumb: whenever you do math or number comparisons on a sensor state, add | float(0) or | int(0) first. It is not optional, it is how templates work.
States have a 255 character limit
The text stored in an entity’s state can be at most 255 characters long. Home Assistant enforces this limit so the state can fit in the database and dashboards. If your template sensor needs to produce something longer (say, a list of names, a formatted table, or a long paragraph), store it in an attribute instead. Attributes don’t have the same limit.
When an entity is missing or unavailable
Home Assistant has two special state values for when things go wrong:
-
unknownmeans the entity exists but Home Assistant does not know its value right now. -
unavailablemeans the entity cannot be reached at all. Maybe a device is offline or an integration failed to load.
And if you ask for an entity that does not exist at all, you get the text unknown back as well.
Templates that depend on live values should handle these cases gracefully. Adding a number fallback (| float(0)) fixes most math problems. For decisions, use has_value (covered below).
Reading an attribute
Attributes carry extra details about an entity. A light has attributes for brightness and color. A weather entity has attributes for forecast data. A media player has attributes for the current track.
To read one, use state_attr:
The kitchen light is at {{ state_attr('light.kitchen', 'brightness') }}.
The kitchen light is at 192.
Like with states, if the entity does not exist or the attribute is not set, you get nothing back (none). For math, add a fallback:
{{ state_attr('light.kitchen', 'brightness') | int(0) }}
192
You can find an entity’s attribute names by looking at Developer Tools > States.
Checking a state
You can compare a state with ==, but there is a dedicated function that is cleaner and handles missing entities without surprises: is_state.
{{ is_state('light.kitchen', 'on') }}
True
This reads naturally: “is the state of light.kitchen equal to on?”. The answer is True or False.
There is a matching function for attributes, is_state_attr:
{{ is_state_attr('media_player.living_room', 'source', 'Spotify') }}
True
And has_value checks whether an entity has a usable state at all (not unknown or unavailable):
{% if has_value('sensor.outdoor_temperature') %}
It is {{ states('sensor.outdoor_temperature') }}°C outside.
{% else %}
The outdoor sensor is unavailable.
{% endif %}
It is 22.5°C outside.
Use has_value whenever you want to fall back to a friendly message instead of showing “unavailable” on a dashboard or in a notification.
Getting a list of entities
states.domain gives you every entity in that domainEach integration in Home Assistant has a unique identifier: The domain. It is often shown as the first part (before the dot) of entity IDs. (the first part of an entity ID, like light. or sensor.). This is how you count, filter, and iterate over groups of entities.
There are {{ states.light | count }} lights in total.
There are 12 lights in total.
Combine it with selectattr to filter the list down to what you care about. selectattr reads as “select entities where this attribute equals this value”:
Lights that are on:
{% for light in states.light | selectattr('state', 'eq', 'on') %}
- {{ light.name }}
{% endfor %}
Lights that are on:
- Kitchen
- Hallway
- Desk
Finding entities by area, device, label, or floor
Home Assistant comes with a family of functions for finding entities grouped by how you’ve organized them:
-
area_entitiesreturns every entity in an areaAn area in Home Assistant is a logical grouping of devices and entities that are meant to match areas (or rooms) in the physical world: your home. For example, theliving roomarea groups devices and entities in your living room. [Learn more]. -
device_entitiesreturns every entity tied to a deviceA device is a model representing a physical or logical unit that contains entities.. -
label_entitiesreturns every entity carrying a given labelLabels in Home Assistant allow grouping elements irrespective of their physical location or type. Labels can be assigned to areas, devices, entities, automations, scenes, scripts, and helpers. Labels can be used in automations and scripts as a target for actions. Labels can also be used to filter data. [Learn more]. -
floor_entitiesreturns every entity on a floorA floor in Home Assistant is a logical grouping of areas that are meant to match the physical floors in your home. Devices & entities are not assigned to floors but to areas. Floors can be used in automations and scripts as a target for actions. For example, to turn off all the lights on the downstairs floor when you go to bed. [Learn more]. -
integration_entitiesreturns every entity created by a given integrationIntegrations connect and integrate Home Assistant with your devices, services, and more. [Learn more].
Each has matching functions for going the other way (for example, area_devices lists the devices in an area). Browse the Areas, Devices, Floors, and Labels categories in the reference for the full set.
Here is how you’d list the bedroom lights that are on:
Bedroom lights on:
{% for entity in area_entities('bedroom') %}
{% if entity.startswith('light.') and is_state(entity, 'on') %}
- {{ state_attr(entity, 'friendly_name') }}
{% endif %}
{% endfor %}
Bedroom lights on:
- Bedroom ceiling
- Bedside lamp
The this variable (in template entities)
When you write a template that defines a template entity, this refers to the entity itself. That is useful when the entity needs to read its own state or attributes without hardcoding its entity ID.
template:
- sensor:
- name: "Kitchen helper"
state: "{{ this.attributes.get('counter', 0) + 1 }}"
attributes:
counter: "{{ this.state | int(0) + 1 }}"
1 (the sensor increments its own value each time it updates)
this only exists where Home Assistant knows which entity the template belongs to. That means template entities and some automation contexts, but not the Developer Tools template editor.
The trigger variable (in automations)
When an automation runs, it receives a trigger variable with details about what caused it. The fields depend on the triggerA trigger is a set of values or conditions of a platform that are defined to cause an automation to run. [Learn more] type; the Automation trigger variables page lists them all.
- trigger: state
entity_id: binary_sensor.front_door
to: "on"
action:
- action: notify.mobile_app
data:
message: >
{{ trigger.to_state.name }} was opened at
{{ trigger.to_state.last_changed.strftime('%H:%M') }}.
Front door was opened at 14:32.
Next steps
- Ready-made examples that combine these tools live on the Common template patterns page.
- The full list of state and entity functions is in the template functions reference.
- When a template does not give you what you expected, see Debugging templates.