I’ve already been plugging in data from my Emporia Vue, which reads the meter from Southern California Edison and allows me to query my usage in kW/h from Home Assistant. I now need to calculate cost, which is variable based on what SCE calls TOU (Time Of Use).
This essentially means peak hours (typically 4PM - 9PM) have higher rates than off-peak. I broke this problem down into 3 entities to solve:
- TOU Season (Summer vs Winter)
- TOU Peak (Current hourly block)
- TOU Cost ($ per kW/h)
I can use Cost as the dynamic entity in our Energy Usage dashboard. This, combined with the kW/h reading, can be used to calculate total energy costs per day.
This defines the 3 entities in my sce.yaml
. If you’re copying this, plug your peak costs into the last few lines of this snippet. You can find updated rates here:
https://www.sce.com/residential/rates/Time-Of-Use-Residential-Rate-Plans
template:
- sensor:
- name: "TOU Season"
state: "{{ ['Winter', 'Summer'][now().month >= 6 and now().month < 10] }}"
icon: mdi:weather-cloudy-clock
- sensor:
- name: "TOU Peak"
icon: mdi:calendar-clock
state: >
{% set is_weekend = now().strftime("%w") == 0 or now().strftime("%w") == 6 %}
{% if states('sensor.tou_season') == "Summer" %}
{% if now().hour >= 16 and now().hour < 21 %}
{% if is_weekend %}
{{ "Mid-Peak" }}
{% else %}
{{ "On-Peak" }}
{% endif %}
{% else %}
{{ "Off-Peak" }}
{% endif %}
{% else %}
{% if now().hour >= 16 and now().hour < 21 %}
{{ "Mid-Peak" }}
{% elif now().hour >= 21 or now().hour < 8 %}
{{ "Off-Peak" }}
{% else %}
{{ "Super Off-Peak" }}
{% endif %}
{% endif %}
- sensor:
- name: "TOU Cost"
icon: mdi:currency-usd
device_class: monetary
state: >
{% if states('sensor.tou_season') == "Summer" %}
{{ {"Off-Peak": 0.15, "On-Peak": 0.41, "Mid-Peak": 0.30}[states('sensor.tou_peak')] }}
{% else %}
{{ {"Super Off-Peak": 0.15, "Off-Peak": 0.15, "Mid-Peak": 0.38}[states('sensor.tou_peak')] }}
{% endif %}
Updated values for Option 1 TOUD-5-8PM:
template:
- sensor:
- name: "TOU Season"
state: "{{ ['Winter', 'Summer'][now().month >= 6 and now().month < 10] }}"
icon: mdi:weather-cloudy-clock
- sensor:
- name: "TOU Peak"
icon: mdi:calendar-clock
state: >
{% set is_weekend = now().strftime("%w") == 0 or now().strftime("%w") == 6 %}
{% if states('sensor.tou_season') == "Summer" %}
{% if now().hour >= 17 and now().hour < 20 %}
{% if is_weekend %}
{{ "Mid-Peak" }}
{% else %}
{{ "On-Peak" }}
{% endif %}
{% else %}
{{ "Off-Peak" }}
{% endif %}
{% else %}
{% if now().hour >= 17 and now().hour < 20 %}
{{ "Mid-Peak" }}
{% elif now().hour >= 20 or now().hour < 8 %}
{{ "Off-Peak" }}
{% else %}
{{ "Super Off-Peak" }}
{% endif %}
{% endif %}
- sensor:
- name: "TOU Cost"
icon: mdi:currency-usd
device_class: monetary
state: >
{% if states('sensor.tou_season') == "Summer" %}
{{ {"Off-Peak": 0.33, "On-Peak": 0.67, "Mid-Peak": 0.50}[states('sensor.tou_peak')] }}
{% else %}
{{ {"Super Off-Peak": 0.32, "Off-Peak": 0.36, "Mid-Peak": 0.55}[states('sensor.tou_peak')] }}
{% endif %}