Automating a battery charge event from an event attribute (Octopus Saving Session)

Hi there,

I hope this is a generic query although it could be specific, i’m not sure.

I have the Octopus Energy integration to HA, and have signed up for Octopus Energy Saving Sessions. For anyone who doesn’t know, these are sessions controlled by the UK’s national power grid network whereby signing-up energy providers and their customers who sign up for these sessions can make a lot of money if they change their energy usage habits during this period.

The Octopus Energy integration gives the following information

As you can see though, this is in the form of a binary sensor (off/on) and also a bunch of attributes.

I have PV and a battery at home, and have managed to create a basic automation that should work for this evening’s saving session which dumps my battery’s charge to the grid when the Octopus Energy integration signals a state change that the saving session period has started (on). However, as you can probably guess this is suboptimal for two reasons:

  1. I only get credited if I have manually signed up for tonight’s saving session
  2. The credit i’ll be given for the session depends on the amount of charge in the battery when the session starts

I’d therefore like to amend/add to my automations in two ways:

  1. to ensure that the action of dumping my charge to the grid ONLY occurs if the “Joined Events” attribute lists the current date and time (to avoid dumping my charge to the grid if i’ve not joined the event in question), and
  2. to be able to force a charge of my battery for a period prior to the next joined event where the period is dictated by the “Next joined event duration in minutes”. e.g. if the duration is 60 minutes I want to trigger a battery charge 60 minutes prior to the event to ensure i’m not charging the battery for longer than I need to at peak rate tariffs.

How would I go about this given the attributes (and their formats) listed in the graphic?

1 Like

Just sitting down to try to do something similar myself, more than likely with NodeRed. Probably won’t get it finished this evening, but will check back in when I have something together, probably over the weekend.

1 Like

I would be interested in your solutions. I’m just battling with the same issue.

I’m setting up the same thing at the moment. I’m basically going to use a similar idea to how I set the charge for agile. I have two template sensors to extract the start and end times then an automation to use those sensors to set the start and end times for the charge. just need to work out the details.

With the latest version of the Octopus Energy integration there is now a binary sensor (binary_sensor.octopus_energy_<account_number>_octoplus_saving_sessions)

Simple automation binary sensor on → start export, off–> stop export
Job done - well next saving session is in 2 hours so we will see.

I made a little template sensor using one of the attributes that only gets populated if you’ve opted in to show ‘Yes’ if I’d opted in. Unfortunately at the start of the session it resets to ‘No’, so not sure if it’s very useful.

- sensor:
  - name: "Opted In?"
    state: >
      {% set session_time = states.binary_sensor.<SENSOR NAME HERE>.attributes["next_joined_event_duration_in_minutes"] %}
      {% if session_time is number %} Yes
      {% else %} No
      {% endif %}
1 Like

This this fire as expected?
I tried to use similar binary sensors for intelligent go dispatching without success :frowning:

Yep, that works great for me with this automation:

alias: Octopus Saving Session - Start Export
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.octopus_energy_<account_id>_octoplus_saving_sessions
    to: "on"
    from: "off"
condition:
  - condition: state
    entity_id: binary_sensor.octopus_energy_<account_id>_octoplus_saving_sessions
    state: "on"
action:
  - repeat:
      sequence:
        - service: select.select_option
          data:
            option: Timed Export
          target:
            entity_id: select.inverter_mode
        - delay:
            hours: 0
            minutes: 0
            seconds: 45
            milliseconds: 0
      until:
        - condition: state
          entity_id: select.inverter_mode
          state: Timed Export
          for:
            hours: 0
            minutes: 0
            seconds: 20
  - service: notify.signal_ha
    data:
      message: Octopus Saving Session Started
mode: single

I have a similar automation to turn off export at the end of the session.
and another automation to auto-join saving session (automation for that is listed in the docs for the Octopus Integration on github)

