Use playback state, then give the household a choice

A Home Assistant TV lights automation needs two things: a media-player entry that reports playback correctly, and permission to change the room. Check the first before adding lighting actions. Then use a dashboard switch to allow dimming for a film, instead of making every television session dark.

Start with one lamp you can already dim from Home Assistant. The walkthrough uses fixed brightness levels for playing, paused and stopped playback. It ignores uncertain states and lets a newer change cancel a pending response. First it reports what it would do; only after that check do you replace the preview with a light command.

If your TV only reports on and off, choose between a simple power-based backlight routine and a manual movie-lighting button. Neither can tell when somebody pauses a film. Do not build a play/pause rule around a state your device never reports. Home Assistant’s media-player state reference distinguishes these states.

Researched from current Home Assistant documentation on October 15, 2026. The example’s logic was checked in an isolated Home Assistant 2026.10.1 runtime with simulated states and recorded action calls. No physical television or lamp was connected; this is not a tested Tara installation. Menu names vary by installed release. The cover is an AI-generated editorial illustration.

1. Watch what your player actually reports

An entity is one control or reading in Home Assistant, identified by a name such as media_player.living_room. The television and its streaming box may have separate entries. An integration is the software connection that supplies those entries.

Open Settings → Tools → States in current versions; older versions call this Developer tools → States. Filter for the relevant media_player. entries. Use the normal TV remote to play a video, pause, resume, return to the app’s menu, and finish watching. Only read the States screen. Editing a state there can trigger real automations without changing the actual TV. See the Tools documentation.

Repeat with each app you intend to use. Write down the entry that best follows what is happening, rather than choosing the one with the nicest name.

On a narrow screen, scroll the table sideways.

What you observeWhat it tells youChoose this next step
Playing and paused follow the remote in the apps you useA usable playback signal for those observed appsTry the preview below. Check stop/menu behavior separately.
Only on and off, even while pausingPower information, without playback detailCheck the streaming-player or app integration; otherwise use a manual lighting button.
Playing stays stuck after returning to the menuThe source does not reliably describe that app sessionLeave automatic dimming disabled for that app. Do not treat a longer delay as a repair.
Brief buffering or idle changes between scenesThe source has interruptions or intermediate statesRehearse the delay and observe whether it filters them without making pause lighting too slow.

Android TV Remote has a specific limitation: it provides remote controls and power information, but no playback status. The official guide suggests using Google Cast alongside it for supported apps. Cast has its own limitations, including unreliable TV power information and apps without the required media support. Combining entries does not create information the apps never expose. See Android TV Remote and Google Cast behavior.

If you already use the Apple TV integration, start by observing its media-player entry. Its presence does not prove every streaming app will report every transition correctly. This guide makes no model-wide compatibility or response-time claim.

2. Add a visible permission switch

Go to Settings → Devices & services → Helpers → Create helper → Toggle. Name it TV lighting allowed and add it to your dashboard. A helper is a setting stored in Home Assistant; it needs no physical switch. Note its actual entity ID. The example uses input_boolean.tv_lighting_allowed.

Where your version offers More options → Each time Home Assistant starts, choose Turn off so a restart requires a fresh opt-in. Set the helper off now too: changing that startup option does not change its current value. Older versions may lack this UI option; the default is to restore the previous state. Do not assume a restart clears permission. See the Toggle helper configuration and restore behavior.

Turn the switch on when the household wants playback lighting, and off when finished. Switching it off stops this routine’s pending or future commands; it does not undo a command already sent. Turn it off before adjusting the lamp manually if you want that adjustment to stay. Other lighting routines also need to respect your choice; our manual-override guide explains that wider handoff.

3. Build a harmless playback preview

Under Settings → Automations & scenes, create a new empty automation. In its menu, choose Edit in YAML, the text form of the configuration. Paste the complete example below; it belongs in that automation editor, without an outer automation: line.

Replace media_player.living_room and input_boolean.tv_lighting_allowed everywhere with your actual IDs. Save and enable the automation, with the permission switch still off. This version creates only a message inside Home Assistant’s Notifications panel; it sends no lamp command or phone push.

On a narrow screen, scroll the code sideways to read long lines.

alias: TV lighting preview
mode: restart
triggers:
  - trigger: state
    entity_id:
      - media_player.living_room
      - input_boolean.tv_lighting_allowed
    to: null
