I’d like to share with the community the new template sensor I’m working on in order to have some statistics from Tibber future electricity prices (and it can easily be adapted to other similar sensors, aka NordPool).
Why am I working on this?
I’m not there yet, but my goal is to find the best time to run appliances based on the known future prices of electricity. Let say my dishwasher takes 0.25kWh in the eco mode (3 hours + 1 drying, where the power consumption is irrelevant) and 0.45kWh in the express mode (1 hour). I’d like to create a Blueprint to find the best program to run and run it at the right time.
But this is to the near future… I still not there yet (and any inspiration will be very welcome).
Dependences:
You have to create a rest sensor based on this example from @p1ranha:
What is currently available?
For now, I have created a sensor to give me some statistics from the available future price info (the rest of today and tomorrow, when available).
With the current capabilities, the sensor is returning the status of the sensor.tibber_prices and adding to that the following attributes:
- future_prices: A list with times and prices, filtered only to the prices in the future (the past prices are removed).
- current_price: The same as your Tibber’s sensor current price, but extracted from the list, so there is a possibility that rounding makes a bit of a difference if you compare both.
- min: The lowest price between all the future information available.
- max: The highest price between all the future information available.
- average: The average price between all the future information available.
- current_price_level: The price level as defined by Tibber (please see table bellow), but instead of using the past 3 days of data to calculate the average, it will use the future prices for the average and compare the current price against that.
- min_3h, min_4h, min_6h, min_8h, min_12h, min_16h, min_24h, max_3h, max_4h, …, average_24h, …, current_price_level_24h: the same as above, but instead of using all the future prices on the average calculation, it will use only the time interval (3h, 4h, 6h, 8h, 12h, 16h or 24h) indicated.
These are the price levels as defined by Tibber (copied from this post from @Naesstrom, but also available on Tibber’s api documentation):
There’s more to come, but please test what is currently available, if you can, and provide some feedback.
template:
- sensor:
- name: Tibber future statistics
state: "{{ states('sensor.tibber_prices') }}"
attributes:
all_prices: "{{ (state_attr('sensor.tibber_prices', 'today') + state_attr('sensor.tibber_prices', 'tomorrow')) }}"
future_prices: "{{ state_attr('sensor.tibber_future_statistics', 'all_prices') | selectattr('startsAt', 'gt', (now() - timedelta(hours=1)) | string | replace(' ','T')) | list }}"
current_price: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', now() | string | replace(' ','T')) | map(attribute='total') | first | float(0) }} "
min: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | map(attribute='total') | min | float(0) }}"
max: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | map(attribute='total') | max | float(0) }}"
average: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | map(attribute='total') | average | float(0) }}"
current_price_level: >-
{% set price_cur = state_attr('sensor.tibber_future_statistics', 'current_price') | float(0) %}
{% set price_avg = state_attr('sensor.tibber_future_statistics', 'average') | float(0) %}
{% if price_cur == 0 or price_avg == 0 %}
unknown
{% else %}
{% set price_ratio = (price_cur / price_avg) %}
{% if price_ratio >= 1.4 %}
VERY_EXPENSIVE
{% elif price_ratio >= 1.15 %}
EXPENSIVE
{% elif price_ratio <= 0.6 %}
VERY_CHEAP
{% elif price_ratio <= 0.9 %}
CHEAP
{% else %}
NORMAL
{% endif %}
{% endif %}
min_3h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=2)) | string | replace(' ','T')) | map(attribute='total') | min | float(0) }}"
max_3h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=2)) | string | replace(' ','T')) | map(attribute='total') | max | float(0) }}"
avg_3h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=2)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) }}"
current_price_level_3h: >-
{% set price_cur = state_attr('sensor.tibber_future_statistics', 'current_price') | float(0) %}
{% set price_avg = state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=2)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) %}
{% if price_cur == 0 or price_avg == 0 %}
unknown
{% else %}
{% set price_ratio = (price_cur / price_avg) %}
{% if price_ratio >= 1.4 %}
VERY_EXPENSIVE
{% elif price_ratio >= 1.15 %}
EXPENSIVE
{% elif price_ratio <= 0.6 %}
VERY_CHEAP
{% elif price_ratio <= 0.9 %}
CHEAP
{% else %}
NORMAL
{% endif %}
{% endif %}
min_4h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=3)) | string | replace(' ','T')) | map(attribute='total') | min | float(0) }}"
max_4h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=3)) | string | replace(' ','T')) | map(attribute='total') | max | float(0) }}"
avg_4h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=3)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) }}"
current_price_level_4h: >-
{% set price_cur = state_attr('sensor.tibber_future_statistics', 'current_price') | float(0) %}
{% set price_avg = state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=3)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) %}
{% if price_cur == 0 or price_avg == 0 %}
unknown
{% else %}
{% set price_ratio = (price_cur / price_avg) %}
{% if price_ratio >= 1.4 %}
VERY_EXPENSIVE
{% elif price_ratio >= 1.15 %}
EXPENSIVE
{% elif price_ratio <= 0.6 %}
VERY_CHEAP
{% elif price_ratio <= 0.9 %}
CHEAP
{% else %}
NORMAL
{% endif %}
{% endif %}
min_6h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=5)) | string | replace(' ','T')) | map(attribute='total') | min | float(0) }}"
max_6h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=5)) | string | replace(' ','T')) | map(attribute='total') | max | float(0) }}"
avg_6h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=5)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) }}"
current_price_level_6h: >-
{% set price_cur = state_attr('sensor.tibber_future_statistics', 'current_price') | float(0) %}
{% set price_avg = state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=5)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) %}
{% if price_cur == 0 or price_avg == 0 %}
unknown
{% else %}
{% set price_ratio = (price_cur / price_avg) %}
{% if price_ratio >= 1.4 %}
VERY_EXPENSIVE
{% elif price_ratio >= 1.15 %}
EXPENSIVE
{% elif price_ratio <= 0.6 %}
VERY_CHEAP
{% elif price_ratio <= 0.9 %}
CHEAP
{% else %}
NORMAL
{% endif %}
{% endif %}
min_8h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=7)) | string | replace(' ','T')) | map(attribute='total') | min | float(0) }}"
max_8h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=7)) | string | replace(' ','T')) | map(attribute='total') | max | float(0) }}"
avg_8h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=7)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) }}"
current_price_level_8h: >-
{% set price_cur = state_attr('sensor.tibber_future_statistics', 'current_price') | float(0) %}
{% set price_avg = state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=7)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) %}
{% if price_cur == 0 or price_avg == 0 %}
unknown
{% else %}
{% set price_ratio = (price_cur / price_avg) %}
{% if price_ratio >= 1.4 %}
VERY_EXPENSIVE
{% elif price_ratio >= 1.15 %}
EXPENSIVE
{% elif price_ratio <= 0.6 %}
VERY_CHEAP
{% elif price_ratio <= 0.9 %}
CHEAP
{% else %}
NORMAL
{% endif %}
{% endif %}
min_12h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=11)) | string | replace(' ','T')) | map(attribute='total') | min | float(0) }}"
max_12h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=11)) | string | replace(' ','T')) | map(attribute='total') | max | float(0) }}"
avg_12h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=11)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) }}"
current_price_level_12h: >-
{% set price_cur = state_attr('sensor.tibber_future_statistics', 'current_price') | float(0) %}
{% set price_avg = state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=11)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) %}
{% if price_cur == 0 or price_avg == 0 %}
unknown
{% else %}
{% set price_ratio = (price_cur / price_avg) %}
{% if price_ratio >= 1.4 %}
VERY_EXPENSIVE
{% elif price_ratio >= 1.15 %}
EXPENSIVE
{% elif price_ratio <= 0.6 %}
VERY_CHEAP
{% elif price_ratio <= 0.9 %}
CHEAP
{% else %}
NORMAL
{% endif %}
{% endif %}
min_16h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=15)) | string | replace(' ','T')) | map(attribute='total') | min | float(0) }}"
max_16h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=15)) | string | replace(' ','T')) | map(attribute='total') | max | float(0) }}"
avg_16h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=15)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) }}"
current_price_level_16h: >-
{% set price_cur = state_attr('sensor.tibber_future_statistics', 'current_price') | float(0) %}
{% set price_avg = state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=15)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) %}
{% if price_cur == 0 or price_avg == 0 %}
unknown
{% else %}
{% set price_ratio = (price_cur / price_avg) %}
{% if price_ratio >= 1.4 %}
VERY_EXPENSIVE
{% elif price_ratio >= 1.15 %}
EXPENSIVE
{% elif price_ratio <= 0.6 %}
VERY_CHEAP
{% elif price_ratio <= 0.9 %}
CHEAP
{% else %}
NORMAL
{% endif %}
{% endif %}
min_24h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=23)) | string | replace(' ','T')) | map(attribute='total') | min | float(0) }}"
max_24h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=23)) | string | replace(' ','T')) | map(attribute='total') | max | float(0) }}"
avg_24h: "{{ state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=23)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) }}"
current_price_level_24h: >-
{% set price_cur = state_attr('sensor.tibber_future_statistics', 'current_price') | float(0) %}
{% set price_avg = state_attr('sensor.tibber_future_statistics', 'future_prices') | selectattr('startsAt', 'lt', (now() + timedelta(hours=23)) | string | replace(' ','T')) | map(attribute='total') | average | float(0) %}
{% if price_cur == 0 or price_avg == 0 %}
unknown
{% else %}
{% set price_ratio = (price_cur / price_avg) %}
{% if price_ratio >= 1.4 %}
VERY_EXPENSIVE
{% elif price_ratio >= 1.15 %}
EXPENSIVE
{% elif price_ratio <= 0.6 %}
VERY_CHEAP
{% elif price_ratio <= 0.9 %}
CHEAP
{% else %}
NORMAL
{% endif %}
{% endif %}