light, switch, cover, and scene Entities: What You See in Home Assistant
light, switch, cover, and scene Entities: What You See in Home Assistant
In Lessons 2 through 7 you chose hardware: bulbs, relays, dimmers, LED strips, blind modules. Now you're looking at the same things from the other side: how Home Assistant describes devices inside the system. Home Assistant doesn't control "the living room lamp" as an abstract object. It controls a specific entity, created by a specific integration, with a defined set of features, states, and limits.
This lesson isn't a dictionary of every entity in HA. We're focusing on light, switch, cover, scene, and script. We're not yet covering sensor, binary_sensor, or climate: those show up in other modules. We'll cover motion and lux sensors alongside automations in Lessons 11 and 12, but today you need to know how a controlling entity differs from an informational one.
Plan on about 110 to 120 minutes. Further on I'll shorten Home Assistant to HA.
This lesson's rule
Don't think "I have a light entity." Think "I have a living room ceiling lamp: HA describes it with a light entity."
First you understand the system's structure, then you build the dashboard, manual control from Lesson 9, and the scenes from Lesson 10.
A real-life problem: I added one bulb, HA shows five things
You bought a Shelly Dimmer, added the integration, and expected one button in the app. Instead you see: light.living_room_ceiling, sensor.living_room_ceiling_power, sensor.living_room_ceiling_energy, update.shelly_dimmer_firmware, button.shelly_dimmer_restart. You ask: "Why so many entities? Which one do I use?"
Or you're writing an automation and use switch.turn_on on an entity that's actually a light. An action from the wrong domain doesn't correctly control the entity: HA might report an error, a warning, or show a failed action in the automation's trace. Don't assume the device not responding means a hardware failure.
A third case: you copy a snippet from a forum with light.living_room_ceiling_lamp, but your entity is named light.living_room_ceiling. The automation is "syntactically correct," but it doesn't touch any device.
From lamp to automation: seven layers
- The physical point: a ceiling lamp in the living room.
- The device: a dimmer, a relay, or a smart bulb.
- The integration: how Home Assistant communicates with the device: Shelly, Hue, ZHA, Zigbee2MQTT, Matter.
- The device in HA: a logical entry grouping one product's entities.
- The entity: a single controlling or informational function.
- The action: a command executed on an entity, e.g. turning a light on.
- Logic and interface: a scene, a script, an automation, a remote, or a dashboard.
An entity is a single object exposed by Home Assistant. It can represent a controlling device, a measurement, a setting, a button, an event, or an update. Not every entity has an on/off switch, and not every one belongs on a household member's dashboard.
In this course we use the term action and the action: syntax. In older guides you'll find the term "service" and the service: notation. The example light.turn_on means the action of turning a light on.
Why do most device-controlling actions start with a domain?light.turn_on, cover.open_cover, switch.turn_on: HA groups actions by entity domain. There are also notification, scene, script, system, and integration actions that don't start with the target device's domain.
A device is not an entity: and why that matters in practice
A device is a physical product (or an integration's virtual object): often one entry under Settings → Devices & Services → Devices. An entity is a single element of control or information. One device can have five, ten, or more entities.
Many integrations group entities under a device, but not every entity has to belong to a physical device. A helper, a scene, a script, or a template entity can exist on its own.
| Device (example) | Example entities, depending on the integration | Everyday control |
|---|---|---|
| Shelly Dimmer Gen3 | light + sensor (power, energy) + update + button |
mainly light.living_room_ceiling |
| Shelly Plus 2PM (cover) | cover + sensor + update |
mainly cover.living_room_blind |
| Aqara Roller Shade Driver E1 | cover + sensor (battery) + possibly update |
mainly cover.bedroom_blind |
| A Philips Hue bulb | light + possibly update |
mainly light.living_room_lamp |
Sort entities into: everyday (control), informational (power, energy), diagnostic (battery, availability), and administrative (restart, firmware). First, remove technical entities from the household dashboard. Only disable them in the entity registry once you know no automation, statistic, or diagnostic process needs them.
Name, entity_id, and unique_id
Every entity has an identifier of the form domain.name, e.g. light.living_room_ceiling. Separately, it has a friendly name for household members. The integration often also assigns a unique_id: a persistent identifier that lets HA recognize the same entity regardless of its friendly name. You don't need to manage unique_id by hand, but know that entity_id is the language of YAML, while the friendly name is the language of the interface.
You can change the name shown on the dashboard without changing the identifier. If you also change the entity_id, check every automation, script, scene, dashboard, template, and notification that uses the old identifier.
A recommended naming pattern: domain.room_function. Examples: light.living_room_ceiling, cover.living_room_patio_blind, switch.bathroom_fan. Don't use light.shelly_123456 or switch.relay_1: hardware can get replaced, but the function in the home stays the same.
Besides entity_id, HA offers organization through an area, a floor, and a label. An area helps in the UI, and a label can group things functionally, e.g. "main lights," "critical," "exterior."
State, attributes, and unknown
State (state) is an entity's main text value. Attributes are additional properties: they aren't separate entities. Not all attributes are always present; null means no value applies in the current mode.
unknown and unavailable
unknown: HA doesn't know the current value.unavailable: the entity or integration is unreachable.- Neither state should be automatically treated as
off,closed, or a safe state (see Lesson 7).
last_changed shows when the main state last changed. last_updated: when the state or attributes last updated. Neither necessarily means the last radio message from the device. Example: brightness changes from 30% to 50%, the state stays on: last_changed may stay the same, while last_updated changes.
switch.lamp = on means the switch is supplying power. It doesn't prove the bulb is actually lit. cover.blind = open doesn't prove the mechanism didn't hit an obstacle. For important functions, keep the commanded state separate from confirmation of the physical effect.
The light entity: capabilities and action parameters
Don't judge a light's capabilities solely from supported_features. Check supported_color_modes, the current color_mode, the color-temperature range, and the options visible in the light.turn_on action form. In older examples you'll find color_temp in mireds: in this course's current code we use color_temp_kelvin, since it matches the values printed on bulb packaging (2200K, 2700K, 4000K).
The transition parameter requests a smooth transition. Not every integration handles it identically: some ignore it, some jump abruptly. Test the effect manually before using a transition in a whole-house scene. Only use parameters your specific entity actually supports.
- action: light.turn_on
target:
entity_id: light.living_room_ceiling
data:
brightness_pct: 40
color_temp_kelvin: 2700
transition: 2
- action: light.turn_off
target:
entity_id: light.living_room_ceiling
data:
transition: 5
- action: light.turn_on
target:
entity_id: light.hallway_ceiling
A light group is a convenient target, not new capabilities
A light group creates one light entity you can send a shared command to. It doesn't change what its members can do: if one lamp doesn't support color, the group won't add RGB to it. When one member is unavailable, the rest can still carry out the command. A group's state isn't proof every source reached an identical state. A group doesn't replace a scene.
The switch entity: when on/off is enough
An on/off relay, a smart plug, a fan: typical switch entities. If a switch entity controls only a lamp, in certain cases you can present it in HA as a light. That makes grouping and a lighting dashboard easier. It doesn't change the hardware's actual capabilities: the relay still doesn't support brightness or color.
Name entities by function: switch.garage_light, not switch.garage_relay. Exception: switch.panel_backup_circuit, when the technical function actually matters.
toggle is convenient for a manual button, but risky in automations: if the state in HA is stale, the result depends on the prior state. In time-based and safety automations, it's better to use an explicit turn_on or turn_off.
- action: switch.turn_on
target:
entity_id: switch.bathroom_fan
The cover entity: a blind isn't two switches side by side
A correctly configured blinds module creates one cover entity. States can include open, closed, opening, closing, unknown, unavailable: depending on the integration. The open state can mean partial opening; you'll find the more precise position in current_position, if the device supports it.
In standard HA semantics, a position of 0 means closed, and 100 means open. A position of 50 means partially open. Always confirm your own integration's behavior on one test blind (Lesson 7).
If the entity supports a percentage position, you can use cover.set_cover_position. Otherwise you stick with open_cover, close_cover, and possibly stop_cover. Not every blind reports position reliably: recall from Lesson 7 that it's often only an estimate.
If you see two switches instead of a cover: go back to Lesson 6. Two independent switches are a sign the device isn't correctly configured as a blinds controller. Don't build your target control setup on top of that.
A cover group is a convenient target, but the blinds don't have to move in sync. STOP can arrive with different delays. A group's position doesn't guarantee physical synchronization. A group can't bypass the local patio lockouts from Lesson 7.
- action: cover.set_cover_position
target:
entity_id: cover.living_room_blind
data:
position: 50
- action: cover.stop_cover
target:
entity_id: cover.living_room_blind
Only test cover actions after confirming directions, limit switches, local STOP, and a clear path of travel, per Lesson 7. Developer Tools bypasses the dashboard's context: don't click random cover actions without observing the blind.
scene, script, and automation: three tools, not synonyms
A scene sets target states for multiple entities. A plain saved scene isn't an automatic "undo" mechanism: it applies a saved state. Dynamically capturing and replaying state (scene.create) is a separate, more advanced technique. A scene describes target states without its own sequence of delays: devices can reach them at slightly different times.
Calling a scene doesn't mean the house stays in that scene. A household member might change one lamp a moment later. If later automations need to know a logical mode, record it in a separate helper (e.g. input_select.light_mode), not by reading the state of a scene entity.
A script is a procedure: a sequence of actions with delays, conditions, and loops. An automation also runs a sequence of actions: the difference is that it has a trigger. A script is just the procedure, and can be started from a dashboard, a remote, another script, or an automation. Long scripts need a deliberately chosen mode (single, restart, queued), so a second press doesn't chaotically launch a second copy.
If an automation always sets the same states for several lights, factor them out into a scene. If the values are calculated dynamically (templates, different conditions per lamp), direct actions can be the right approach.
- action: scene.turn_on
target:
entity_id: scene.living_room_evening
- action: script.living_room_slow_fade
A remote, a wall switch, and an event entity
A remote doesn't become a light entity and doesn't take over a lamp's state. It can, however, have its own battery entity, an event entity, or device triggers. Pressing it is meant to call an action on the actual light entity, scene, or script.
A Zigbee remote, a wall switch, a dashboard, and an automation: all of them can affect the same entity. The most recent command might change the expected state, but ultimately the integration decides how and when to update the entity based on communication with the device. The delay depends on the device, the protocol, the integration, and network quality: measure it at your own point.
For smart bulbs, cutting power with a wall switch produces unavailable: that's normal behavior. It's worth running an exercise: safely turn off the lamp with a plain switch, watch for unavailable, restore power, and check the entity comes back. Don't run this test on a blind.
Developer Tools: where to check this before writing YAML
States: this tab shows an entity's current model in HA: entity_id, state, attributes, last_changed, last_updated. It's the basic diagnostic location, not the "source of truth" about the physical world. Manually editing a state in Developer Tools only changes the model in HA temporarily: it doesn't control the physical device.
Actions: a manual test before YAML. If it works here but not in the automation: the problem is in the trigger or a condition.
Use the Actions tab to test devices. Manually typing in a different entity state can change only the model visible in HA, and doesn't have to send any command to the physical device.
An action works manually, but not in the automation
Open the automation and check its execution trace. You'll see whether the trigger fired, which condition returned false, and where execution stopped. The logbook helps confirm when the state changed and whether the device was unavailable. Don't start swapping hardware before checking the trace.
Two screens, two different purposes
- The household dashboard: lights, blinds, scenes, lockouts: readable names, no restart buttons and firmware entities.
- The technical dashboard: power, energy, battery, firmware, availability, last test, errors.
Mark critical entities (the patio blind, the automation lockout, STOP, the stairway light) with a label or a separate table. Not every entity carries the same level of importance. A button.shelly_restart button doesn't belong on the family dashboard: an accidental press could briefly disable control.
A point-to-Home Assistant mapping table
| Point | Hardware | Integration | Domain | entity_id | Features | Manual | Without HA | Test date |
|---|---|---|---|---|---|---|---|---|
| Living room ceiling | Dimmer | Shelly | light | light.living_room_ceiling |
on/off, brightness | button | yes | date |
| Living room blind | Cover module | Shelly | cover | ____ | up/down/stop, position? | button | yes | date |
| ____ | Relay | ____ | switch / light | ____ | on/off | ____ | ____ | ____ |
Common mistakes
Thinking "1 purchase = 1 entity": a device can have many entities.
switch.turn_on on a light entity: the wrong action domain.
Treating open as 100%, or on as confirmation a lamp is lit.
Treating unknown like off.
Using a scene as an indicator of the active mode: use a helper instead.
Testing a cover without a confirmed STOP from Lesson 7.
Using toggle in an automation with an uncertain state.
Device names instead of a room's function (shelly_123).
Hands-on exercise
☐ Sort them into: everyday, informational, diagnostic, and administrative.
☐ Find the friendly name,
entity_id, parent device, integration, and area.☐ For one
light entity, check its state, attributes, and supported color modes.☐ If the light supports brightness, test
brightness_pct: 30.☐ If it supports color temperature, test
color_temp_kelvin.☐ Check whether the device actually supports
transition: compare 0s and 3s.☐ For one
cover entity, record the available actions; only move it after the tests from Lesson 7.☐ Check whether position 0 means closed and 100 means open.
☐ Fill in the point → integration → entity table for at least five points.
☐ Mark entities as critical, technical, or meant for a household member.
☐ Open the trace of one working automation and check its conditions and actions.
☐ Don't change an
entity_id until you've checked every place it's used.
Key takeaways
- The physical point, the device, the integration, and the entity are different layers.
- One device can create many entities with different functions.
- The friendly name is for household members, and
entity_idis for configuration. - Changing an
entity_idrequires checking automations, scenes, scripts, and dashboards. unknownandunavailabledon't mean a safe state.- You check a light's capabilities through its supported modes and the action form, not by guessing.
- A relay presented as a light still doesn't gain dimming functionality.
- An entity's state doesn't always confirm the physical effect actually happened.
- A cover position of 0 means closed and 100 means open: if the integration follows standard semantics.
- Not every blind supports a percentage position, or reports it reliably.
- A group simplifies control, but doesn't guarantee identical execution by every device.
- A scene sets target states, a script runs a procedure, and an automation adds a trigger.
- You use Actions to test devices, and States and automation traces to diagnose problems.
- A household dashboard and a technical dashboard should contain different entities.
In Lesson 9 we return to the physical layer: buttons, remotes, wall switches, and Plan B. We build the "Evening," "Movie," and "Guests" scenes in Lesson 10. Blind schedules come in Lesson 13: with helpers and conditions wired up to your own entity_id values.