Skip to content

Instantly share code, notes, and snippets.

@lparry
Last active April 23, 2026 02:15
Show Gist options
  • Select an option

  • Save lparry/34d1f94710bd366628e5aa6c8b9a0152 to your computer and use it in GitHub Desktop.

Select an option

Save lparry/34d1f94710bd366628e5aa6c8b9a0152 to your computer and use it in GitHub Desktop.
Appliance Cycle Power Usage
blueprint:
name: Appliance Cycle Power Usage
description: >-
Detects an appliance cycle start/end from power usage, calculates
energy and cost, and sends a notification. Fixed version with correct
variable references and adjustable cycle cooldown.
domain: automation
input:
appliance_name:
name: Appliance name
description: Used in notification text (e.g. Dishwasher, Washing Machine)
default: Appliance
selector:
text:
multiline: false
multiple: false
power_sensor:
name: Power sensor
description: Sensor reporting instantaneous power (W)
selector:
entity:
domain:
- sensor
reorder: false
multiple: false
energy_sensor:
name: Energy sensor
description: Sensor reporting cumulative energy (kWh)
selector:
entity:
domain:
- sensor
reorder: false
multiple: false
energy_start_helper:
name: Energy start helper
description: input_number used to store starting energy reading
selector:
entity:
domain:
- input_number
reorder: false
multiple: false
start_threshold:
name: Start threshold (W)
description: Power above this means the cycle has started
default: 100
selector:
number:
min: 0.0
max: 2000.0
step: 1.0
mode: slider
idle_threshold:
name: Idle threshold (W)
description: Power below this (for a while) means the cycle is finished
default: 5
selector:
number:
min: 0.0
max: 200.0
step: 1.0
mode: slider
idle_time:
name: Idle duration
description: How long power must stay below idle threshold to complete. (Set to 40+ mins for Dishwashers).
default: 00:05:00
selector:
duration: {}
cooldown_time:
name: Cycle Cooldown (Seconds)
description: Minimum time between cycle starts. Set this HIGHER than your appliance's longest possible cycle to prevent resetting mid-cycle.
default: 14400
selector:
number:
min: 0
max: 86400
step: 300
mode: slider
energy_price:
name: Energy price ($/kWh)
description: Used to estimate cycle cost
default: 0.3
selector:
number:
min: 0.0
max: 2.0
step: 0.01
mode: slider
notify_target:
name: Notification target
description: "Notify service to call, e.g. 'family_phones' for notify.family_phones"
selector:
text:
multiline: false
multiple: false
mode: single
variables:
appliance_name: !input appliance_name
power_sensor: !input power_sensor
energy_sensor: !input energy_sensor
energy_start_helper: !input energy_start_helper
start_threshold: !input start_threshold
idle_threshold: !input idle_threshold
idle_time: !input idle_time
cooldown_time: !input cooldown_time
energy_price: !input energy_price
notify_target: !input notify_target
trigger:
- id: cycle_start
platform: numeric_state
entity_id: !input power_sensor
above: !input start_threshold
- id: cycle_complete
platform: numeric_state
entity_id: !input power_sensor
below: !input idle_threshold
for: !input idle_time
action:
- choose:
- conditions:
- condition: trigger
id: cycle_start
sequence:
- condition: template
value_template: >-
{{ (now() - states[energy_start_helper].last_changed).total_seconds() > (cooldown_time | int) }}
- service: input_number.set_value
target:
entity_id: !input energy_start_helper
data:
value: "{{ states(energy_sensor) | float(0) }}"
- conditions:
- condition: trigger
id: cycle_complete
sequence:
- variables:
energy_start: "{{ states(energy_start_helper) | float(0) }}"
energy_now: "{{ states(energy_sensor) | float(0) }}"
energy_used: "{{ (energy_now - energy_start) | float(0) }}"
cost: "{{ (energy_used * energy_price) | float(0) }}"
- service: "notify.{{ notify_target }}"
data:
title: "{{ appliance_name }} cycle complete"
message: "{{ appliance_name }} cycle finished. Energy used: {{ energy_used | round(2) }} kWh. Estimated cost: ${{ cost | round(2) }}. "
- service: input_number.set_value
target:
entity_id: !input energy_start_helper
data:
value: "{{ energy_now }}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment