This is the back-end services for my Home Energy Management dashboard.
I have been cleaning up automations that have sprawled over the last 5-years. One of these clean-up was replacing my old and, simple solar inverter with a shiny new one.
The new solar system is a substantial improvement on the old one. As soon as it was added, I realised some gaps.
What are the questions this is trying to answer
- How can I control my renewable assets without another vendor app or two?
- How to save money? (Set and Forget)
- What did my stuff do? (Notes and detailed logs)
- What is my stuff doing now (Control)
Here is the critical hardware used:
- Fronius GEN24 (Inverter)
- Fronius Smart IP Meter
- Fronius Reserva Battery Energy Storage Solution (BESS)
- Fronius Wattpilot Flex (EV Charger)
Associated articles:
Here is what you will need to complete this setup:
- Home assistant + HACS
- Static IP address for inverter (or smart meter) and EV charger
- Inverter will require the technician password or at least the technician to enable some settings for this to work (username + password)
- EV charger will require the serial number and the default password
Step 1:
Add custom repo’s in HACS (http://homeassistant.local:8123/hacs/dashboard → 3 dots menu in top right → custom repositories)
https://github.com/callifo/fronius_modbus
https://github.com/mk-maddin/wattpilot-HA
Step 2.
Restart Home Assistant
Step 3.
Add integrations (http://homeassistant.local:8123/config/integrations/dashboard > +Add integration)
Fronius Modbus
Fronius Wattpilot
Step 4.
See what automations for your use case. For my personal use case, I am in Perth, Western Australia, using the Synergy time-of-use tariff. I have the following goals for my renewables investment:
- Peak Shaving: Discharging stored battery power during expensive peak-demand hours to reduce commercial utility “demand charges”.
- Energy Arbitrage: Charging the batteries when electricity is cheap (e.g., in the middle of the night) and discharging them when grid prices are high.
- Renewable Integration: Storing excess energy generated by onsite solar panels for use when the sun isn’t shining.
- Grid Services (VPP or Virtual Power Plant): Participating in demand response programs to stabilise the local utility grid and even generate revenue.
- Grid Resilience (Blackout protection): Participating in demand response programs to stabilise the local utility grid and even generate revenue.
Here is some more information on this VERY loaded topic Rapid backup understanding UPS vs BESS technologies
Step 5.
Deploy appropriate automations
Energy Tariffs changer
alias: Energy Tariffs changer
description: >-
This routine is for a 4-tier Time of Use (TOU) tariff from Synergy in Western
Australia.
Automation created by Benn, full documentation available on HA communities
https://community.home-assistant.io/t/fronius-solar-bess-ev-charging/1025454
triggers:
- at: input_datetime.tou_06_00_off_peak
variables:
tariff: Off Peak
trigger: time
- at: input_datetime.tou_09_00_super_off_peak
variables:
tariff: Super Off Peak
trigger: time
- at: input_datetime.tou_15_00_peak
variables:
tariff: Peak
trigger: time
- at: input_datetime.tou_21_00_off_peak
variables:
tariff: Off Peak
trigger: time
- at: input_datetime.tou_23_00_overnight
variables:
tariff: Overnight
trigger: time
actions:
- parallel:
- target:
entity_id: select.tou_em_channel_b_energy
data:
option: '{{ tariff }}'
action: select.select_option
- action: logbook.log
metadata: {}
data:
entity_id: select.tou_em_channel_b_energy
domain: automation
message: '#Automation told me to do it.'
name: sensor.main_line_em_channel_b_energy
- choose:
- conditions:
- condition: state
entity_id: select.tou_em_channel_b_energy
state:
- Peak
sequence:
- action: input_number.set_value
metadata: {}
target:
entity_id: input_number.energy_tiered_price_current
data:
value: 0.5533
- parallel:
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Peak"'
name: sensor.main_line_em_channel_b_energy
entity_id: sensor.main_line_em_channel_b_energy
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Peak"'
name: input_datetime.tou_15_00_peak
entity_id: input_datetime.tou_15_00_peak
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Peak"'
name: select.tou_em_channel_b_energy
entity_id: select.tou_em_channel_b_energy
- conditions:
- condition: state
entity_id: select.tou_em_channel_b_energy
state:
- Super Off Peak
sequence:
- action: input_number.set_value
metadata: {}
target:
entity_id: input_number.energy_tiered_price_current
data:
value: 0.0885
- parallel:
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Super Off Peak"'
name: sensor.main_line_em_channel_b_energy
entity_id: sensor.main_line_em_channel_b_energy
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Super Off Peak"'
name: input_datetime.tou_09_00_super_off_peak
entity_id: input_datetime.tou_09_00_super_off_peak
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Super Off Peak"'
name: select.tou_em_channel_b_energy
entity_id: select.tou_em_channel_b_energy
- conditions:
- condition: state
entity_id: select.tou_em_channel_b_energy
state:
- Off Peak
sequence:
- action: input_number.set_value
metadata: {}
target:
entity_id: input_number.energy_tiered_price_current
data:
value: 0.2434
- parallel:
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Off Peak"'
name: sensor.main_line_em_channel_b_energy
entity_id: sensor.main_line_em_channel_b_energy
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Off Peak"'
name: input_datetime.tou_21_00_off_peak
entity_id: input_datetime.tou_21_00_off_peak
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Off Peak"'
name: input_datetime.tou_06_00_off_peak
entity_id: input_datetime.tou_06_00_off_peak
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Off Peak"'
name: select.tou_em_channel_b_energy
entity_id: select.tou_em_channel_b_energy
- conditions:
- condition: state
entity_id: select.tou_em_channel_b_energy
state:
- Overnight
sequence:
- action: input_number.set_value
metadata: {}
target:
entity_id: input_number.energy_tiered_price_current
data:
value: 0.2434
- parallel:
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Overnight"'
name: sensor.main_line_em_channel_b_energy
entity_id: sensor.main_line_em_channel_b_energy
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Overnight"'
name: input_datetime.tou_23_00_overnight
entity_id: input_datetime.tou_23_00_overnight
- action: logbook.log
metadata: {}
data:
domain: Select
message: 'Energy tariff: set rate for "Overnight"'
name: select.tou_em_channel_b_energy
entity_id: select.tou_em_channel_b_energy
mode: single
Renewables sub-routine: BESS discharge limit to actual max
alias: 'Renewables sub-routine: BESS discharge limit to actual max'
description: >-
This routine overwrites some minor back-end errors with Fronius inverters on
actual maximum charge/discharge. You can identify this in >2 mins from the
"Fronius reserva battery datasheet".
Automation created by Benn, full documentation available on HA communities
https://community.home-assistant.io/t/fronius-solar-bess-ev-charging/1025454
triggers:
- trigger: numeric_state
entity_id:
- number.reserva_discharge_limit
for:
hours: 0
minutes: 0
seconds: 15
above: 6760
conditions: []
actions:
- parallel:
- action: number.set_value
metadata: {}
target:
entity_id: number.reserva_discharge_limit
data:
value: '6760'
- action: logbook.log
metadata: {}
data:
message: 'Renewables sub-routine: BESS discharge limit to actual max'
entity_id: number.reserva_discharge_limit
domain: Select
name: number.reserva_discharge_limit
mode: single
Renewables sub-routine: BESS PV charge limit to actual max
alias: 'Renewables sub-routine: BESS PV charge limit to actual max'
description: >-
This routine overwrites some minor back-end errors with Fronius inverters on
actual maximum charge/discharge. You can identify this in >2 mins from the
"Fronius reserva battery datasheet".
Automation created by Benn, full documentation available on HA communities
https://community.home-assistant.io/t/fronius-solar-bess-ev-charging/1025454
triggers:
- trigger: numeric_state
entity_id:
- number.reserva_pv_charge_limit
for:
hours: 0
minutes: 0
seconds: 18
above: 6760
conditions: []
actions:
- parallel:
- action: number.set_value
metadata: {}
target:
entity_id: number.reserva_pv_charge_limit
data:
value: '6760'
- action: logbook.log
metadata: {}
data:
message: 'Renewables sub-routine: BESS PV charge limit to actual max'
entity_id: number.reserva_pv_charge_limit
domain: Select
name: number.reserva_pv_charge_limit
mode: single
Renewables routine, Energy Arbitrage: Cheap TOU (part 1/2) Solar-only
alias: 'Renewables routine, Energy Arbitrage: Cheap TOU (part 1/2) Solar-only'
description: >-
This routine is to limit grid charge and enable solar charging of a BESS unit.
Automation created by Benn, full documentation available on HA communities
https://community.home-assistant.io/t/fronius-solar-bess-ev-charging/1025454
triggers:
- trigger: state
entity_id:
- select.tou_em_channel_b_energy
to:
- Super Off Peak
for:
hours: 0
minutes: 0
seconds: 1
conditions: []
actions:
- sequence:
- sequence:
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_battery_api_mode
data:
option: Manual
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_storage_control_mode
data:
option: Charge from Grid
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_grid
data: {}
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_ac
data: {}
- parallel:
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 1 of 2 Solar-only charge'
entity_id: select.reserva_battery_api_mode
domain: Select
name: select.reserva_battery_api_mode
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 1 of 2 Solar-only charge'
entity_id: select.reserva_storage_control_mode
domain: Select
name: select.reserva_storage_control_mode
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 1 of 2 Solar-only charge'
entity_id: switch.reserva_charge_from_grid
domain: Select
name: switch.reserva_charge_from_grid
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 1 of 2 Solar-only charge'
entity_id: switch.reserva_charge_from_ac
domain: Select
name: switch.reserva_charge_from_ac
- sequence:
- action: number.set_value
metadata: {}
data:
value: '0'
target:
entity_id: number.reserva_grid_charge_power
- delay:
hours: 0
minutes: 0
seconds: 15
milliseconds: 0
- action: number.set_value
metadata: {}
target:
entity_id: number.reserva_target_feed_in
data:
value: '0'
- delay:
hours: 0
minutes: 0
seconds: 15
milliseconds: 0
mode: single
Renewables routine, Energy Arbitrage: Cheap TOU (part 2/2) Solar + Grid
alias: 'Renewables routine, Energy Arbitrage: Cheap TOU (part 2/2) Solar + Grid'
description: |-
This routine is to limit grid charge and enable solar charging of a BESS unit.
Automation created by Benn, full documentation available on HA communities
https://community.home-assistant.io/t/fronius-solar-bess-ev-charging/1025454
triggers:
- trigger: state
entity_id:
- select.tou_em_channel_b_energy
to:
- Super Off Peak
for:
hours: 3
minutes: 0
seconds: 1
conditions: []
actions:
- sequence:
- sequence:
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_battery_api_mode
data:
option: Manual
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_storage_control_mode
data:
option: Charge from Grid
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_grid
data: {}
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_ac
data: {}
- parallel:
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 2 of 2 Solar+grid'
entity_id: select.reserva_battery_api_mode
domain: Select
name: select.reserva_battery_api_mode
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 2 of 2 Solar+grid'
entity_id: select.reserva_storage_control_mode
domain: Select
name: select.reserva_storage_control_mode
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 2 of 2 Solar+grid'
entity_id: switch.reserva_charge_from_grid
domain: Select
name: switch.reserva_charge_from_grid
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 2 of 2 Solar+grid'
entity_id: switch.reserva_charge_from_ac
domain: Select
name: switch.reserva_charge_from_ac
- sequence:
- action: number.set_value
metadata: {}
data:
value: '6700'
target:
entity_id: number.reserva_grid_charge_power
- delay:
hours: 0
minutes: 0
seconds: 15
milliseconds: 0
- action: number.set_value
metadata: {}
target:
entity_id: number.reserva_target_feed_in
data:
value: '0'
- delay:
hours: 0
minutes: 0
seconds: 15
milliseconds: 0
mode: single
Renewables routine, Energy Arbitrage: Expensive TOU - Peak Shaving ignore the grid
alias: 'Renewables routine, Energy Arbitrage: Expensive TOU - Peak Shaving ignore the grid'
description: >-
This routine is to maximise "Peak Shaving"
Automation created by Benn, full documentation available on HA communities
https://community.home-assistant.io/t/fronius-solar-bess-ev-charging/1025454
triggers:
- trigger: state
entity_id:
- select.tou_em_channel_b_energy
to:
- Peak
conditions: []
actions:
- parallel:
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_battery_api_mode
data:
option: Auto
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_storage_control_mode
data:
option: PV Charge and Discharge Limit
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_ac
data: {}
- sequence:
- delay:
hours: 0
minutes: 0
seconds: 3
milliseconds: 0
- action: number.set_value
metadata: {}
target:
entity_id: number.reserva_discharge_limit
data:
value: '6760'
- action: number.set_value
metadata: {}
target:
entity_id: number.reserva_pv_charge_limit
data:
value: '6760'
- action: switch.turn_off
metadata: {}
target:
entity_id: switch.reserva_charge_from_grid
data: {}
- parallel:
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 1 of 2 Solar-only charge'
entity_id: select.reserva_battery_api_mode
domain: Select
name: select.reserva_battery_api_mode
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 1 of 2 Solar-only charge'
entity_id: select.reserva_storage_control_mode
domain: Select
name: select.reserva_storage_control_mode
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 1 of 2 Solar-only charge'
entity_id: switch.reserva_charge_from_grid
domain: Select
name: switch.reserva_charge_from_grid
- action: logbook.log
metadata: {}
data:
message: 'Renewables routine: Cheap TOU part 1 of 2 Solar-only charge'
entity_id: switch.reserva_charge_from_ac
domain: Select
name: switch.reserva_charge_from_ac
mode: single
Renewables routine, Grid Resilience: Shoulder TOU - Boost your battery (part1/2)
alias: 'Renewables routine, Grid Resilience: Shoulder TOU - Boost your battery (part1/2)'
description: >-
This routine is for "Grid Resilience". This is an alternative to a static
"minimum state of charge"; this is a 2-part process.
1. Start: Charge your battery during a fairly cheap after-hours time until the
goal % is reached. ~35% (This automation)
2. End: Resume discharging using standard device settings
Automation created by Benn, full documentation available on HA communities
https://community.home-assistant.io/t/fronius-solar-bess-ev-charging/1025454
triggers:
- trigger: state
entity_id:
- select.tou_em_channel_b_energy
from:
- Off Peak
to:
- Overnight
conditions: []
actions:
- sequence:
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_battery_api_mode
data:
option: Manual
- delay:
hours: 0
minutes: 0
seconds: 30
milliseconds: 0
- sequence:
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_grid
data: {}
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_ac
data: {}
- delay:
hours: 0
minutes: 0
seconds: 30
milliseconds: 0
- sequence:
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_storage_control_mode
data:
option: Charge from Grid
- delay:
hours: 0
minutes: 0
seconds: 30
milliseconds: 0
- sequence:
- action: number.set_value
metadata: {}
data:
value: '3000'
target:
entity_id: number.reserva_grid_charge_power
- action: number.set_value
metadata: {}
target:
entity_id: number.reserva_pv_charge_limit
data:
value: '6760'
- action: number.set_value
metadata: {}
target:
entity_id: number.reserva_target_feed_in
data:
value: '0'
- action: logbook.log
metadata: {}
data:
domain: automation
message: >-
modbus automation to enable grid #Automation told me to
do it.
entity_id: sensor.reserva_state_of_charge
- action: logbook.log
metadata: {}
data:
domain: automation
entity_id: sensor.reserva_grid_charging
message: >-
modbus automation to enable grid #Automation told me to
do it.
mode: single
Renewables routine, Grid Resilience: Shoulder TOU - Boost your battery (part2/2)
alias: >-
Renewables routine, Grid Resilience: Shoulder TOU - Boost your battery
(part2/2)
description: >-
This routine is for "Grid Resilience". This is an alternative to a static
"minimum state of charge"; this is a 2-part process.
1. Start: Charge your battery during a fairly cheap after-hours time until the
goal % is reached. ~35%
2. End: Resume discharging using standard device settings (This automation)
Automation created by Benn, full documentation available on HA communities
https://community.home-assistant.io/t/fronius-solar-bess-ev-charging/1025454
triggers:
- trigger: numeric_state
entity_id:
- sensor.reserva_state_of_charge_2
above: 35
conditions:
- condition: select.is_option_selected
target:
entity_id: select.tou_em_channel_b_energy
options:
behavior: any
for: '00:00:00'
option:
- Overnight
actions:
- parallel:
- sequence:
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_battery_api_mode
data:
option: Auto
- action: logbook.log
metadata: {}
data:
message: >-
Renewables routine, Grid Resilience: Shoulder TOU - Boost your
battery (part2/2)
entity_id: select.reserva_battery_api_mode
domain: Select
name: select.reserva_battery_api_mode
- sequence:
- action: select.select_option
metadata: {}
target:
entity_id: select.reserva_storage_control_mode
data:
option: Auto
- action: logbook.log
metadata: {}
data:
message: >-
Renewables routine, Grid Resilience: Shoulder TOU - Boost your
battery (part2/2)
entity_id: switch.reserva_charge_from_grid
domain: Select
name: switch.reserva_charge_from_grid
- sequence:
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_ac
data: {}
- action: logbook.log
metadata: {}
data:
message: >-
Renewables routine, Grid Resilience: Shoulder TOU - Boost your
battery (part2/2)
entity_id: switch.reserva_charge_from_ac
domain: Select
name: switch.reserva_charge_from_ac
- sequence:
- action: switch.turn_on
metadata: {}
target:
entity_id: switch.reserva_charge_from_grid
data: {}
- action: logbook.log
metadata: {}
data:
message: >-
Renewables routine, Grid Resilience: Shoulder TOU - Boost your
battery (part2/2)
entity_id: select.reserva_storage_control_mode
domain: Select
name: select.reserva_storage_control_mode
mode: single