springfall2008 / batpred

Home battery prediction and charging automation for Home Assistant, supporting many inverter types
https://springfall2008.github.io/batpred/
128 stars 44 forks source link

Enhancement: smarter optimisation for future cheap-rate periods #144

Closed gcoan closed 1 year ago

gcoan commented 1 year ago

I'm lucky enough to live in one of the East Anglia postcodes where Octopus are running their power-up scheme this year (but I suspect the same principles may apply to Octopus agile customers).

During the power up event Octopus give free electricity, as much as you can consume. So far every one of the power up events has been from 2-4pm, but potentially they could be at other times when there is plentiful grid supply. (interestingly there is no change to export rates during the power up period so if you had the battery and inverter charging capacity you could import and export several times during the period and get paid for all the exports!)

I configure the power-up as a price override in config.yaml, and predbat notices it and suggests it as another charge_limit_best slot, but it doesn't seem to be planning to make optimal use of that free electricity.

Here's the graphs of tonight & tomorrow's predictions with normal Octopus Flux pricing periods: battery predictiom

home cost prediction

energy rates

data prediction

In essence, best is hold the battery at about 2.8kW during the flux offpeak period (to retain sufficient charge to see the house through to solar charging starting), let the batteries charge up during the morning, export any excess in the early afternoon, then a discharge in the early evening taking advantage of the flux peak period.

Then after I added the Octopus powerup period as a price override, apart from this appearing as another potential charge up period the planned activity is the same. No additional import or export that I could see:

battery prediction powerup

home cost prediction power up

energy rates power up

data prediction power up