conditions: []
actions:
  - condition: state
    entity_id: input_boolean.tv_lighting_allowed
    state: "on"
  - delay: "00:00:05"
  - condition: state
    entity_id: input_boolean.tv_lighting_allowed
    state: "on"
  - variables:
      playback: "{{ states('media_player.living_room') }}"
  - condition: template
    value_template: "{{ playback in ['playing', 'paused', 'idle', 'off'] }}"
  - variables:
      level: "{{ {'playing': 15, 'paused': 45, 'idle': 65, 'off': 65}[playback] }}"
  - action: persistent_notification.create
    data:
      notification_id: tv_lighting_preview
      title: TV lighting preview
      message: >-
        {{ now().strftime('%H:%M:%S') }} — {{ playback }}:
        would set the TV lamp to {{ level }}%.
        No light command was sent.

The fixed notification ID updates one preview message. Its timestamp helps distinguish a fresh result from an old one. That behavior comes from the Persistent Notification integration.

to: null watches changes of state while ignoring attribute-only updates, such as playback-position metadata. mode: restart replaces a pending run when another watched state changes. The permission checks sit inside the actions: an off event can cancel the previous wait before stopping at the check. See the state-trigger options and automation modes.

The five seconds is a chosen settling period after Home Assistant receives a state, not a measured end-to-end response time. Buffering, on, unknown and unavailable produce no new message. On recovery to a recognized state, the routine can run again if permission remains on. A restart or automation reload interrupts a pending run; there is no elapsed-time catch-up.

4. Rehearse a short viewing session

Use a harmless video and the normal remote. The following outcomes come from the example’s logic, not from hardware measurements.

Scroll sideways on a phone to see the expected result and what each check proves.

Try thisExpected previewWhat it checks
Permission off; play and pauseNo new message; any old message stays unchangedThe household can keep normal lighting.
Leave a video playing, then turn permission onAfter the settling period: playing, 15%Opting in works even when playback has already started.
Pause, then resume within three secondsNo 45% pause request; a later 15% message follows resumed playbackThe new state cancels the pending pause response.
Pause for longer than five secondsPaused, 45%A deliberate pause requests a brighter lamp.
Return to a menu that reports idle, or stop the player so it reports offIdle or off, 65%The example uses a fixed finished-viewing level.
Pause, then turn permission off during the waitNo fresh pause messageOpting out cancels a pending change.

If a row fails, first check the actual state and the automation’s trace, its record of executed steps. A stuck playing state is a source problem; a failed permission check is a configuration problem. Run actions can exercise the action sequence, but it does not test the real state trigger. The checks inside this example’s actions still apply. See testing automations and reading traces.

5. Connect one lamp after the preview agrees

Turn permission off. Choose a nonessential lamp already controllable as a dimmable light. entity, and check its ordinary brightness control. Keep exit routes and somebody else’s reading light outside this experiment.

In the same automation, replace the final persistent_notification.create step and its entire data: block with this step, keeping the earlier actions. Replace light.tv_lamp with your lamp’s ID. Rename the automation TV lighting.

  - action: light.turn_on
    target:
      entity_id: light.tv_lamp
    data:
      brightness_pct: "{{ level | int }}"

Save, then repeat the viewing-session checks while watching the lamp. This command can turn an off lamp on. Confirm that is what you want. The 15/45/65 values are brightness percentages; adjust them in the earlier mapping for your room. Check the physical result as well as the trace. The light turn-on action describes the brightness field.

These fixed levels make the finish predictable, but they do not restore your lamp’s previous setting. For that separate behavior, read saving and restoring a lighting snapshot, including its restart and interruption limits. Avoid adding temporary snapshots until the playback signal itself behaves well.

If the lamp brightens whenever an app briefly reports idle, lengthen the settling period modestly and rehearse again. If idle lasts through trailers or menus that you want to keep dim, this fixed mapping does not suit that app: leave permission off there or use a manual preset. If another automation keeps changing the same lamp, coordinate its permission checks rather than repeatedly sending competing brightness commands.

Common questions

Will this detect only movies, not music or previews?

No. Playing means media is playing; it does not identify a film. This example relies on your permission switch. App or media-type filters need separately verified attributes, and trailers may share those attributes with the main feature.

Does stopping the TV turn this permission switch off?

No. A recognized idle or off state requests 65% while permission is on. Turn the switch off after watching. The routine intentionally leaves the lamp on at that level; use its normal control when you want darkness.

Will this work without the internet?

The rule runs in Home Assistant, but the complete result depends on the media and lighting integrations. Internet streaming may stop even if local lamp control remains available. This recipe does not make a cloud-connected lamp local.

Start with a playback source you have observed, one lamp and the permission switch. When planning several rooms, Tara’s home automation kit with coordinated local routines is the relevant next step for agreeing which controls should work together.