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 > 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.

Tip

Keep the Settings > 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.

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
The kitchen light is {{ states('light.kitchen') }}.
Result
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.

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
{{ states('sensor.outdoor_temperature') | float(0) + 5 }}
Result
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:

  • unknown means the entity exists but Home Assistant does not know its value right now.
  • unavailable means 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:

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
The kitchen light is at {{ state_attr('light.kitchen', 'brightness') }}.
Result
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:

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
{{ state_attr('light.kitchen', 'brightness') | int(0) }}
Result
192

You can find an entity’s attribute names by looking at Settings > Tools > States.

Reading the state object

states only gives you the state, as text. To read more about an entity, use its state object: states. followed by the entity ID, such as states.sensor.outdoor_temperature.

The state object has the following properties:

  • state: The state, as text.
  • state_with_unit: The state followed by its unit, such as 22.5 °C. For sensors, the value is rounded the way Home Assistant shows it. Only available in templates.
  • attributes: The attributes, such as attributes.brightness.
  • name: The name of the entity.
  • entity_id, domain, and object_id: The entity ID, and its two parts. For sensor.outdoor_temperature, the domain is sensor and the object ID is outdoor_temperature.
  • last_changed, last_updated, and last_reported: When the state last changed, when the state or attributes last changed, and when the entity last reported its state. All three are in UTC.
  • context: The context of the state, which tells you what caused the change.
TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
It is {{ states.sensor.outdoor_temperature.state_with_unit }} outside.
Result
It is 22.5 °C outside.

If the entity doesn’t exist, the state object is none. Reading one of its properties gives an empty result, but reading further, such as .attributes.unit_of_measurement, causes an error. Check for none first, for example, {% if states.sensor.outdoor_temperature is not none %}. To read only the state or an attribute, states() and state_attr() are safer. For all details, refer to State object.

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.

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
{{ is_state('light.kitchen', 'on') }}
Result
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:

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
{{ is_state_attr('media_player.living_room', 'source', 'Spotify') }}
Result
True

And has_value checks whether an entity has a usable state at all (not unknown or unavailable):

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
{% if has_value('sensor.outdoor_temperature') %}
  It is {{ states('sensor.outdoor_temperature') }}°C outside.
{% else %}
  The outdoor sensor is unavailable.
{% endif %}
Result
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.

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
There are {{ states.light | count }} lights in total.
Result
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”:

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
Lights that are on:
{% for light in states.light | selectattr('state', 'eq', 'on') %}
  - {{ light.name }}
{% endfor %}
Result
Lights that are on:
  - Kitchen
  - Hallway
  - Desk

How often templates update

Templates that update automatically, such as in a template entity or a Markdown card, render again when an entity they use changes. To keep this light, Home Assistant limits how often templates that use many entities render again:

  • A template that goes through all states, such as states | selectattr('state', 'eq', 'unavailable') | list | count, renders again at most once per minute. A template that only counts all entities, such as states | count, isn’t limited. It renders again only when an entity is added or removed.
  • A template that goes through all entities of a domain, such as states.light, renders again at most once per second.
  • A change to an entity that the template names directly, such as in states('sensor.outdoor_temperature'), always makes the template render again right away.

For details, and how to avoid the limit with a trigger, refer to Rate limiting updates.

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_entities returns every entity in an areaAn area in Home Assistant is a logical grouping of devices and entities that represents a room or space in your home, such as the living room, kitchen, or garage. [Learn more].
  • device_entities returns every entity tied to a deviceA device is a model representing a physical or logical unit that contains entities..
  • label_entities returns 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_entities returns 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_entities returns 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:

TemplateA template is an automation definition that can include variables for the action or data from the trigger values. This allows automations to generate dynamic actions. [Learn more]
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 %}
Result
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. For example, this sensor keeps its last value while the outdoor sensor is unavailable:

AutomationAutomations in Home Assistant allow you to automatically respond to things that happen in and around your home. [Learn more]
template:
  - sensor:
      - name: "Outdoor temperature (last known)"
        unit_of_measurement: "°C"
        state: >
          {% if has_value('sensor.outdoor_temperature') %}
            {{ states('sensor.outdoor_temperature') }}
          {% else %}
            {{ this.state | float(none) }}
          {% endif %}
Result
22.5 (the last value, while the outdoor sensor is unavailable)

The sensor has a unit, so its state must be a number. Before it has had a value, this.state is unknown, so float(none) turns it into none instead.

A template that reads its own entity renders again when that entity changes. If the template changes the value every time, such as a counter that adds one to its own state, it keeps updating itself. Home Assistant detects this loop, stops it, and logs a “Template loop detected” warning. To count something, use a counter helper instead.

this only exists where Home Assistant knows which entity the template belongs to. That means template entities and some automation contexts, but not the Template editor available in Settings > Tools > Template.

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 the part of an automation that makes the automation start when something specific happens, for example, when the sun sets, a door opens, or a button is pressed. [Learn more] type; the Automation trigger variables page lists them all.

AutomationAutomations in Home Assistant allow you to automatically respond to things that happen in and around your home. [Learn more]
triggers:
  - trigger: state
    entity_id: binary_sensor.front_door
    to: "on"
actions:
  - action: notify.send_message
    target:
      entity_id: notify.my_device
    data:
      message: >
        {{ trigger.to_state.name }} was opened at
        {{ as_local(trigger.to_state.last_changed).strftime('%H:%M') }}.
Result
Front door was opened at 14:32.

last_changed is in UTC, so the example converts it to your local time with as_local before formatting it.

Next steps