I’ve written a short article on trying to fully automate forced export during Octopus Saving Sessions - hopefully you find it useful: Automated Octopus Saving Sessions with Solax X1 Hybrid G4

After the first few saving sessions I’ve also realised I need to automate things. I was looking for an approach that didn’t require black belt jinja skills.

Calendar triggers get rid of lots of the date time and extracting events from octopus complexity.

Overview
Use a modified join session automation that also creates an event in the savings session calendar. Huge thanks to @BottlecapDave for the integration and join session blueprint
Use calendar triggers with offsets to control the battery operation. I have a pre charge event that fires two hours before a savings session starts to persuade the Powerwall to charge using the Tesla Custom Integration and one that fires 2 mins before the session starts to return the battery to supplying the house.

For me it’s nice the battery control is separate from the octopus integration -means it’s easy to test the battery control using manually entered test sessions in the calendar.

Can post more details if anyone is interested.

Hi Steve_jo - yes i’d love to know more as that’s exactly what I’m after. Can you let me know (in complete code numpty terms) how you achieve all that please?

Will try. May take a couple of posts - easier to do than write up.

Preparation - get the integrations installed and helpers created

I created a calendar called ‘Saving sessions’

Tesla Custom Integration - needed to control the Powerwall

Follow the instructions to get your key and get it working. The integration exposes a lot of sensors, I’m a bit paranoid about HA database size so I disable almost all of them. (I use the local Tesla Powerwall - Home Assistant integration to monitor the battery so don’t need all the monitoring info from the custom integration)

We only need number.home_energy_gateway_backup_reserve to automate saving sessions.

Again follow the instructions to get your API key and you’ll need your account number to get it going. Same comment re all the many entities created We need octopus_energy_a_XXXXXXX_octoplus_saving_session_events and I’ve left octopus_energy_a_XXXXXXX_octoplus_saving_sessions enabled as it flags when saving sessions are active - might be handy. (XXXXXXX will be your account number - automatically handled by the integration)

Set up two datetime helpers - Settings - Devices and Services - Helpers - Create Helper
Date and/or time - select date and time
I’ve called them ‘Session start time’ and Session end time’

Auto Join Automation - to follow.
This will create events in your Saving sessions calendar but you can create events manually to test the battery stuff

Battery Automations

Precharge

alias: Pre charge on - start battery charging
description: >-
  Sets battery level to 50% 2 hours before saving session starts focing battery
  to charge up to 50% - adds about 30% or 4kWh
trigger:
  - platform: calendar
    event: start
    offset: "-2:00:00"
    entity_id: calendar.saving_sessions
condition: []
action:
  - service: notify.notifier_name
    data:
      title: Calendar event triggered
      message: >-
        Pre charge tunred on for savings session starting {{
        trigger.calendar_event.start }} 
  - service: number.set_value
    target:
      entity_id: number.home_energy_gateway_backup_reserve
    data:
      value: "50"
mode: single

You can set this up in the Automation UI or use YAML
Adjust the time offset to meet your requirements. My Powerwall seems to charge at about 2kW when adjusting the reserve level - so 2 hours gives me about 4kWh which is more than enough to cover my typical savings session use. I could perhaps save a few pennies by optimising the charge time but life is too short and it really is only a few pennies per session.

Normal Operation

alias: Pre charge off - normal operation
description: >-
  Sets battery level back to 20% 2 mins before saving session starts so battery
  starts to supply house again
trigger:
  - platform: calendar
    event: start
    offset: "-0:02:00"
    entity_id: calendar.saving_sessions
condition: []
action:
  - service: notify.notifier_name
    data:
      title: Calendar event triggered
      message: Battery Reserve level returned to 20%
  - service: number.set_value
    target:
      entity_id: number.home_energy_gateway_backup_reserve
    data:
      value: "20"
mode: single

