Automating Octopus Power-ups

One of the challenges of renewable energy is matching demand to supply. In other words, when it’s sunny and windy, more energy is generated than is required, at certain points in the day.

This can be stored for later use, but this infrastructure is expensive and can take a long time to provision. An alternative is to incentivise people to shift their electricity consumption to match periods when green supply is high.

Octopus Energy have recently launched Octopus Power-ups as a trial in Eastern and South-Eastern England. When they predict excess supply for the following day, customers are invited to opt-in to a power-up slot which is a two-hour window where electricity is free – you’re encouraged to consume as much electricity as you can. For those of us with home batteries, electric cars and immersion heaters, this is a real opportunity to save some money and help the grid if it can be automated.

I use Home Assistant to orchestrate the process and I’m documenting it here in case it’s useful.

Components

  • FoxESS batteries
  • Intelligent Octopus tariff
  • Tesla Model 3 EV

Default Behaviours

  • Charge the home batteries to 100% in the off-peak overnight hours (23:30-05:30)
  • From 05:30-23:30 (peak hours) use battery to serve the house load until solar kicks in.
  • Solar generated electricity priority is (a) house load, (b) top up the battery, (c) divert to the hot water immersion heater
  • Allow Octopus to schedule and orchestrate car charging

Power-up Behaviours

  • Charge the battery to 50% in the off-peak overnight hours – our aim is for the battery to be as close to 10% charge when the power-up slot begins so this figure needs to be tuneable, and may be further automated in the future.
  • Meet house load using battery/solar as above
  • During the power-up slot:
    • Charge the house battery to 100%
    • Trigger an Intelligent Octopus bump charge and initiate charging – without this, Octopus will stop the car charging during daytime
  • When the power-up slot ends:
    • Revert the house battery charging settings to the defaults
    • Stop the car charging and terminate the Intelligent Octopus bump charge

Home Assistant configuration

Integrations

UI and Helpers

This is an entities-row card which allows you to chose the date and start/end times for the upcoming power-up slot, and chose the maximum battery SOC (state of charge) for overnight charging. Four helpers are required to store this information.

Template Sensors

My template sensors are defined in a separate templates.yaml file. We want to specify our start and end times as local times (ie taking account of daylight saving time) but translate them into a proper timestamp to trigger the automations correctly. It’s also handy to have a binary_sensor to show when a power-up slot is scheduled, and when it’s active:

- sensor:
    - name: "Octopus Power-up Slot start"
      device_class: "timestamp"
      unique_id: octopus_powerup_start
      state: "{{ ((states.input_datetime.octopus_power_up_date.attributes.timestamp + states.input_datetime.octopus_power_up_start.attributes.timestamp)  | as_datetime | as_local).isoformat() }}"

    - name: "Octopus Power-up Slot end"
      device_class: "timestamp"
      unique_id: octopus_powerup_end
      state: "{{ ((states.input_datetime.octopus_power_up_date.attributes.timestamp + states.input_datetime.octopus_power_up_end.attributes.timestamp)  | as_datetime | as_local).isoformat() }}"

- binary_sensor:
    - name: Octopus Power-up Slot pending
      unique_id: octopus_powerup_slot_pending
      state: "{{ states.sensor.octopus_power_up_slot_end.state | as_datetime > now() }}"

    - name: Octopus Power-up Slot active
      unique_id: octopus_powerup_slot_active
      state: "{{ states.sensor.octopus_power_up_slot_end.state | as_datetime > now() > states.sensor.octopus_power_up_slot_start.state | as_datetime }}"

Automations

FoxESS provides two configurable slots for battery charging. Unfortunately, the implementation of them is a bit… shit? In particular, slots cannot straddle midnight (i.e you can’t have a slot which starts at 23:30 and ends at 05:30 – this has to be configured as two slots).

As Intelligent Octopus off-peak starts at 23:30, this presents a problem – we don’t want to be meeting house load from the battery after 23:30 at night under any circumstances. Fortunately, we can just enable force charging but disable charge from grid from 23:30-00:00, and then manipulate slot two as we go. The setup in the FoxESS app looks as follows:

Then we have three automations.

At midnight on power-up day we want to reduce the maximum battery SOC to 50% (or whatever we defined it as in the UI we’ve just created):

Yaml:

alias: Octopus Power-up max SOC
description: ""
trigger:
  - platform: time
    at: input_datetime.octopus_power_up_date
condition: []
action:
  - service: number.set_value
    data:
      value: "{{ states.input_number.octopus_power_up_max_soc.state | int }}"
    target:
      entity_id: number.max_soc
mode: single

When the power-up slot starts we want to:

  • Set the second battery charge slot start and end times to match the power-up slot
  • Set the max battery charge to 100%
  • Schedule an Intelligent Octopus bump charge
  • Start the car charging

