-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAuto Off Timer
More file actions
206 lines (187 loc) · 6.66 KB
/
Copy pathAuto Off Timer
File metadata and controls
206 lines (187 loc) · 6.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
blueprint:
name: Auto-Off After X Time (Restart-Safe)
description: >
Turns a device off a set amount of time after it turns on — no matter
what turned it on (an automation, a schedule, a dashboard tap, or the
physical button on the device). Unlike a plain "for:" trigger, this
survives a Home Assistant restart: instead of counting elapsed time in
memory, it writes the actual clock time the device should turn off into
an input_datetime helper, and schedules off of that. If HA happens to be
down through the entire window, a catch-up check at startup turns the
device off immediately instead of missing it.
REQUIRED SETUP: before using this blueprint, create an input_datetime
helper for this device (Settings > Devices & services > Helpers >
Create helper > Date and/or time). Check BOTH "Date" and "Time" — a
time-only helper does not reliably hold a future timestamp across a
restart. Create one helper per device you use this blueprint on.
domain: automation
input:
target_entity:
name: Device
description: The single entity to auto-off. Duplicate this automation (with its own helper) for additional devices.
selector:
entity:
domain:
- light
- switch
- fan
- climate
- humidifier
- media_player
- siren
- valve
- water_heater
- remote
- input_boolean
- cover
- lock
helper_datetime:
name: Off-time helper
description: >
An input_datetime helper (with both Date and Time enabled) dedicated
to this device. This blueprint writes the scheduled off-time into
it. Create one per device — don't share a single helper across
multiple instances of this blueprint.
selector:
entity:
domain: input_datetime
auto_off_time:
name: Turn off after
description: How long the device should stay "on" before it's turned off.
default:
hours: 0
minutes: 15
seconds: 0
selector:
duration: {}
send_warning:
name: Send a warning first?
description: >
Optional, best-effort only. This warning is NOT restart-safe (it
uses a simple timer, same as the old approach) — if HA restarts
during the warning window, the warning may be skipped. The
turn-off itself is unaffected and still happens reliably.
default: false
selector:
boolean: {}
warning_time:
name: Warning lead time
description: How long after the device turns on to run the warning action. Must be shorter than "Turn off after".
default:
hours: 0
minutes: 1
seconds: 0
selector:
duration: {}
warning_action:
name: Warning action
description: >
What to do when the warning fires. Defaults to a persistent
notification. Replace with a mobile app notify action, a light
flash, a TTS announcement, etc.
default:
- action: persistent_notification.create
data:
title: Auto-off warning
notification_id: "autooff_warning"
message: >-
{{ state_attr(target_entity, 'friendly_name') or target_entity }} will turn off soon.
selector:
action: {}
turnoff_condition:
name: Condition to allow turn-off
description: >
Advanced. A template that must evaluate to "true" for the turn-off
to actually happen. Leave as "true" to always turn off. Example: to
skip turning off a media player while it's actively playing, use
"{{ is_state(target_entity, 'playing') == false }}".
default: "true"
selector:
template: {}
turnoff_action:
name: Turn-off action
description: >
What "off" means for this device. Defaults to the generic
homeassistant.turn_off service. Override for entities that don't
support it, e.g. cover.close_cover for a cover, or lock.lock for a
lock. The device is available as {{ target_entity }}.
default:
- action: homeassistant.turn_off
target:
entity_id: "{{ target_entity }}"
selector:
action: {}
variables:
target_entity: !input target_entity
off_helper: !input helper_datetime
auto_off_duration: !input auto_off_time
mode: parallel
max: 10
max_exceeded: silent
trigger:
- id: schedule
trigger: state
entity_id: !input target_entity
to: "on"
- id: warn
trigger: state
entity_id: !input target_entity
to: "on"
for: !input warning_time
enabled: !input send_warning
- id: execute
trigger: time
at: !input helper_datetime
- id: catchup
trigger: homeassistant
event: start
condition: []
action:
- choose:
# Device just turned on: write the real clock time it should turn off at.
- conditions:
- condition: trigger
id: schedule
sequence:
- action: input_datetime.set_datetime
target:
entity_id: "{{ off_helper }}"
data:
datetime: >-
{{ (now() + timedelta(
hours=auto_off_duration.hours | default(0, true),
minutes=auto_off_duration.minutes | default(0, true),
seconds=auto_off_duration.seconds | default(0, true)
)).strftime('%Y-%m-%d %H:%M:%S') }}
# Best-effort warning before turn-off (not restart-safe).
- conditions:
- condition: trigger
id: warn
sequence: !input warning_action
# The scheduled off-time was reached normally.
- conditions:
- condition: trigger
id: execute
sequence:
- condition: state
entity_id: !input target_entity
state: "on"
- condition: template
value_template: !input turnoff_condition
- sequence: !input turnoff_action
# HA just started up: catch up if the off-time already passed while it was down.
- conditions:
- condition: trigger
id: catchup
sequence:
- condition: state
entity_id: !input target_entity
state: "on"
- condition: template
value_template: >-
{{ states(off_helper) not in ['unknown', 'unavailable', 'none']
and state_attr(off_helper, 'timestamp') is not none
and state_attr(off_helper, 'timestamp') <= now().timestamp() }}
- condition: template
value_template: !input turnoff_condition
- sequence: !input turnoff_action