This puts the battery reserve level back to my normal 20% value so the battery starts supplying the house again. It takes a minute or two for the Tesla Servers to tell the battery abut the new level hence the small offset before the start of the session.

Both also send me a notification

Hope that is clear. Will detail the auto join automation when I get a chance in the next day or two (other things on!) Anyway according to Octopus no more sessions for a while over the holidays.

Good luck

Octopus saving sessions have started up again. Here’s the automation I use to join events and create calendar events - thanks to @BottlecapDave for his auto join automation on which this is based.

alias: My octo auto join
description: >-
  Joins a session when announced, Sets two helpers with start and and datetimes,
  creates calendar entry, sends notification
trigger:
  - platform: state
    entity_id: event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events
condition:
  - condition: template
    value_template: >-
      {{
      state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events',
      'available_events') | length > 0 }}
action:
  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.session_start_time
    data:
      datetime: >-
        {{
        state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events','available_events')[0]['start'] 
        }}
  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.session_end_time
    data:
      datetime: >-
        {{
        state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events','available_events')[0]['end'] 
        }}
  - service: octopus_energy.join_octoplus_saving_session_event
    data:
      event_code: >-
        {{
        state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events',
        'available_events')[0]['code'] }}
    target:
      entity_id: event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events
  - service: calendar.create_event
    target:
      entity_id: calendar.saving_sessions
    data:
      summary: Saving Session
      start_date_time: "{{ states('input_datetime.session_start_time') }}"
      end_date_time: "{{ states('input_datetime.session_end_time') }}"
  - service: notify.mobile_app_stephens_iphone_2
    data:
      message: >-
        {% set event_start =
        state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events',
        'available_events')[0]['start'] %} Joined a new Octopus Energy saving
        session. It starts at {{ event_start.strftime('%H:%M') }} on {{
        event_start.day }}/{{ event_start.month }}
mode: single

replace all the XXXXXXXX with your Octopus key.

Works for me.

@steve_jo - my HA/YAML skills are still not where they need to be. I’m an expert at cut & paste and following step-by-step instructions, but I could do with a little help with this one. I’m trying to follow your guidance on how to set up automatic battery charging. Can you share the code/detail of what you describe above as “a modified join session automation that also creates an event in the savings session calendar”? I’ve got the auto-join automation working, so next is to get the calendar event populated. Thanks so much.

That’s what the automation in the post immediately above yours does.

In more detail - it detects there’s an event available - this bit

trigger:
  - platform: state
    entity_id: event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events
condition:
  - condition: template
    value_template: >-
      {{
      state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events',
      'available_events') | length > 0 }}

then populates two previously created helpers with the start and end times of the event

action:
  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.session_start_time
    data:
      datetime: >-
        {{
        state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events','available_events')[0]['start'] 
        }}
  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.session_end_time
    data:
      datetime: >-
        {{
        state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events','available_events')[0]['end'] 
        }}

it then joins the event

 - service: octopus_energy.join_octoplus_saving_session_event
    data:
      event_code: >-
        {{
        state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events',
        'available_events')[0]['code'] }}
    target:
      entity_id: event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events

and creates a calendar entry from the helpers

- service: calendar.create_event
    target:
      entity_id: calendar.saving_sessions
    data:
      summary: Saving Session
      start_date_time: "{{ states('input_datetime.session_start_time') }}"
      end_date_time: "{{ states('input_datetime.session_end_time') }}"

finally it notifies me

- service: notify.mobile_app_stephens_iphone_2
    data:
      message: >-
        {% set event_start =
        state_attr('event.octopus_energy_a_XXXXXXXX_octoplus_saving_session_events',
        'available_events')[0]['start'] %} Joined a new Octopus Energy saving
        session. It starts at {{ event_start.strftime('%H:%M') }} on {{
        event_start.day }}/{{ event_start.month }}

Hope that helps and cut and paste can now do the job!

Oh you star! Thanks Steve. I look forward to cutting-and-pasting this evening!!