I’ve stopped using the “normal Tibber integration”, not because I have a conflict, but because that is not needed after a couple of modifications on @p1ranha’s REST sensor in order to add the current price on its state (instead of an “OK”):
sensor:
# https://community.home-assistant.io/t/tibber-sensor-for-future-price-tomorrow/253818/23
- platform: rest
name: Tibber Electricity Price
resource: https://api.tibber.com/v1-beta/gql
method: POST
scan_interval: 900
payload: '{ "query": "{ viewer { homes { currentSubscription { priceInfo { current { total currency level } today { total startsAt level } tomorrow { total startsAt level }}}}}}" }'
json_attributes_path: "$.data.viewer.homes[0].currentSubscription.priceInfo"
json_attributes:
- current
- today
- tomorrow
value_template: '{{ value_json["data"]["viewer"]["homes"][0]["currentSubscription"]["priceInfo"]["current"]["total"] }}'
headers:
Authorization: !secret tibber_api_token
Content-Type: application/json
User-Agent: REST
This doesn’t have the consumption statistics as the “official” integration and also doesn’t have the price level (for witch I have a template sensor to calculate, but also would be easy to add in this sensor if you don’t wanna have another sensor).
PS: Note I’m using 900 sec (15min) as scan interval, which is working fine for me and prevents taking too long to fetching for the new price when a new hour starts (this could be easily solved by a template sensor).
This is the other template sensor I’ve mentioned. It probably needs a review/clean up as I’m sure I’m not using half of those attributes available.
The result of this sensor is what I use for my energy dashboard, as if updates the current rate faster than the REST sensor (thanks to the longer scan interval I’ve used there):
template:
- sensor:
- name: Electricity price
unique_id: d4c04abf-c258-4f0f-a61d-cc0170225081
unit_of_measurement: "SEK/kWh"
icon: mdi:currency-usd
state: >-
{% if this.attributes.future_prices | default('unknown') in ['unknown', 'unavailable'] or (this.attributes.future_prices | default([]) | map(attribute='total') | list | count) < 1 %}
unknown
{% else %}
{{ this.attributes.future_prices | default([]) | map(attribute='total') | list | first | float(0) }}
{% endif %}
attributes:
current: >-
{% if state_attr('sensor.tibber_electricity_price', 'current') %}
{{ state_attr('sensor.tibber_electricity_price', 'current') }}
{% else %}
[ ]
{% endif %}
today: >-
{% if state_attr('sensor.tibber_electricity_price', 'today') %}
{{ state_attr('sensor.tibber_electricity_price', 'today') }}
{% else %}
[ ]
{% endif %}
tomorrow: >-
{% if state_attr('sensor.tibber_electricity_price', 'tomorrow') %}
{{ state_attr('sensor.tibber_electricity_price', 'tomorrow') }}
{% else %}
[ ]
{% endif %}
all_prices: "{{ this.attributes.today | default([]) + this.attributes.tomorrow | default([]) }}"
#today_count: "{{ this.attributes.today | default([]) | map(attribute='total') | list | count }}"
#tomorrow_count: "{{ this.attributes.tomorrow | default([]) | map(attribute='total') | list | count }}"
#all_prices_count: "{{ this.attributes.all_prices | default([]) | map(attribute='total') | list | count }}"
min_price: >-
{% if this.attributes.today | default('unknown') in ['unknown','unavailable','none'] or (this.attributes.today | default([]) | map(attribute='total') | list | count) < 1 %}
unknown
{% else %}
{{ this.attributes.today | default([0]) | map(attribute='total') | list | min | float(0) | round(4) }}
{% endif %}
max_price: >-
{% if this.attributes.today | default('unknown') in ['unknown','unavailable','none'] or (this.attributes.today | default([]) | map(attribute='total') | list | count) < 1 %}
unknown
{% else %}
{{ this.attributes.today | default([0]) | map(attribute='total') | list | max | float(0) | round(4) }}
{% endif %}
avg_price: >-
{% if this.attributes.today | default('unknown') in ['unknown','unavailable','none'] or (this.attributes.today | default([]) | map(attribute='total') | list | count) < 1 %}
unknown
{% elif (this.attributes.today | default([]) | map(attribute='total') | list | count) < 2 %}
{{ this.attributes.today | default([0]) | map(attribute='total') | list | max | float(0) | round(4) }}
{% else %}
{{ this.attributes.today | default([0]) | map(attribute='total') | list | average(0) | float(0) | round(4) }}
{% endif %}
price_level: >-
{% if (this.attributes.current | default('unknown')) in ['unknown','unavailable','none'] %}
unknown
{% else %}
{{ this.attributes.current.level | default('unknown') | replace('_', ' ') | capitalize }}
{% endif %}
price_level_1d: >-
{% set price_cur = this.state | default(0) | float(0) %}
{% set price_avg = this.attributes.avg_price | default(0) | 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 %}
price_level_combined: >-
{% set level1 = this.attributes.price_level_1d | default('unknown') %}
{% set level3 = this.attributes.price_level | default('unknown') %}
{% if level1 == level3 %}
{{ level1 }}
{% elif level1 in ['unknown','unavailable','none'] or level3 in ['unknown','unavailable','none'] %}
unknown
{% elif level1 == "Very cheap" %}
{{ level3 }}
{% elif level3 == "Very cheap" %}
{{ level1 }}
{% elif level1 == "Cheap" %}
{{ level3 }}
{% elif level3 == "Cheap" %}
{{ level1 }}
{% elif level1 == "Normal" %}
{{ level3 }}
{% elif level3 == "Normal" %}
{{ level1 }}
{% elif level1 == "Expensive" %}
{{ level3 }}
{% else %}
{{ level1 }}
{% endif %}
is_below_average: >-
{% if is_number(this.state) and is_number(this.attributes.avg_price) %}
{{ (this.state | float(0) < this.attributes.avg_price | float(0)) | lower }}
{% else %}
unknown
{% endif %}
is_above_average: >-
{% if is_number(this.state) and is_number(this.attributes.avg_price) %}
{{ (this.state | float(0) > this.attributes.avg_price | float(0)) | lower}}
{% else %}
unknown
{% endif %}
is_at_min: >-
{% if is_number(this.state) and is_number(this.attributes.min_price) %}
{{ (this.state | float(0) <= this.attributes.min_price | float(0)) | lower }}
{% else %}
unknown
{% endif %}
is_at_max: >-
{% if is_number(this.state) and is_number(this.attributes.max_price) %}
{{ (this.state | float(0) >= this.attributes.max_price | float(0)) | lower }}
{% else %}
unknown
{% endif %}
is_close_to_min: >-
{% if is_number(this.state) and is_number(this.attributes.min_price) %}
{{ (this.state | float(0) <= (1.15 * this.attributes.min_price | float(0))) | lower }}
{% else %}
unknown
{% endif %}
future_prices: >-
{% if (this.attributes.all_prices | default('unknown')) in ['unknown','unavailable','none'] %}
unknown
{% else %}
{{ (this.attributes.all_prices | default([])) | selectattr('startsAt', 'gt', (now() - timedelta(hours=1)) | string | replace(' ','T')) | list }}
{% endif %}
future_prices_totals: >-
{% if (this.attributes.future_prices | default('unknown')) in ['unknown','unavailable','none'] %}
unknown
{% else %}
{{ (this.attributes.future_prices | default([])) | map(attribute='total') | list }}
{% endif %}
#future_prices_count: "{{ (this.attributes.future_prices_totals | default([])) | count }}"
future_prices_min: |-
{% if this.attributes.future_prices_totals | default([0]) | count > 0 %}
{{ this.attributes.future_prices_totals | default([0]) | min | float(0) | round(4) }}
{% else %}
unknown
{% endif %}
future_prices_max: |-
{% if this.attributes.future_prices_totals | default([0]) | count > 0 %}
{{ (this.attributes.future_prices_totals | default([0])) | max | float(0) | round(4) }}
{% else %}
unknown
{% endif %}
future_prices_avg: >-
{% if this.attributes.future_prices_totals | default([0]) | count > 0 %}
{{ (this.attributes.future_prices_totals | default([0])) | average(0) | float(0) | round(4) }}
{% else %}
unknown
{% endif %}
future_prices_curr_price_level: >-
{% set price_cur = this.state | default(0) | float(0) %}
{% set price_avg = this.attributes.future_prices_avg | default(0) | 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 %}
future_prices_16h: >-
{% if (this.attributes.future_prices | default('unknown')) in ['unknown','unavailable','none'] %}
unknown
{% else %}
{{ (this.attributes.future_prices | default([]) | list)[0:16]}}
{% endif %}
future_prices_16h_totals: >-
{% if (this.attributes.future_prices_16h | default('unknown')) in ['unknown','unavailable','none'] %}
unknown
{% else %}
{{ (this.attributes.future_prices_16h | default([])) | map(attribute='total') | list }}
{% endif %}
#future_prices_16h_count: "{{ (this.attributes.future_prices_16h_totals | default([])) | count }}"
future_prices_16h_min: |-
{% if this.attributes.future_prices_16h_totals | default([0]) | count > 0 %}
{{ (this.attributes.future_prices_16h_totals | default([0])) | min | float(0) | round(4) }}
{% else %}
unknown
{% endif %}
future_prices_16h_max: |-
{% if this.attributes.future_prices_16h_totals | default([0]) | count > 0 %}
{{ (this.attributes.future_prices_16h_totals | default([0])) | max | float(0) | round(4) }}
{% else %}
unknown
{% endif %}
future_prices_16h_avg: >-
{% if this.attributes.future_prices_16h_totals | default([0]) | count > 0 %}
{{ (this.attributes.future_prices_16h_totals | default([0])) | average(0) | float(0) | round(4) }}
{% else %}
unknown
{% endif %}
future_prices_16h_current_price_level: >-
{% set price_cur = this.state | default(0) | float(0) %}
{% set price_avg = this.attributes.future_prices_16h_avg | default(0) | 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 %}
future_prices_16h_current_price_is_close_to_min: >-
{% if is_number(this.state) and is_number(this.attributes.future_prices_16h_min) %}
{{ (this.state | float(0) <= (1.15 * this.attributes.future_prices_16h_min | default(0) | float(0))) | lower }}
{% else %}
unknown
{% endif %}
future_prices_16h_current_price_is_at_min: >-
{% if this.state | default(0) | float(0) > 0 and this.attributes.future_prices_16h_min | default(0) | float(0) > 0 %}
{{ (this.state | default(0) | float(0) <= this.attributes.future_prices_16h_min | default(0) | float(0)) | lower }}
{% else %}
unknown
{% endif %}