Last active
August 13, 2025 08:18
-
-
Save bullshit/443416eacec1f7aca19cfb40e1565de9 to your computer and use it in GitHub Desktop.
Automatically controls TV volume based on time and door status.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
blueprint: | |
name: Smart TV Volume Control with Door Logic | |
description: > | |
Automatically controls TV volume based on time and door status. | |
**Day Time (07:00-22:00):** Unlimited volume regardless of door status. | |
**Night Time (22:00-07:00):** | |
- Door closed: Maximum volume configurable (default 20%) | |
- Door open: Lower maximum volume configurable (default 10%) | |
When door opens during night, it stores current volume and restores it when door closes (respecting night limits). | |
domain: automation | |
input: | |
media_player_entity: | |
name: Media Player | |
description: The TV or media player to control | |
selector: | |
entity: | |
domain: media_player | |
door_sensor: | |
name: Door/Window Sensor | |
description: Binary sensor that detects if door/window is open | |
selector: | |
entity: | |
domain: binary_sensor | |
night_start_time: | |
name: Night Start Time | |
description: When night mode begins (volume restrictions start) | |
default: "22:00:00" | |
selector: | |
time: | |
day_start_time: | |
name: Day Start Time | |
description: When day mode begins (volume restrictions end) | |
default: "07:00:00" | |
selector: | |
time: | |
night_volume_door_closed: | |
name: Night Volume (Door Closed) | |
description: Maximum volume when door is closed during night (0.0-1.0) | |
default: 0.20 | |
selector: | |
number: | |
min: 0.0 | |
max: 1.0 | |
step: 0.01 | |
mode: slider | |
night_volume_door_open: | |
name: Night Volume (Door Open) | |
description: Maximum volume when door is open during night (0.0-1.0) | |
default: 0.10 | |
selector: | |
number: | |
min: 0.0 | |
max: 1.0 | |
step: 0.01 | |
mode: slider | |
volume_memory_helper: | |
name: Volume Memory Helper | |
description: > | |
Input number helper to store volume before door opens. | |
Create one via Settings → Helpers → Number (min: 0, max: 1, step: 0.01) | |
selector: | |
entity: | |
domain: input_number | |
enable_logging: | |
name: Enable Logging | |
description: Log volume changes to the logbook | |
default: true | |
selector: | |
boolean: | |
variables: | |
night_vol_closed: !input night_volume_door_closed | |
night_vol_open: !input night_volume_door_open | |
memory_entity: !input volume_memory_helper | |
logging_enabled: !input enable_logging | |
trigger: | |
# Trigger when media player volume changes | |
- entity_id: !input media_player_entity | |
attribute: volume_level | |
trigger: state | |
id: volume_changed | |
# Trigger when media player turns on | |
- entity_id: !input media_player_entity | |
trigger: state | |
to: | |
- "on" | |
- "playing" | |
- "paused" | |
id: tv_turned_on | |
# Trigger at night time start | |
- trigger: time | |
at: !input night_start_time | |
id: night_start | |
# Trigger when door opens | |
- trigger: state | |
entity_id: !input door_sensor | |
to: "on" | |
id: door_opened | |
# Trigger when door closes | |
- trigger: state | |
entity_id: !input door_sensor | |
to: "off" | |
id: door_closed | |
condition: | |
# Only run if media player is on/playing | |
- condition: not | |
conditions: | |
- condition: state | |
entity_id: !input media_player_entity | |
state: "off" | |
# Only run during night hours | |
- condition: or | |
conditions: | |
- condition: time | |
after: !input night_start_time | |
- condition: time | |
before: !input day_start_time | |
action: | |
- variables: | |
media_player_entity: !input media_player_entity | |
door_sensor: !input door_sensor | |
current_volume: "{{ state_attr(media_player_entity, 'volume_level') | float(0) }}" | |
door_is_open: "{{ is_state(door_sensor, 'on') }}" | |
volume_limit: >- | |
{% if door_is_open %} | |
{{ night_vol_open }} | |
{% else %} | |
{{ night_vol_closed }} | |
{% endif %} | |
- choose: | |
# === DOOR OPENED DURING NIGHT === | |
- conditions: | |
- condition: trigger | |
id: door_opened | |
sequence: | |
- if: | |
- condition: template | |
value_template: "{{ current_volume > night_vol_open }}" | |
then: | |
# Store current volume and reduce it | |
- action: input_number.set_value | |
target: | |
entity_id: "{{ memory_entity }}" | |
data: | |
value: "{{ current_volume }}" | |
- action: media_player.volume_set | |
target: | |
entity_id: "{{ media_player_entity }}" | |
data: | |
volume_level: "{{ night_vol_open }}" | |
# Optional logging | |
- if: | |
- condition: template | |
value_template: "{{ logging_enabled }}" | |
then: | |
- action: logbook.log | |
data: | |
name: "Smart TV Volume Control" | |
message: "Door opened: Volume limited to {{ (night_vol_open * 100) | round }}%" | |
entity_id: "{{ media_player_entity }}" | |
else: | |
# Volume is already low enough, clear memory to prevent restoration | |
- action: input_number.set_value | |
target: | |
entity_id: "{{ memory_entity }}" | |
data: | |
value: 0 | |
# === DOOR CLOSED DURING NIGHT === | |
- conditions: | |
- condition: trigger | |
id: door_closed | |
sequence: | |
- variables: | |
stored_volume: "{{ states(memory_entity) | float(0) }}" | |
# Only restore if we actually stored a meaningful volume | |
- if: | |
- condition: template | |
value_template: "{{ stored_volume > 0 }}" | |
then: | |
- variables: | |
restore_volume: "{{ [stored_volume, night_vol_closed] | min }}" | |
- action: media_player.volume_set | |
target: | |
entity_id: "{{ media_player_entity }}" | |
data: | |
volume_level: "{{ restore_volume }}" | |
# Optional logging | |
- if: | |
- condition: template | |
value_template: "{{ logging_enabled }}" | |
then: | |
- action: logbook.log | |
data: | |
name: "Smart TV Volume Control" | |
message: "Door closed: Volume restored to {{ (restore_volume * 100) | round }}%" | |
entity_id: "{{ media_player_entity }}" | |
# === VOLUME LIMITING (other triggers) === | |
- conditions: | |
- condition: template | |
value_template: "{{ current_volume > (volume_limit | float) }}" | |
sequence: | |
- action: media_player.volume_set | |
target: | |
entity_id: "{{ media_player_entity }}" | |
data: | |
volume_level: "{{ volume_limit }}" | |
# Optional logging | |
- if: | |
- condition: template | |
value_template: "{{ logging_enabled }}" | |
then: | |
- action: logbook.log | |
data: | |
name: "Smart TV Volume Control" | |
message: >- | |
Volume limited to {{ (volume_limit | float * 100) | round }}% | |
(door {{ 'open' if door_is_open else 'closed' }}) | |
entity_id: "{{ media_player_entity }}" | |
mode: restart |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment