-
-
Notifications
You must be signed in to change notification settings - Fork 50
Octopus Agile
Assumes that the Home Assistant Octopus Energy intergration is installed and configured.
There are two options for the template sensor depending on if you also have a sensor set up for the agile price prediction. In both cases you will need to replace the XXXX_XXXX in the entiry names with the values for your electric meter.
If you do have the prediction sensor configured as per here, you can use this template sensor for pricing:
- sensor:
- name: "Octopus Energy Price Sensor"
unique_id: octopus_energy_price_sensor
unit_of_measurement: GBP/kWh
state: "{{ (states('sensor.octopus_energy_electricity_XXXXXX_XXXXXX_current_rate') | float) }}"
attributes:
prices_today: >
{% set today = now() %}
{% set fifteen_minutes = timedelta(minutes=15) %}
{% set ns = namespace(data=[]) %}
{% set current_day_rates = state_attr("event.octopus_energy_electricity_XXXX_XXXX_current_day_rates", "rates") %}
{% set time_key = 'start' %}
{% set price_key = 'value_inc_vat' %}
{% for i in current_day_rates | default([], true) %}
{% set current_day_i_date = as_local(as_datetime(i[time_key])) %}
{% if current_day_i_date.date() == today.date() %}
{% set ns.data = ns.data + [dict(time = current_day_i_date.isoformat(), price = i[price_key])] %}
{% set ns.data = ns.data + [dict(time = (current_day_i_date + fifteen_minutes).isoformat(), price = i[price_key])] %}
{% endif %}
{% endfor %}
{% set last_date_in_current_day = as_datetime(ns.data[-1].time) %}
{% set next_day_rates = state_attr("event.octopus_energy_electricity_XXXX_XXXX_next_day_rates", "rates") %}
{% if next_day_rates %}
{% set next_day_time_key = 'start' %}
{% set price_key = 'value_inc_vat' %}
{% for i in next_day_rates | default([], true) if as_local(as_datetime(i[next_day_time_key])).date() == today.date() %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[next_day_time_key])).isoformat(), price = i[price_key])] %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[next_day_time_key]) + fifteen_minutes).isoformat(), price = i[price_key])] %}
{% endfor %}
{% else %}
{% set forecast_data = state_attr('sensor.agile_predict', 'prices') %}
{% set time_key = 'date_time' %}
{% set price_key = 'agile_pred' %}
{% for i in forecast_data | default([], true) %}
{% set forcast_next_i_date = as_local(as_datetime(i[time_key])) %}
{% if forcast_next_i_date.date() == today.date() and forcast_next_i_date > last_date_in_current_day %}
{% set ns.data = ns.data + [dict(time = forcast_next_i_date.isoformat(), price = i[price_key] / 100)] %}
{% set ns.data = ns.data + [dict(time = (forcast_next_i_date + fifteen_minutes).isoformat(), price = i[price_key] / 100)] %}
{% endif %}
{% endfor %}
{% endif %}
{{ ns.data }}
prices_tomorrow: >
{% set tomorrow = now() + timedelta(days=1) %}
{% set fifteen_minutes = timedelta(minutes=15) %}
{% set ns = namespace(data=[]) %}
{% set next_day_rates = state_attr("event.octopus_energy_electricity_XXXX_XXXX_next_day_rates", "rates") %}
{% if next_day_rates %}
{% set time_key = 'start' %}
{% set price_key = 'value_inc_vat' %}
{% for i in next_day_rates | default([], true) if as_local(as_datetime(i[time_key])).date() == tomorrow.date() %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[time_key])).isoformat(), price = i[price_key])] %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[time_key]) + fifteen_minutes).isoformat(), price = i[price_key])] %}
{% endfor %}
{% else %}
{% set forecast_data = state_attr('sensor.agile_predict', 'prices') %}
{% set time_key = 'date_time' %}
{% set price_key = 'agile_pred' %}
{% for i in forecast_data | default([], true) if as_local(as_datetime(i[time_key])).date() == tomorrow.date() %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[time_key])).isoformat(), price = i[price_key] / 100)] %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[time_key]) + fifteen_minutes).isoformat(), price = i[price_key] / 100)] %}
{% endfor %}
{% endif %}
{{ ns.data }}If you don't or only want to use announced pricing then you can use this template sensor:
- sensor:
- name: "Octopus Energy Price Sensor"
unique_id: octopus_energy_price_sensor
unit_of_measurement: GBP/kWh
state: "{{ (states('sensor.octopus_energy_electricity_XXXXXX_XXXXXX_current_rate') | float) }}"
attributes:
prices_today: >
{% set today = now() %}
{% set fifteen_minutes = timedelta(minutes=15) %}
{% set ns = namespace(data=[]) %}
{% set current_day_rates = state_attr("event.octopus_energy_electricity_XXXX_XXXX_current_day_rates", "rates") %}
{% set time_key = 'start' %}
{% set price_key = 'value_inc_vat' %}
{% for i in current_day_rates | default([], true) %}
{% set current_day_i_date = as_local(as_datetime(i[time_key])) %}
{% if current_day_i_date.date() == today.date() %}
{% set ns.data = ns.data + [dict(time = current_day_i_date.isoformat(), price = i[price_key])] %}
{% set ns.data = ns.data + [dict(time = (current_day_i_date + fifteen_minutes).isoformat(), price = i[price_key])] %}
{% endif %}
{% endfor %}
{% set last_date_in_current_day = as_datetime(ns.data[-1].time) %}
{% set next_day_rates = state_attr("event.octopus_energy_electricity_XXXX_XXXX_next_day_rates", "rates") %}
{% if next_day_rates %}
{% set next_day_time_key = 'start' %}
{% set price_key = 'value_inc_vat' %}
{% for i in next_day_rates | default([], true) if as_local(as_datetime(i[next_day_time_key])).date() == today.date() %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[next_day_time_key])).isoformat(), price = i[price_key])] %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[next_day_time_key]) + fifteen_minutes).isoformat(), price = i[price_key])] %}
{% endfor %}
{% endif %}
{{ ns.data }}
prices_tomorrow: >
{% set tomorrow = now() + timedelta(days=1) %}
{% set fifteen_minutes = timedelta(minutes=15) %}
{% set ns = namespace(data=[]) %}
{% set next_day_rates = state_attr("event.octopus_energy_electricity_XXXX_XXXX_next_day_rates", "rates") %}
{% if next_day_rates %}
{% set time_key = 'start' %}
{% set price_key = 'value_inc_vat' %}
{% for i in next_day_rates | default([], true) if as_local(as_datetime(i[time_key])).date() == tomorrow.date() %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[time_key])).isoformat(), price = i[price_key])] %}
{% set ns.data = ns.data + [dict(time = as_local(as_datetime(i[time_key]) + fifteen_minutes).isoformat(), price = i[price_key])] %}
{% endfor %}
{% endif %}
{{ ns.data }}The template is a little complicated as the agile pricing "day" stops at 22:30 so we need to also look at the "next day" to get the final few elements for prices_today. We also need to duplicate the prices so they are every 15 minutes as the integration gives an error if you only supply values for every 30 minutes.