What I have in my own powerup scripts to do is I think the optimal price approach (obviously this doesn't have the sophistication of daily load prediction):

So by 2pm I have the 9.5 50% full and the 5.2 completely empty.

By 4pm when my scripts have finished I will have got to the same soc that predbat predicts in the best plan (14.7kW) except that I will have exported all the solar for half of the morning and filled up the batteries for free. I can charge the 5.2 to full in 2 hours and the 9.5 to full if it starts at 50%.

Appreciate that as written this is very specific to my inverter & battery sizes and configuration, but if the essence of some of this can be carried forward into predbat: "looking forward" to not let the batteries unnecessarily fill with solar when there is a cheap (free) electricity period coming up. This I think may apply to Octopus Agile.

springfall2008 commented 1 year ago

Do you have freeze discharge enabled (this is basically turning off battery charging)? For this to work in the day you would have to set rate high to lower so that day slots are included in the calculation

I’ve also push a new version to main with a different optimisation algorithm that maybe worth a try

gcoan commented 1 year ago

Do you have freeze discharge enabled (this is basically turning off battery charging)? For this to work in the day you would have to set rate high to lower

I didn’t have freeze discharge enabled, but in looking at how the battery was being held overnight I noticed that freeze discharge was one of the recommended settings for Octopus Flux so I had set it to on.

Doesn’t look any different. No afternoon importing 21022916-D750-4336-8B67-03904E54E1D4

rate-high-threshold was set to 1.2. Dropping it to 1.1, no change.

Dropping it to 1.0 it changes the plan to take some advantage of the cheaper period. Looks like it still lets the battery charge to nearly full, then does a force discharge (which is less efficient than my approach of just letting it all export). And the force export doesn’t appear to finish until about 2:30 when it then starts the force charge - so it misses out on 30 mins of free electricity whilst it’s still discharging and it doesn’t get soc to 100%.

15F946C6-8EB6-40A0-A77B-F69869406EFD E7C98750-49B0-4642-9053-B5EE73F5030A

I’ll try the other version tomorrow

springfall2008 commented 1 year ago

then does a force discharge (which is less efficient than my approach of just letting it all export).

Are you sure, wouldn't that leave you less to export at the peak evening export rate?

gcoan commented 1 year ago

then does a force discharge (which is less efficient than my approach of just letting it all export).

Are you sure, wouldn't that leave you less to export at the peak evening export rate?

Here's the current prediction

image

There are two problems with this, the purple where it lets the battery charge up, and then force discharges it. My approach just holds the battery level, the smaller one at 4% and the bigger one at 50% which is more efficient (and profitable) as there's no energy losses incurred in charging and discharging the battery. Admittedly either approach incurs the same voltage conversion losses either directly from the DC panels to AC for export (my approach), or on DC battery discharge for export (predbat).

The other problem is the timing of this discharge activity. The discharging starts at 13:30 and runs until 14:30, when it switches to charging until 16:00. My approach leaves capacity in the batteries so that the charge can start at 14:00. I have two 2.6kW Gen 1 inverters so can charge 10.4kW in the two hours, which will fill the 9,5 to 100% (from 50%) and the 5.2 to 100% (from 4%) if I start at 14:00. I will end up with the batteries completely full before 4pm for the evening peak whereas predbat predicts to not manage to quite get there on best.

gcoan commented 1 year ago

Do you have freeze discharge enabled (this is basically turning off battery charging)?

As I mentioned last night I didn't have freeze discharge on, but turned it on last night.

I'm confused by the description/name of it though, in the readme: set_discharge_freeze When enabled if a discharge reaches the expected battery level for the discharge slot then charging of the battery will be frozen (charge rate 0) and all non-self consumed solar is exported. When this is disabled the inverter will return to ECO mode (default)

This talks about changing behaviour in a discharge slot, but from the battery prediction graph it doesn't appear that we are in a discharge slot?

Nevertheless, this morning it does appear to be taking an effect in predbat, I'm not entirely sure what it is doing (and why), because its turning freeze discharge on and off repeatedly every 15-20 minutes or so image

image

Here's the logfile appdaemon (3).log

gcoan commented 1 year ago

I’ve also push a new version to main with a different optimisation algorithm that maybe worth a try

Just installed the new main version at 10:44 and restarted appdaemon. Will see what it does for a bit

gcoan commented 1 year ago

Current activity plan (with the new main) appears very similar to before, but it doesn't seem to be chopping and changing into and out of freeze discharging: image

image

Is letting it PV charge, then a force discharge before the free period finishing at 14:30, then a free period charge then the peak period force discharge image image

Both batteries are still charging from solar and are at 61% and 48%, so I'm going to stop predbat and leave my scripts to manage the cheap period activity, then see what it looks like compared to the predbat plan

springfall2008 commented 1 year ago

This talks about changing behaviour in a discharge slot, but from the battery prediction graph it doesn't appear that we are in a discharge slot?

I think it's because a 99% discharge is often selected, which doesn't show well on the chart.

You can see it here the little indent at the top of the peak is a freeze.

image

gcoan commented 1 year ago

Tomorrow is the next Octopus power-up event and its not predicted to be a particularly sunny day tomorrow either so the predbat prediction (before I add the zero rate over-ride from 2-4pm) is for a big overnight charge to bring the battery up to the level that it'll then fill with what little solar we will have: image

When I add the 2 hour zero rate import period I get something more like what I expected, a much smaller overnight charge, partial solar fill and then a 2 hour import to fill the batteries: image

image

Unlike last time when there was a lot of solar being generated, its not planning on importing solar in the morning only to export it later on. Which is a big improvement.

What I will be interested to see is if predbat treats the two inverters and their battery capacities differently. I suspect it won't and both will be allowed to charge from solar during the morning. As I described above, my more optimal hand-crafted scripts doesn't allow H to charge at all in the morning as the capacity is 5.2kW, the charge rate is 2.6kWh and in a 2 hour zero rate period this battery can be fully charged - so I set the discharge rate for inverter 1 to zero to prevent it charging at all and let all solar PV from that inverter get exported. It would be lovely if predbat could do this kind of smarter battery optimisation, planning the activities based on the charge and discharge rates of the individual inverters and their attached battery capacities. I suspect at the moment that the optimisation is done on a single kwh soc figure across all inverters as I see both inverters being controlled the same.

gcoan commented 1 year ago

Today I tried to leave predbat to manage the battery activity during the Octopus power-up (zero rate) 2 hour event as its plan seemed to match(ish) what I would have optimised the inverters to do.

However there were two activities it did where it didn't choose the optimal (most best best) battery plan and I had to intervene, in both cases, by shutting predbat down by stopping appdaemon so I could control the inverters myself.

Issue 1. As I suspected would happen, predbat doesn't appear to take account of individual inverter throughput and battery capacity to predict correctly that the smaller battery can be fully charged during the 2 hour zero rate period. As a result both inverters were left through the morning to charge up. It was a grey day so they didn't charge a lot, but by 1:15pm inverter 1 soc had reached 19%, taking up capacity that we could have filled from grid import for free. I tried turning different predbat controls off to set the charge rate to zero but couldn't manage to do so, so stopped predbat, did a force discharge of that inverter down to 4%, then restarted predbat at 2pm so it would start the force charging of both batteries.

Issue 2. I think its linked to the way predbat calculates maximum battery charge rate across all inverters rather than on a per inverter/battery basis, but during the two hour charge period predbat set the battery reserve & target during the charge period firstly to 80%, then 81, 82 and 83%. It should have been setting it to 100% to charge the maximum possible in the charging period. image

The consequence of this is that just after 15:30, H had reached 83% and so stopped charging, despite there still being free capacity in the battery and despite the import rate being zero. Again I stopped predbat and did a force charge for the remaining 20 minutes or so, the battery soc on that inverter reaching 100% (for free) as I expected it would.

Here's the two logfiles covering this 2-4pm period

appdaemon.log appdaemon.log.1.txt

Appreciate that some of this may be trying to bend predbat in ways that it doesn't currently naturally support, so hence why I marked this as an enhancement request.

So, sub-request, how do I easily turn predbat off to control the battery activities via my own scripts?

I had (last power-up event) written my own script to turn the key predbat switches off and on:

alias: Octopus Power Up, turn predbat off and on
description: >-
  On an Octopus Power-Up day, at sunrise, turn off predbat from changing
  inverter settings, then turn back on at 4pm (power-up end)
trigger:
  - platform: sun
    event: sunrise
    offset: 0
    id: power-up-day-start
  - platform: time
    at:
      - "16:00:20"
    id: power-up-end
condition:
  - condition: template
    value_template: >-
      {{ (now().date()) | string ==
      states('input_datetime.octopus_power_up_date') }}
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - power-up-day-start
        sequence:
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.predbat_control
      - conditions:
          - condition: trigger
            id:
              - power-up-end
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id:
                - switch.predbat_control
mode: single

Initially I tried it with listing all the predbat control switches as entities in the switch.turn_on and turn_off services, then I tried adding these entities to a helper group and switching that on and off: image

But either way I had the same effect, only the first switch set charge window was turned off. I think it might be because of the way these entities are linked to the predbat python code whereby whenever I change a predbat control the script re-runs automatically (doesn't wait for the 5 minute re-run period). Ordinarily this is great, but I think when I am trying to change half a dozen control switches at the same time, the first one gets thrown, the predbat script runs, and then all the other switch changes get lost as the script is running. I've noticed if I manually throw multiple switches there is a noticeable delay in HA before some of the switches "throw over", presumably because predbat is running after each change

treforsouthwell-sifive commented 1 year ago

I think there are two things here:

  1. Your unusual imbalanced batteries

Most users have matching batteries and so don't have the same type of issues you have experienced. I think to make this work properly Predbat would need to simulate each inverter/battery individually. In theory you could run two Predbat's, one on each inverter but without them being aligned it would lead to a new set of cross charging issues.

  1. To prevent the battery being full you have to freeze charging or discharge

Predbat can only do this in discharge slots, so your high rate needs to cover the slots before the negative import rate or it won't be allowed.

gcoan commented 1 year ago

Happy to close this as the new read-only switch in #190 enables me to do what I want and optimise my own battery activity in "unusual" circumstances. Longer term if predbat is able to optimise individual inverters and batteries separately that'd be great, but I have what I wanted now.