There are of course many ways to do the same thing in HA and mine isn't necessarily the best! This is also not designed to be a step by step guide, but more an overview of what I did.
1) I wanted the energy dashboard to properly report the energy usage using my Octopus tariff, Cosy. So I followed the Speak to the Geek guidance to create the correct energy meters and have my usage reported on the energy dashboard in HA:
https://www.speaktothegeek.co.uk/2023/0 ... dashboard/
I notice there is also a newer article covering similar but I've not validated this.
https://www.speaktothegeek.co.uk/2024/0 ... dashboard/
2) Then I wanted to use those energy meters as triggers for my inverter automations. My strategy is to charge overnight as much as needed but then use the 2 other low rate periods on Cosy to charge the battery as needed. The idea behind this was to try and not cycle the battery too much, but also to see if I could cope with just one overnight charge which might mean that something like Octopus Go, or Flux might be better for me in future (I suspect I'll change to Flux in summer for the higher export rates).
The overnight automation:
Code: Select all
alias: >-
Set inverter workmode based on Cosy tariff low rate PERIOD 1, forecast and
battery charge remaining.
description: >-
Sets inverter work-mode based on changing tariff times and current battery
capacity. Uses average kwh per day less used already today less forecast
solar production left for the day to calculate a target charge level
trigger:
- platform: time
at: input_datetime.cosy_low_rate_period_1_start
variables:
workload: Force Charge
tariff: cosylowperiod1
condition:
- condition: template
value_template: >-
{{ states('input_number.battery_forecast_charge_requirement') |
float(default=0) > 0 }}
- condition: state
entity_id: input_boolean.solar_holiday
state: "off"
action:
- data_template:
entity_id: input_number.battery_force_charge_set_limit
value: >-
{{ states('input_number.battery_forecast_charge_requirement') |
float(default=0) + states('sensor.battery_usable_charge_remaining') |
float(default=0) }}
action: input_number.set_value
- delay: "00:01:05"
- target:
entity_id: select.h160g2_work_mode
data:
option: Force Charge
action: select.select_option
- device_id: fd1e057faad66503672ff3467d907b97
domain: number
entity_id: 2d0c11159d0f3ffe12b82175e9dee918
type: set_value
value: 0
- action: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id: input_boolean.solar_boost
mode: single
- A helper called "input_number.battery_forecast_charge_requirement" is the brains behind this, and is based on a simple calculation which looks at the solar forecast for the day at 4am, the usual energy usage at home per day (12kWh) and the amount of charge left in the battery, plus a margin to allow for error. I'll post the automation which sets this below.
- I have a helper called "solar holiday" so that I can turn charging off when I'm away
- Another helper called "solar boost" when on adds another 2kWh to the battery charge
Automation which turns off a force charge when the set limit is reached.
Code: Select all
alias: Turn off force charge when set limit is reached v2
description: Turns off Force Charge when battery charge remaining >= Force Charge Set Limit
trigger:
- platform: template
value_template: >-
{{ states('sensor.battery_usable_charge_remaining') | float(0) >
states('input_number.battery_force_charge_set_limit') | float(0) }}
condition:
- condition: state
entity_id: select.h160g2_work_mode
state: Force Charge
for:
hours: 0
minutes: 0
seconds: 0
enabled: true
action:
- target:
entity_id: select.h160g2_work_mode
data:
option: Self Use
action: select.select_option
enabled: true
- action: logbook.log
metadata: {}
data:
message: Charge remaining is now above battery force charge set limit.
entity_id: sensor.h160g2_inverter_state
name: Stop charging at set battery limit
mode: single
Code: Select all
alias: Sets forecast charge requirement inc boost v2
description: >-
Sets forecast charge requirement for the battery based on daily load average,
used energy today so far, forecast remaining solar energy production and the
usable charge remaining in the battery.
trigger:
- platform: time_pattern
minutes: /5
condition: []
action:
- if:
- condition: state
entity_id: input_boolean.solar_boost
state: "on"
then:
- data_template:
entity_id: input_number.battery_forecast_charge_requirement
value: >-
{{ (12 - states('sensor.h160g2_load_energy_today') |
float(default=0) -
states('sensor.energy_production_today_remaining') |
float(default=0) - states('sensor.battery_usable_charge_remaining')
| float(default=0) + 6.5) | round(1, 'ceil') }}
action: input_number.set_value
else:
- data_template:
entity_id: input_number.battery_forecast_charge_requirement
value: >-
{{ (12 - states('sensor.h160g2_load_energy_today') |
float(default=0) -
states('sensor.energy_production_today_remaining') |
float(default=0) - states('sensor.battery_usable_charge_remaining')
| float(default=0) + 4.5) | round(1, 'ceil') }}
action: input_number.set_value
mode: single
Automation to switch force charge off at end of all periods
Just in case the battery doesn't finish charging by the end of the low rate I also have this automation to turn force charge off. I also find this handy as sometimes I'll manually put the inverter into force charge and I know that it will turn off automatically at the end of each low rate.
Code: Select all
alias: Set inverter workmode to Self Use at end of all low rate periods
description: >-
Sets inverter work mode back to Self Use at the end of all low rate periods if
still force charging (may have already stopped charging if set rate limit
reached), and turns battery discharge back on.
trigger:
- platform: time
at: input_datetime.cosy_low_rate_period_1_end
variables:
workload: Self Use
tariff: cosystandardperiod
- platform: time
at: input_datetime.cosy_low_rate_period_2_end
variables:
workload: Self Use
tariff: cosyhighperiod
- platform: time
at: input_datetime.cosy_low_rate_period_3_end
variables:
workload: Self Use
tariff: cosystandardperiod
condition:
- condition: or
conditions:
- condition: numeric_state
entity_id: sensor.h160g2_max_discharge_current
below: 5
- condition: state
entity_id: select.h160g2_work_mode
state: Force Charge
action:
- if:
- condition: state
entity_id: select.h160g2_work_mode
state: Force Charge
then:
- data:
option: Self Use
target:
entity_id: select.h160g2_work_mode
action: select.select_option
- device_id: fd1e057faad66503672ff3467d907b97
domain: number
Code: Select all
action:
- device_id: fd1e057faad66503672ff3467d907b97
domain: number
entity_id: 2d0c11159d0f3ffe12b82175e9dee918
type: set_value
value: 0
In practice I'm mostly using the morning slot for 80% of grid usage. On a solar day where we expect to see >14kWh of PV it doesn't bring in anything from the grid at all.
Happy to answer any questions.