Templates in command line sensor + Octopus Energy API

Hi @LifeBandit666

Any chance you could share the configuration you built? This would be helpful

Thank you

Yes please… for me too. I’ve just got electricity (and not really a tech) so the lastest instructions e.g. changes for config etc, any custom stuff would be great…

2 Likes

I’ve broken mine in to 4 hour slots now to see usage throughout the day and night.

This also allows me to track spending based on periods of the day

If anyone wants the config let me know

1 Like

Yes please…

Ooh, yes please

Here is the code to add to the sensor.yaml file - you just need to edit the Region, MPRN,MPAN and serials:

## octopus go rest template ##

- platform: rest
  name: Go rates today
  resource_template: >-
    {% set region = 'H' %}
    {% set from = as_timestamp(as_timestamp(now())|timestamp_custom('%Y-%m-%d') + 'T00:00:00') %}
    {% set to = from + 24 * 60 * 60 %}
    {% set format = '%Y-%m-%dT%H:%M:%SZ' %}
    https://api.octopus.energy/v1/products/GO-21-05-13/electricity-tariffs/E-1R-GO-21-05-13-{{ region }}/standard-unit-rates/?period_from={{ from|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) }}&period_to={{ to|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) }}
  value_template: >-
    {% set from = ((as_timestamp(utcnow()) / 1800)|round(0, 'floor') | int * 1800)|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) %}
    {% if value_json.results is defined and value_json.results|count > 0 %}
      {{ as_timestamp(value_json.results[-1].valid_from)|timestamp_custom('%Y-%m-%d') }}
    {% else %}
      Unknown
    {% endif %}
  json_attributes:
    - "results"

- platform: rest
  name: Go rates off peak
  resource_template: >-
    {% set region = 'H' %}
    {% set from = as_timestamp(as_timestamp(now())|timestamp_custom('%Y-%m-%d') + 'T00:30:00') %}
    {% set to = from + 4 %}
    {% set format = '%Y-%m-%dT%H:%M:%SZ' %}
    https://api.octopus.energy/v1/products/GO-21-05-13/electricity-tariffs/E-1R-GO-21-05-13-{{ region }}/standard-unit-rates/?period_from={{ from|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) }}&period_to={{ to|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) }}
  value_template: >-
    {% set from = ((as_timestamp(utcnow()) / 1800)|round(0, 'floor') | int * 1800)|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) %}
    {% if value_json.results is defined and value_json.results|count > 0 %}
      {{ as_timestamp(value_json.results[-1].valid_from)|timestamp_custom('%Y-%m-%d') }}
    {% else %}
      Unknown
    {% endif %}
  json_attributes:
    - "results"

- platform: template
  sensors:
    go_current_rate:
      friendly_name: Go current rate
      icon_template: mdi:flash
      value_template: >-
        {% set from = ((as_timestamp(utcnow()) / 1800)|round(0, 'floor') | int * 1800)|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) %}
        {{ ((state_attr('sensor.go_rates_today', 'results')|selectattr('valid_from', 'eq', from)|first).value_inc_vat)|round(2) }}
      unit_of_measurement: 'p/kWh'
      attribute_templates:
        valid_from: >-
          {% set from = ((as_timestamp(utcnow()) / 1800)|round(0, 'floor') | int * 1800)|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) %}
          {{ (state_attr('sensor.go_rates_today', 'results')|selectattr('valid_from', 'eq', from)|first).valid_from }}
        valid_to: >-
          {% set from = ((as_timestamp(utcnow()) / 1800)|round(0, 'floor')|int * 1800)|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) %}
          {{ (state_attr('sensor.go_rates_today', 'results')|selectattr('valid_from', 'eq', from)|first).valid_to }}