Yaml:

alias: Octopus Power-up Period start
description: ""
trigger:
  - platform: time
    at: sensor.octopus_power_up_slot_start
condition: []
action:
  - parallel:
      - service: foxess_modbus.update_charge_period
        data:
          inverter: bb431a8f0b4902c51fdb98acdc4a6c6a
          enable_force_charge: true
          enable_charge_from_grid: true
          start: >-
            {{states.sensor.octopus_power_up_slot_start.state | as_timestamp | 
            timestamp_custom('%H:%M:%S')}}
          end: >-
            {{states.sensor.octopus_power_up_slot_end.state | as_timestamp | 
            timestamp_custom('%H:%M:%S')}}
          charge_period: "2"
      - service: number.set_value
        data:
          value: "100"
        target:
          entity_id: number.max_soc
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.octopus_bump_charge
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.blue_shell_charger
mode: single

As the power-up slot ends, we want to stop charging batteries and car, and revert the settings to defaults:

Yaml:

alias: Octopus Power-up Period end
description: ""
trigger:
  - platform: time
    at: sensor.octopus_power_up_slot_end
condition: []
action:
  - parallel:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.octopus_bump_charge
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.blue_shell_charger
      - service: foxess_modbus.update_charge_period
        data:
          inverter: bb431a8f0b4902c51fdb98acdc4a6c6a
          enable_force_charge: true
          enable_charge_from_grid: true
          start: "00:00:00"
          end: "05:30:00"
          charge_period: "2"
mode: single

Results

We shifted around 14kWh of grid consumption to the power-up slot. Octopus will show this as a saving of around £4.30 which technically correct as that’s how much that electricity would have cost if we’d bought it at that time – but it’s really consumption from overnight that’s been shifted to daytime. So the saving is really around £1.05 on this occasion. As important as the saving – we created 14kWh of additional demand, to help mop up some of the surplus from excess renewables generation.

House battery dipped to 42% before solar kicked in and started charging it more. – it was back up to 69% at the start of the power-up slot. So we could have lived with a lower overnight SOC and got more into the battery during the slot.

We charge the car to 100% each night (Tesla guidelines for this model) – the car was used this morning but was still on 93% at the start of the slot so there was only a limited amount of headroom today.

Future enhancements

I had to control the immersion heater manually. I’m waiting for components to allow me to integrate the Solar iBoost+ into Home Assistant, based on this work which will allow me to include it into these automations.

If we are at home, it’s better to shift other loads which can’t be automated into the power-up slots – using the oven, the tumble dryer and the dishwasher. I will use the binary_sensors to trigger notifications and to alert on our kitchen dashboard to remind the family to do that if possible.


Comments

2 responses to “Automating Octopus Power-ups”

  1. David John Varghese avatar
    David John Varghese

    I have managed to create sensors to read this information off my email account using the IMAP integration that gets the date and time off the subject line

    So now I have a power-up start and end time sensors and I can do automations so muuch more efficiently. Let me know that helps you!

    # gmail powerup sensor
    – sensors:
    octopus_power_up_start_time:
    friendly_name: “Octopus – Power-Up Start Time”
    value_template: >
    {% set time_str = states(‘sensor.homeassistant_mail_sensor’) | regex_findall_index(‘\\d+:\\d+ [AP]M’, 0) %}
    {% set date_str = states(‘sensor.homeassistant_mail_sensor’) | regex_findall_index(‘\\d+/\\d+/\\d+’, 0) %}
    {% set datetime_str = date_str + ‘ ‘ + time_str %}
    {% set datetime_obj = strptime(datetime_str, ‘%d/%m/%y %I:%M %p’) %}
    {{ datetime_obj }}

    octopus_power_up_end_time:
    friendly_name: “Octopus – Power-Up End Time”
    value_template: >
    {% set time_str = states(‘sensor.homeassistant_mail_sensor’) | regex_findall_index(‘\\d+:\\d+ [AP]M’, 1) %}
    {% set date_str = states(‘sensor.homeassistant_mail_sensor’) | regex_findall_index(‘\\d+/\\d+/\\d+’, 0) %}
    {% set datetime_str = date_str + ‘ ‘ + time_str %}
    {% set datetime_obj = strptime(datetime_str, ‘%d/%m/%y %I:%M %p’) %}
    {{ datetime_obj }}
    – sensors:
    now:
    friendly_name: “Now”
    value_template: “{{ now() }}”
    entity_id: sensor.date

    1. Thank you for laying out how this can be done – very nice, and I’ll give that a go myself. Have you explored whether it’s possible to automate the opt-in too?

Leave a Reply

Your email address will not be published. Required fields are marked *