- platform: rest
  name: Gas consumption
  resource_template: >-
    {% set mprn = '00000000000' %}
    {% set serial = 'ABC000000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/gas-meter-points/{{ mprn }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T00:00:00' }}&period_to={{ date + 'T23:59:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"

- platform: template
  sensors:
    gas_cost:
      friendly_name: Gas cost
      icon_template: mdi:cash-multiple
      value_template: >-
        {% set unit_price = 3.95 %}
        {% set standing_charge = 23.85 %}
        {% set calorific_value = 39.1 %}
        {% set usage = state_attr('sensor.gas_consumption', 'results') %}
        {% if usage is defined and usage|count == 48 %}
          {{ ((states('sensor.gas_consumption') | float * 1.02264 * calorific_value / 3.6) * unit_price / 100 + standing_charge / 100)|round(2) }}
        {% else %}
          Unknown
        {% endif %}
      device_class: energy
      unit_of_measurement: '£'

- platform: rest
  name: Electricity consumption
  resource_template: >-
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/electricity-meter-points/{{ mpan }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T00:00:00' }}&period_to={{ date + 'T23:59:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"

- platform: rest
  name: Electricity consumption midnight
  resource_template: >-
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/electricity-meter-points/{{ mpan }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T00:00:00' }}&period_to={{ date + 'T00:29:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"

- platform: rest
  name: Electricity consumption off peak
  resource_template: >-
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/electricity-meter-points/{{ mpan }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T00:30:00' }}&period_to={{ date + 'T04:29:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"

- platform: rest
  name: Electricity consumption graveyard
  resource_template: >-
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/electricity-meter-points/{{ mpan }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T04:30:00' }}&period_to={{ date + 'T08:29:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"


- platform: rest
  name: Electricity consumption morning
  resource_template: >-
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/electricity-meter-points/{{ mpan }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T08:30:00' }}&period_to={{ date + 'T12:29:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"

- platform: rest
  name: Electricity consumption afternoon
  resource_template: >-
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/electricity-meter-points/{{ mpan }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T12:30:00' }}&period_to={{ date + 'T16:29:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"


- platform: rest
  name: Electricity consumption evening
  resource_template: >-
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/electricity-meter-points/{{ mpan }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T16:30:00' }}&period_to={{ date + 'T20:29:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"

- platform: rest
  name: Electricity consumption night
  resource_template: >-
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}
    {% set date = as_timestamp(now() - timedelta(days = 1))|timestamp_custom('%Y-%m-%d') %}
    https://api.octopus.energy/v1/electricity-meter-points/{{ mpan }}/meters/{{ serial }}/consumption/?period_from={{ date + 'T20:30:00' }}&period_to={{ date + 'T23:59:59' }}
  headers:
    Authorization: !secret octopus_auth
  value_template: "{{ value_json.results|sum(attribute='consumption')|round(3) }}"
  unit_of_measurement: 'kWh'
  device_class: energy
  json_attributes:
    - "results"

- platform: template
  sensors:
    electricity_cost:
      friendly_name: Electricity cost
      icon_template: mdi:cash-multiple
      value_template: >-
        {% set standing_charge = 25 %}
        {% set usage = state_attr('sensor.electricity_consumption', 'results') %}
        {% if usage is defined and usage|count == 48 %}
          {% set ns = namespace(total=0) %}
          {% for p in range(0, 48) %}
            {% set time = as_timestamp(usage[p].interval_start)|timestamp_custom('%H:%M:%S') %}
            {% set unit_price = 15.59 %}
            {% if '00:30:00' <= time < '04:30:00' %}
              {% set unit_price = 5 %}
            {% endif %}
            {% set ns.total = ns.total + (usage[p].consumption * unit_price / 100) %}
          {% endfor %}
          {{ (ns.total + standing_charge / 100)|round(2) }}
        {% else %}
          Unknown
        {% endif %}
      unit_of_measurement: '£'
      device_class: monetary

- platform: template
  sensors:
    electricity_cost_off_peak:
      friendly_name: Electricity cost off peak
      icon_template: mdi:cash-multiple
      value_template: >-
        {% set standing_charge = 0 %}
        {% set usage = state_attr('sensor.electricity_consumption_off_peak', 'results') %}
        {% if usage is defined and usage|count == 8 %}
          {% set ns = namespace(total=0) %}
          {% for p in range(0, 8) %}
            {% set time = as_timestamp(usage[p].interval_start)|timestamp_custom('%H:%M:%S') %}
            {% set unit_price = 5 %}
            {% set ns.total = ns.total + (usage[p].consumption * unit_price / 100) %}
          {% endfor %}
          {{ (ns.total + standing_charge / 100)|round(2) }}
        {% else %}
          Unknown
        {% endif %}
      unit_of_measurement: '£'
      device_class: monetary

Then to get these working with “Energy” you will need to add the following to your customize.yaml file:

sensor.gas_cost:
  unit_of_measurement: GBP
  device_class: monetary
  state_class: total
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.gas_consumption:
  unit_of_measurement: kWh
  device_class: energy
  state_class: total_increasing
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.electricity_consumption_night:
  unit_of_measurement: kWh
  device_class: energy
  state_class: total_increasing
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.electricity_consumption_evening:
  unit_of_measurement: kWh
  device_class: energy
  state_class: total_increasing
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.electricity_consumption_afternoon:
  unit_of_measurement: kWh
  device_class: energy
  state_class: total_increasing
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.electricity_consumption_morning:
  unit_of_measurement: kWh
  device_class: energy
  state_class: total_increasing
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.electricity_consumption_graveyard:
  unit_of_measurement: kWh
  device_class: energy
  state_class: total_increasing
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.electricity_consumption_off_peak:
  unit_of_measurement: kWh
  device_class: energy
  state_class: total_increasing
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.electricity_consumption_midnight:
  unit_of_measurement: kWh
  device_class: energy
  state_class: total_increasing
  last_reset: '1970-01-01T00:00:00+00:00'
sensor.electricity_cost_off_peak:
  unit_of_measurement: GBP
  device_class: monetary
  state_class: total
  last_reset: '1970-01-01T00:00:00+00:00'

For the pricing I only use the energy sensor for offpeak to apply the daily charges:

For the rest I just use the static values:

Finally you’ll need to add the octopus auth to the secrets.yaml file:

octopus_auth: 'Basic base64encodedapikey'

Note: you can simply use the following line in a linux terminal to obtain your base64 encoded api key without using any online utility:

echo 'your_api_key' | base64

Then you can simply calculate your daily usage using the following:

- platform: template
  sensors:
    total_energy_cost:
      friendly_name: "Energy Cost - Total"
      value_template: "{{ states('sensor.electricity_cost') | float + states('sensor.electricity_cost_off_peak') | float + states('sensor.gas_cost') | float}}"
      unit_of_measurement: '£'
      device_class: monetary

- platform: template
  sensors:
    total_energy_consumption:
      friendly_name: "Energy Consumption - Total"
      value_template: "{{ states('sensor.electricity_consumption') | float + states('sensor.electricity_consumption_off_peak') | float + states('sensor.gas_consumption') | float}}"
      unit_of_measurement: 'kWh'
      device_class: energy

The finally add the following to your configuration.yaml file if you don’t have it in there already (thanks to @BookOfGreg for pointing this out):

homeassistant:
  customize: !include customize.yaml

sensor: !include sensor.yaml

Hope this helps

6 Likes

added everything I have so far

1 Like

I have copied your code directly into my config files updating the following:

    {% set region = 'H' %}
...
#gas
    {% set mprn = '00000000000' %}
    {% set serial = 'ABC000000000' %}
...
#elec
    {% set mpan = '0000000000000' %}
    {% set serial = '00A000000' %}

I am seeing a number of errors in my logs as a result of adding them:

homeassistant.exceptions.TemplateError: UndefinedError: No first item, sequence was empty.

2021-10-29 09:52:37 ERROR (MainThread) [homeassistant.helpers.template] Template variable error: No first item, sequence was empty. when rendering '{% set from = ((as_timestamp(utcnow()) / 1800)|round(0, 'floor') | int * 1800)|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) %} {{ (state_attr('sensor.go_rates_today', 'results')|selectattr('valid_from', 'eq', from)|first).valid_from }}'

2021-10-29 09:52:37 ERROR (MainThread) [homeassistant.helpers.event] Error while processing template: Template("{% set from = ((as_timestamp(utcnow()) / 1800)|round(0, 'floor') | int * 1800)|timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) %} {{ (state_attr('sensor.go_rates_today', 'results')|selectattr('valid_from', 'eq', from)|first).valid_from }}")

Any thoughts what may be going on here?

are you getting the rates data when you use the developer tool in HA?

Sorry I was not clear; I have replaced those values:

    {% set region = 'M' %}

    {% set mprn = '920xxx3410' %}
    {% set serial = 'G4P036xxxx1800' %}

etc…

I have amended my response above,but I wouldn’t really care about the rates as you can use helpers to undertake that task - that is if you want to use rates to do rate based automations:

Then simply use automations mapped against the helper:

alias: Octopus Go Start
description: ''
trigger:
  - platform: time
    at: '00:30'
condition: []
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.octopus_go
    data:
      value: 5
mode: single
alias: Octopus Go End
description: ''
trigger:
  - platform: time
    at: '04:30'
condition: []
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.octopus_go
    data:
      value: 15.59
mode: single

Hope this helps

image
yes, am getting those values.

could it be this one causing the error?
image

ok for go it will only show the current rate when the rate has triggered - so at 00:30 it will go to 5 and at 04:30 it will go back to 15.59

You can use these rate updates to do automation based triggers, but like I said above you can remove the code and use helpers instead

you should be good to go - for the gas costs you will have to wait a while - its taken me a couple of days to get the costs working -only had the guy round to fix the meter the other day

Please note you will have to amend the costs to be line with what values you get, as you get a better rate than me: 15.18p normal rate

once your done you should end up with this:

good luck with all

1 Like

Thank you, I need more patience :slight_smile:

For those I am going to have to wait a while. My Gas meter is currently not reporting 30 min data due to a firmware fault (according to Octopus) so am ignoring that one.

Additional question: for the Energy setup in HA I am not sure how to configure the Grid Consumption. I am seeing the below options but not the one I expected “sensor.electricity_consumption”

image

it will take approx 24 hours for you to get data but it does work - I have been battling against it for ages and tweaking code to get it to work, but my electricity API pull has been up and running for about 1 month now:


2 Likes

thats because its not in the customize.yaml file, as you need device and state class values applied to the sensors to make it work with the energy dashboard

you don’t really need TBH, i was just using it on another dashboard to cross reference ahead of getting energy dashboard working

1 Like

Thank you. Your answers have been really helpful.

no worries at all. my pain your gain :wink:

1 Like

Been reading all this with interest. I’ve been using HA for a couple of years to monitor my boiler and central heating. I’ve recently been moved to Octopus Energy and have a SMETS2 smart meter, so would like to get that data into HA. I’ve enabled half-hourly data on my Octopus account and can download .CSVs so just need to stitch it all in HA.

I guess I’m interested in half-hourly consumption which I can then aggregate somehow by day, week, month. I don’t need realtime (yet) so the Octopus API sounds the route to go. I’m on the price-cap tariff, so not expecting frequent price changes, but it would be good if that’s retrievable through the API so the rates are up to date.

Is there a wiki or other doc summarising how to set things up? Thanks.

This thread should help you with the consumption side of things - Hildebrandglow - Smart Meters - SMETS2